aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/capability.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/capability.c')
-rw-r--r--kernel/capability.c227
1 files changed, 23 insertions, 204 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index adb262f83de1..58b00519624a 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -127,160 +127,6 @@ static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
127 return 0; 127 return 0;
128} 128}
129 129
130#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
131
132/*
133 * Without filesystem capability support, we nominally support one process
134 * setting the capabilities of another
135 */
136static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
137 kernel_cap_t *pIp, kernel_cap_t *pPp)
138{
139 struct task_struct *target;
140 int ret;
141
142 spin_lock(&task_capability_lock);
143 read_lock(&tasklist_lock);
144
145 if (pid && pid != task_pid_vnr(current)) {
146 target = find_task_by_vpid(pid);
147 if (!target) {
148 ret = -ESRCH;
149 goto out;
150 }
151 } else
152 target = current;
153
154 ret = security_capget(target, pEp, pIp, pPp);
155
156out:
157 read_unlock(&tasklist_lock);
158 spin_unlock(&task_capability_lock);
159
160 return ret;
161}
162
163/*
164 * cap_set_pg - set capabilities for all processes in a given process
165 * group. We call this holding task_capability_lock and tasklist_lock.
166 */
167static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
168 kernel_cap_t *inheritable,
169 kernel_cap_t *permitted)
170{
171 struct task_struct *g, *target;
172 int ret = -EPERM;
173 int found = 0;
174 struct pid *pgrp;
175
176 spin_lock(&task_capability_lock);
177 read_lock(&tasklist_lock);
178
179 pgrp = find_vpid(pgrp_nr);
180 do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
181 target = g;
182 while_each_thread(g, target) {
183 if (!security_capset_check(target, effective,
184 inheritable, permitted)) {
185 security_capset_set(target, effective,
186 inheritable, permitted);
187 ret = 0;
188 }
189 found = 1;
190 }
191 } while_each_pid_task(pgrp, PIDTYPE_PGID, g);
192
193 read_unlock(&tasklist_lock);
194 spin_unlock(&task_capability_lock);
195
196 if (!found)
197 ret = 0;
198 return ret;
199}
200
201/*
202 * cap_set_all - set capabilities for all processes other than init
203 * and self. We call this holding task_capability_lock and tasklist_lock.
204 */
205static inline int cap_set_all(kernel_cap_t *effective,
206 kernel_cap_t *inheritable,
207 kernel_cap_t *permitted)
208{
209 struct task_struct *g, *target;
210 int ret = -EPERM;
211 int found = 0;
212
213 spin_lock(&task_capability_lock);
214 read_lock(&tasklist_lock);
215
216 do_each_thread(g, target) {
217 if (target == current
218 || is_container_init(target->group_leader))
219 continue;
220 found = 1;
221 if (security_capset_check(target, effective, inheritable,
222 permitted))
223 continue;
224 ret = 0;
225 security_capset_set(target, effective, inheritable, permitted);
226 } while_each_thread(g, target);
227
228 read_unlock(&tasklist_lock);
229 spin_unlock(&task_capability_lock);
230
231 if (!found)
232 ret = 0;
233
234 return ret;
235}
236
237/*
238 * Given the target pid does not refer to the current process we
239 * need more elaborate support... (This support is not present when
240 * filesystem capabilities are configured.)
241 */
242static inline int do_sys_capset_other_tasks(pid_t pid, kernel_cap_t *effective,
243 kernel_cap_t *inheritable,
244 kernel_cap_t *permitted)
245{
246 struct task_struct *target;
247 int ret;
248
249 if (!capable(CAP_SETPCAP))
250 return -EPERM;
251
252 if (pid == -1) /* all procs other than current and init */
253 return cap_set_all(effective, inheritable, permitted);
254
255 else if (pid < 0) /* all procs in process group */
256 return cap_set_pg(-pid, effective, inheritable, permitted);
257
258 /* target != current */
259 spin_lock(&task_capability_lock);
260 read_lock(&tasklist_lock);
261
262 target = find_task_by_vpid(pid);
263 if (!target)
264 ret = -ESRCH;
265 else {
266 ret = security_capset_check(target, effective, inheritable,
267 permitted);
268
269 /* having verified that the proposed changes are legal,
270 we now put them into effect. */
271 if (!ret)
272 security_capset_set(target, effective, inheritable,
273 permitted);
274 }
275
276 read_unlock(&tasklist_lock);
277 spin_unlock(&task_capability_lock);
278
279 return ret;
280}
281
282#else /* ie., def CONFIG_SECURITY_FILE_CAPABILITIES */
283
284/* 130/*
285 * If we have configured with filesystem capability support, then the 131 * If we have configured with filesystem capability support, then the
286 * only thing that can change the capabilities of the current process 132 * only thing that can change the capabilities of the current process
@@ -315,22 +161,6 @@ static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
315} 161}
316 162
317/* 163/*
318 * With filesystem capability support configured, the kernel does not
319 * permit the changing of capabilities in one process by another
320 * process. (CAP_SETPCAP has much less broad semantics when configured
321 * this way.)
322 */
323static inline int do_sys_capset_other_tasks(pid_t pid,
324 kernel_cap_t *effective,
325 kernel_cap_t *inheritable,
326 kernel_cap_t *permitted)
327{
328 return -EPERM;
329}
330
331#endif /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */
332
333/*
334 * Atomically modify the effective capabilities returning the original 164 * Atomically modify the effective capabilities returning the original
335 * value. No permission check is performed here - it is assumed that the 165 * value. No permission check is performed here - it is assumed that the
336 * caller is permitted to set the desired effective capabilities. 166 * caller is permitted to set the desired effective capabilities.
@@ -424,16 +254,14 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
424 * @data: pointer to struct that contains the effective, permitted, 254 * @data: pointer to struct that contains the effective, permitted,
425 * and inheritable capabilities 255 * and inheritable capabilities
426 * 256 *
427 * Set capabilities for a given process, all processes, or all 257 * Set capabilities for the current process only. The ability to any other
428 * processes in a given process group. 258 * process(es) has been deprecated and removed.
429 * 259 *
430 * The restrictions on setting capabilities are specified as: 260 * The restrictions on setting capabilities are specified as:
431 * 261 *
432 * [pid is for the 'target' task. 'current' is the calling task.] 262 * I: any raised capabilities must be a subset of the old permitted
433 * 263 * P: any raised capabilities must be a subset of the old permitted
434 * I: any raised capabilities must be a subset of the (old current) permitted 264 * E: must be set to a subset of new permitted
435 * P: any raised capabilities must be a subset of the (old current) permitted
436 * E: must be set to a subset of (new target) permitted
437 * 265 *
438 * Returns 0 on success and < 0 on error. 266 * Returns 0 on success and < 0 on error.
439 */ 267 */
@@ -452,10 +280,13 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
452 if (get_user(pid, &header->pid)) 280 if (get_user(pid, &header->pid))
453 return -EFAULT; 281 return -EFAULT;
454 282
283 /* may only affect current now */
284 if (pid != 0 && pid != task_pid_vnr(current))
285 return -EPERM;
286
455 if (copy_from_user(&kdata, data, tocopy 287 if (copy_from_user(&kdata, data, tocopy
456 * sizeof(struct __user_cap_data_struct))) { 288 * sizeof(struct __user_cap_data_struct)))
457 return -EFAULT; 289 return -EFAULT;
458 }
459 290
460 for (i = 0; i < tocopy; i++) { 291 for (i = 0; i < tocopy; i++) {
461 effective.cap[i] = kdata[i].effective; 292 effective.cap[i] = kdata[i].effective;
@@ -473,32 +304,20 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
473 if (ret) 304 if (ret)
474 return ret; 305 return ret;
475 306
476 if (pid && (pid != task_pid_vnr(current))) 307 /* This lock is required even when filesystem capability support is
477 ret = do_sys_capset_other_tasks(pid, &effective, &inheritable, 308 * configured - it protects the sys_capget() call from returning
478 &permitted); 309 * incorrect data in the case that the targeted process is not the
479 else { 310 * current one.
480 /* 311 */
481 * This lock is required even when filesystem 312 spin_lock(&task_capability_lock);
482 * capability support is configured - it protects the
483 * sys_capget() call from returning incorrect data in
484 * the case that the targeted process is not the
485 * current one.
486 */
487 spin_lock(&task_capability_lock);
488
489 ret = security_capset_check(current, &effective, &inheritable,
490 &permitted);
491 /*
492 * Having verified that the proposed changes are
493 * legal, we now put them into effect.
494 */
495 if (!ret)
496 security_capset_set(current, &effective, &inheritable,
497 &permitted);
498 spin_unlock(&task_capability_lock);
499 }
500
501 313
314 ret = security_capset_check(&effective, &inheritable, &permitted);
315 /* Having verified that the proposed changes are legal, we now put them
316 * into effect.
317 */
318 if (!ret)
319 security_capset_set(&effective, &inheritable, &permitted);
320 spin_unlock(&task_capability_lock);
502 return ret; 321 return ret;
503} 322}
504 323