Changes in kernel/generic/src/security/cap.c [b3f8fb7:6b10dab] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/security/cap.c
rb3f8fb7 r6b10dab 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ 32 32 33 33 /** 34 * @file 35 * @brief 34 * @file cap.c 35 * @brief Capabilities control. 36 36 * 37 37 * @see cap.h 38 38 */ 39 39 40 40 #include <security/cap.h> 41 41 #include <proc/task.h> 42 42 #include <synch/spinlock.h> 43 #include <syscall/sysarg64.h>44 43 #include <syscall/copy.h> 45 44 #include <arch.h> … … 48 47 /** Set capabilities. 49 48 * 50 * @param t Task whose capabilities are to be changed.49 * @param task Task whose capabilities are to be changed. 51 50 * @param caps New set of capabilities. 52 */ 53 void cap_set(task_t *t, cap_t caps) 54 { 55 ipl_t ipl; 56 57 ipl = interrupts_disable(); 58 spinlock_lock(&t->lock); 59 60 t->capabilities = caps; 61 62 spinlock_unlock(&t->lock); 63 interrupts_restore(ipl); 51 * 52 */ 53 void cap_set(task_t *task, cap_t caps) 54 { 55 irq_spinlock_lock(&task->lock, true); 56 task->capabilities = caps; 57 irq_spinlock_unlock(&task->lock, true); 64 58 } 65 59 66 60 /** Get capabilities. 67 61 * 68 * @param t Task whose capabilities are to be returned. 62 * @param task Task whose capabilities are to be returned. 63 * 69 64 * @return Task's capabilities. 70 */ 71 cap_t cap_get(task_t *t) 72 { 73 ipl_t ipl; 74 cap_t caps; 75 76 ipl = interrupts_disable(); 77 spinlock_lock(&t->lock); 78 79 caps = t->capabilities; 80 81 spinlock_unlock(&t->lock); 82 interrupts_restore(ipl); 65 * 66 */ 67 cap_t cap_get(task_t *task) 68 { 69 irq_spinlock_lock(&task->lock, true); 70 cap_t caps = task->capabilities; 71 irq_spinlock_unlock(&task->lock, true); 83 72 84 73 return caps; … … 89 78 * The calling task must have the CAP_CAP capability. 90 79 * 91 * @param uspace_taskid_arg Userspace structure holding destination task ID. 92 * @param caps Capabilities to grant. 93 * 94 * @return Zero on success or an error code from @ref errno.h. 95 */ 96 unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps) 97 { 98 sysarg64_t taskid_arg; 99 task_t *t; 100 ipl_t ipl; 101 int rc; 102 80 * @param taskid Destination task ID. 81 * @param caps Capabilities to grant. 82 * 83 * @return Zero on success or an error code from @ref errno.h. 84 * 85 */ 86 static sysarg_t cap_grant(task_id_t taskid, cap_t caps) 87 { 103 88 if (!(cap_get(TASK) & CAP_CAP)) 104 return (unative_t) EPERM; 105 106 rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t)); 107 if (rc != 0) 108 return (unative_t) rc; 109 110 ipl = interrupts_disable(); 111 spinlock_lock(&tasks_lock); 112 t = task_find_by_id((task_id_t) taskid_arg.value); 113 if ((!t) || (!context_check(CONTEXT, t->context))) { 114 spinlock_unlock(&tasks_lock); 115 interrupts_restore(ipl); 116 return (unative_t) ENOENT; 89 return (sysarg_t) EPERM; 90 91 irq_spinlock_lock(&tasks_lock, true); 92 task_t *task = task_find_by_id(taskid); 93 94 if ((!task) || (!context_check(CONTEXT, task->context))) { 95 irq_spinlock_unlock(&tasks_lock, true); 96 return (sysarg_t) ENOENT; 117 97 } 118 98 119 spinlock_lock(&t->lock); 120 cap_set(t, cap_get(t) | caps); 121 spinlock_unlock(&t->lock); 122 123 spinlock_unlock(&tasks_lock); 124 interrupts_restore(ipl); 99 irq_spinlock_lock(&task->lock, false); 100 task->capabilities |= caps; 101 irq_spinlock_unlock(&task->lock, false); 102 103 irq_spinlock_unlock(&tasks_lock, true); 125 104 return 0; 126 105 } … … 131 110 * attempt to revoke capabilities from itself. 132 111 * 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 unative_t 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 (unative_t) 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) || (!context_check(CONTEXT, t->context))) { 153 spinlock_unlock(&tasks_lock); 154 interrupts_restore(ipl); 155 return (unative_t) ENOENT; 112 * @param taskid Destination task ID. 113 * @param caps Capabilities to revoke. 114 * 115 * @return Zero on success or an error code from @ref errno.h. 116 * 117 */ 118 static sysarg_t cap_revoke(task_id_t taskid, cap_t caps) 119 { 120 irq_spinlock_lock(&tasks_lock, true); 121 122 task_t *task = task_find_by_id(taskid); 123 if ((!task) || (!context_check(CONTEXT, task->context))) { 124 irq_spinlock_unlock(&tasks_lock, true); 125 return (sysarg_t) ENOENT; 156 126 } 157 127 158 128 /* 159 129 * Revoking capabilities is different from granting them in that … … 161 131 * doesn't have CAP_CAP. 162 132 */ 163 if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) { 164 spinlock_unlock(&tasks_lock); 165 interrupts_restore(ipl); 166 return (unative_t) EPERM; 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); 138 return (sysarg_t) EPERM; 167 139 } 168 140 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); 141 task->capabilities &= ~caps; 142 irq_spinlock_unlock(&TASK->lock, false); 143 144 irq_spinlock_unlock(&tasks_lock, true); 176 145 return 0; 177 146 } 178 147 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 */ 160 sysarg_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 */ 181 sysarg_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 */ 205 sysarg_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 */ 221 sysarg_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 179 228 /** @} 180 229 */ 181
Note:
See TracChangeset
for help on using the changeset viewer.