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