aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/commoncap.c44
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
39kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */
40EXPORT_SYMBOL(cap_bset);
41
42/* Global security state */ 28/* Global security state */
43 29
44unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ 30unsigned 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 */
585long 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
585int cap_task_setscheduler (struct task_struct *p, int policy, 595int cap_task_setscheduler (struct task_struct *p, int policy,
586 struct sched_param *lp) 596 struct sched_param *lp)