diff options
Diffstat (limited to 'security/commoncap.c')
-rw-r--r-- | security/commoncap.c | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 01ab47845dcf..5aba82679a0b 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -25,20 +25,6 @@ | |||
25 | #include <linux/mount.h> | 25 | #include <linux/mount.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | 27 | ||
28 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
29 | /* | ||
30 | * Because of the reduced scope of CAP_SETPCAP when filesystem | ||
31 | * capabilities are in effect, it is safe to allow this capability to | ||
32 | * be available in the default configuration. | ||
33 | */ | ||
34 | # define CAP_INIT_BSET CAP_FULL_SET | ||
35 | #else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
36 | # define CAP_INIT_BSET CAP_INIT_EFF_SET | ||
37 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
38 | |||
39 | kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */ | ||
40 | EXPORT_SYMBOL(cap_bset); | ||
41 | |||
42 | /* Global security state */ | 28 | /* Global security state */ |
43 | 29 | ||
44 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | 30 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ |
@@ -140,6 +126,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | |||
140 | /* incapable of using this inheritable set */ | 126 | /* incapable of using this inheritable set */ |
141 | return -EPERM; | 127 | return -EPERM; |
142 | } | 128 | } |
129 | if (!cap_issubset(*inheritable, | ||
130 | cap_combine(target->cap_inheritable, | ||
131 | current->cap_bset))) { | ||
132 | /* no new pI capabilities outside bounding set */ | ||
133 | return -EPERM; | ||
134 | } | ||
143 | 135 | ||
144 | /* verify restrictions on target's new Permitted set */ | 136 | /* verify restrictions on target's new Permitted set */ |
145 | if (!cap_issubset (*permitted, | 137 | if (!cap_issubset (*permitted, |
@@ -337,10 +329,11 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) | |||
337 | /* Derived from fs/exec.c:compute_creds. */ | 329 | /* Derived from fs/exec.c:compute_creds. */ |
338 | kernel_cap_t new_permitted, working; | 330 | kernel_cap_t new_permitted, working; |
339 | 331 | ||
340 | new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); | 332 | new_permitted = cap_intersect(bprm->cap_permitted, |
341 | working = cap_intersect (bprm->cap_inheritable, | 333 | current->cap_bset); |
334 | working = cap_intersect(bprm->cap_inheritable, | ||
342 | current->cap_inheritable); | 335 | current->cap_inheritable); |
343 | new_permitted = cap_combine (new_permitted, working); | 336 | new_permitted = cap_combine(new_permitted, working); |
344 | 337 | ||
345 | if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || | 338 | if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || |
346 | !cap_issubset (new_permitted, current->cap_permitted)) { | 339 | !cap_issubset (new_permitted, current->cap_permitted)) { |
@@ -581,6 +574,23 @@ int cap_task_kill(struct task_struct *p, struct siginfo *info, | |||
581 | 574 | ||
582 | return -EPERM; | 575 | return -EPERM; |
583 | } | 576 | } |
577 | |||
578 | /* | ||
579 | * called from kernel/sys.c for prctl(PR_CABSET_DROP) | ||
580 | * done without task_capability_lock() because it introduces | ||
581 | * no new races - i.e. only another task doing capget() on | ||
582 | * this task could get inconsistent info. There can be no | ||
583 | * racing writer bc a task can only change its own caps. | ||
584 | */ | ||
585 | long cap_prctl_drop(unsigned long cap) | ||
586 | { | ||
587 | if (!capable(CAP_SETPCAP)) | ||
588 | return -EPERM; | ||
589 | if (!cap_valid(cap)) | ||
590 | return -EINVAL; | ||
591 | cap_lower(current->cap_bset, cap); | ||
592 | return 0; | ||
593 | } | ||
584 | #else | 594 | #else |
585 | int cap_task_setscheduler (struct task_struct *p, int policy, | 595 | int cap_task_setscheduler (struct task_struct *p, int policy, |
586 | struct sched_param *lp) | 596 | struct sched_param *lp) |