source: mainline/generic/src/security/cap.c@ 2569ec90

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2569ec90 was 2569ec90, checked in by Jakub Jermar <jakub@…>, 19 years ago

In task_kill(), remove the task from the tasks_btree before proceeding.
Thus, when the kernel finds the task in the tasks_btree and locks it before
releasing tasks_lock, it is guaranteed that the task will not be destroyed
until the lock is held. If the kernel needs to unlock the task, do some operation
and lock it again, it should increase its refcount before doing so. In that case,
when releasing the lock, it must decrement the refcount and if it reaches
zero, it must call task_destroy().

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (C) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @file cap.c
31 * @brief Capabilities control.
32 *
33 * @see cap.h
34 */
35
36#include <security/cap.h>
37#include <proc/task.h>
38#include <synch/spinlock.h>
39#include <syscall/sysarg64.h>
40#include <syscall/copy.h>
41#include <arch.h>
42#include <typedefs.h>
43#include <errno.h>
44
45/** Set capabilities.
46 *
47 * @param t Task whose capabilities are to be changed.
48 * @param caps New set of capabilities.
49 */
50void cap_set(task_t *t, cap_t caps)
51{
52 ipl_t ipl;
53
54 ipl = interrupts_disable();
55 spinlock_lock(&t->lock);
56
57 t->capabilities = caps;
58
59 spinlock_unlock(&t->lock);
60 interrupts_restore(ipl);
61}
62
63/** Get capabilities.
64 *
65 * @param t Task whose capabilities are to be returned.
66 * @return Task's capabilities.
67 */
68cap_t cap_get(task_t *t)
69{
70 ipl_t ipl;
71 cap_t caps;
72
73 ipl = interrupts_disable();
74 spinlock_lock(&t->lock);
75
76 caps = t->capabilities;
77
78 spinlock_unlock(&t->lock);
79 interrupts_restore(ipl);
80
81 return caps;
82}
83
84/** Grant capabilities to a task.
85 *
86 * The calling task must have the CAP_CAP capability.
87 *
88 * @param uspace_taskid_arg Userspace structure holding destination task ID.
89 * @param caps Capabilities to grant.
90 *
91 * @return Zero on success or an error code from @ref errno.h.
92 */
93__native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
94{
95 sysarg64_t taskid_arg;
96 task_t *t;
97 ipl_t ipl;
98 int rc;
99
100 if (!(cap_get(TASK) & CAP_CAP))
101 return (__native) EPERM;
102
103 rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
104 if (rc != 0)
105 return (__native) rc;
106
107 ipl = interrupts_disable();
108 spinlock_lock(&tasks_lock);
109 t = task_find_by_id((task_id_t) taskid_arg.value);
110 if (!t) {
111 spinlock_unlock(&tasks_lock);
112 interrupts_restore(ipl);
113 return (__native) ENOENT;
114 }
115
116 spinlock_lock(&t->lock);
117 cap_set(t, cap_get(t) | caps);
118 spinlock_unlock(&t->lock);
119
120 spinlock_unlock(&tasks_lock);
121
122
123
124 interrupts_restore(ipl);
125 return 0;
126}
127
128/** Revoke capabilities from a task.
129 *
130 * The calling task must have the CAP_CAP capability or the caller must
131 * attempt to revoke capabilities from itself.
132 *
133 * @param uspace_taskid_arg Userspace structure holding destination task ID.
134 * @param caps Capabilities to revoke.
135 *
136 * @return Zero on success or an error code from @ref errno.h.
137 */
138__native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
139{
140 sysarg64_t taskid_arg;
141 task_t *t;
142 ipl_t ipl;
143 int rc;
144
145 rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
146 if (rc != 0)
147 return (__native) rc;
148
149 ipl = interrupts_disable();
150 spinlock_lock(&tasks_lock);
151 t = task_find_by_id((task_id_t) taskid_arg.value);
152 if (!t) {
153 spinlock_unlock(&tasks_lock);
154 interrupts_restore(ipl);
155 return (__native) ENOENT;
156 }
157
158 /*
159 * Revoking capabilities is different from granting them in that
160 * a task can revoke capabilities from itself even if it
161 * doesn't have CAP_CAP.
162 */
163 if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
164 spinlock_unlock(&tasks_lock);
165 interrupts_restore(ipl);
166 return (__native) EPERM;
167 }
168
169 spinlock_lock(&t->lock);
170 cap_set(t, cap_get(t) & ~caps);
171 spinlock_unlock(&t->lock);
172
173 spinlock_unlock(&tasks_lock);
174
175 interrupts_restore(ipl);
176 return 0;
177}
Note: See TracBrowser for help on using the repository browser.