source: mainline/kernel/generic/src/security/cap.c@ 346b12a2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 346b12a2 was 473d5d2, checked in by Martin Decky <martin@…>, 14 years ago

add magic value to THE structure for better stack/memory corruption detection
rename (security) contexts to containers (a slightly less overloaded term within SPARTAN kernel)

  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[1077d91]1/*
[df4ed85]2 * Copyright (c) 2006 Jakub Jermar
[1077d91]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
[da1bafb]29/** @addtogroup generic
[b45c443]30 * @{
31 */
32
[cf26ba9]33/**
[da1bafb]34 * @file cap.c
35 * @brief Capabilities control.
[cf26ba9]36 *
37 * @see cap.h
38 */
[da1bafb]39
[1077d91]40#include <security/cap.h>
41#include <proc/task.h>
42#include <synch/spinlock.h>
[2bb8648]43#include <syscall/copy.h>
[1077d91]44#include <arch.h>
[2bb8648]45#include <errno.h>
[1077d91]46
47/** Set capabilities.
48 *
[da1bafb]49 * @param task Task whose capabilities are to be changed.
[1077d91]50 * @param caps New set of capabilities.
[da1bafb]51 *
[1077d91]52 */
[da1bafb]53void cap_set(task_t *task, cap_t caps)
[1077d91]54{
[da1bafb]55 irq_spinlock_lock(&task->lock, true);
56 task->capabilities = caps;
57 irq_spinlock_unlock(&task->lock, true);
[1077d91]58}
59
60/** Get capabilities.
61 *
[da1bafb]62 * @param task Task whose capabilities are to be returned.
63 *
[1077d91]64 * @return Task's capabilities.
[da1bafb]65 *
[1077d91]66 */
[da1bafb]67cap_t cap_get(task_t *task)
[1077d91]68{
[da1bafb]69 irq_spinlock_lock(&task->lock, true);
70 cap_t caps = task->capabilities;
71 irq_spinlock_unlock(&task->lock, true);
[1077d91]72
73 return caps;
74}
[2bb8648]75
76/** Grant capabilities to a task.
77 *
78 * The calling task must have the CAP_CAP capability.
79 *
[6b10dab]80 * @param taskid Destination task ID.
81 * @param caps Capabilities to grant.
[2bb8648]82 *
83 * @return Zero on success or an error code from @ref errno.h.
[da1bafb]84 *
[2bb8648]85 */
[6b10dab]86static sysarg_t cap_grant(task_id_t taskid, cap_t caps)
[2bb8648]87{
88 if (!(cap_get(TASK) & CAP_CAP))
[96b02eb9]89 return (sysarg_t) EPERM;
[2bb8648]90
[da1bafb]91 irq_spinlock_lock(&tasks_lock, true);
[6b10dab]92 task_t *task = task_find_by_id(taskid);
[da1bafb]93
[473d5d2]94 if ((!task) || (!container_check(CONTAINER, task->container))) {
[da1bafb]95 irq_spinlock_unlock(&tasks_lock, true);
[96b02eb9]96 return (sysarg_t) ENOENT;
[2bb8648]97 }
98
[da1bafb]99 irq_spinlock_lock(&task->lock, false);
100 task->capabilities |= caps;
101 irq_spinlock_unlock(&task->lock, false);
[2569ec90]102
[da1bafb]103 irq_spinlock_unlock(&tasks_lock, true);
[2bb8648]104 return 0;
105}
106
107/** Revoke capabilities from a task.
108 *
109 * The calling task must have the CAP_CAP capability or the caller must
110 * attempt to revoke capabilities from itself.
111 *
[6b10dab]112 * @param taskid Destination task ID.
113 * @param caps Capabilities to revoke.
[2bb8648]114 *
115 * @return Zero on success or an error code from @ref errno.h.
[da1bafb]116 *
[2bb8648]117 */
[6b10dab]118static sysarg_t cap_revoke(task_id_t taskid, cap_t caps)
[2bb8648]119{
[da1bafb]120 irq_spinlock_lock(&tasks_lock, true);
121
[6b10dab]122 task_t *task = task_find_by_id(taskid);
[473d5d2]123 if ((!task) || (!container_check(CONTAINER, task->container))) {
[da1bafb]124 irq_spinlock_unlock(&tasks_lock, true);
[96b02eb9]125 return (sysarg_t) ENOENT;
[2bb8648]126 }
[da1bafb]127
[2bb8648]128 /*
129 * Revoking capabilities is different from granting them in that
130 * a task can revoke capabilities from itself even if it
131 * doesn't have CAP_CAP.
132 */
[da1bafb]133 irq_spinlock_unlock(&TASK->lock, false);
134
135 if ((!(TASK->capabilities & CAP_CAP)) || (task != TASK)) {
136 irq_spinlock_unlock(&TASK->lock, false);
137 irq_spinlock_unlock(&tasks_lock, true);
[96b02eb9]138 return (sysarg_t) EPERM;
[2bb8648]139 }
140
[da1bafb]141 task->capabilities &= ~caps;
142 irq_spinlock_unlock(&TASK->lock, false);
143
144 irq_spinlock_unlock(&tasks_lock, true);
[2bb8648]145 return 0;
146}
[b45c443]147
[6b10dab]148#ifdef __32_BITS__
149
150/** Grant capabilities to a task (32 bits)
151 *
152 * The calling task must have the CAP_CAP capability.
153 *
154 * @param uspace_taskid User-space pointer to destination task ID.
155 * @param caps Capabilities to grant.
156 *
157 * @return Zero on success or an error code from @ref errno.h.
158 *
159 */
160sysarg_t sys_cap_grant(sysarg64_t *uspace_taskid, cap_t caps)
161{
162 sysarg64_t taskid;
163 int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
164 if (rc != 0)
165 return (sysarg_t) rc;
166
167 return cap_grant((task_id_t) taskid, caps);
168}
169
170/** Revoke capabilities from a task (32 bits)
171 *
172 * The calling task must have the CAP_CAP capability or the caller must
173 * attempt to revoke capabilities from itself.
174 *
175 * @param uspace_taskid User-space pointer to destination task ID.
176 * @param caps Capabilities to revoke.
177 *
178 * @return Zero on success or an error code from @ref errno.h.
179 *
180 */
181sysarg_t sys_cap_revoke(sysarg64_t *uspace_taskid, cap_t caps)
182{
183 sysarg64_t taskid;
184 int rc = copy_from_uspace(&taskid, uspace_taskid, sizeof(sysarg64_t));
185 if (rc != 0)
186 return (sysarg_t) rc;
187
188 return cap_revoke((task_id_t) taskid, caps);
189}
190
191#endif /* __32_BITS__ */
192
193#ifdef __64_BITS__
194
195/** Grant capabilities to a task (64 bits)
196 *
197 * The calling task must have the CAP_CAP capability.
198 *
199 * @param taskid Destination task ID.
200 * @param caps Capabilities to grant.
201 *
202 * @return Zero on success or an error code from @ref errno.h.
203 *
204 */
205sysarg_t sys_cap_grant(sysarg_t taskid, cap_t caps)
206{
207 return cap_grant((task_id_t) taskid, caps);
208}
209
210/** Revoke capabilities from a task (64 bits)
211 *
212 * The calling task must have the CAP_CAP capability or the caller must
213 * attempt to revoke capabilities from itself.
214 *
215 * @param taskid Destination task ID.
216 * @param caps Capabilities to revoke.
217 *
218 * @return Zero on success or an error code from @ref errno.h.
219 *
220 */
221sysarg_t sys_cap_revoke(sysarg_t taskid, cap_t caps)
222{
223 return cap_revoke((task_id_t) taskid, caps);
224}
225
226#endif /* __64_BITS__ */
227
[06e1e95]228/** @}
[b45c443]229 */
Note: See TracBrowser for help on using the repository browser.