diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 59 | ||||
-rw-r--r-- | security/dummy.c | 16 |
2 files changed, 61 insertions, 14 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 778cb0cfc5d8..48ca5b092768 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -24,6 +24,25 @@ | |||
24 | #include <linux/hugetlb.h> | 24 | #include <linux/hugetlb.h> |
25 | #include <linux/mount.h> | 25 | #include <linux/mount.h> |
26 | 26 | ||
27 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
28 | /* | ||
29 | * Because of the reduced scope of CAP_SETPCAP when filesystem | ||
30 | * capabilities are in effect, it is safe to allow this capability to | ||
31 | * be available in the default configuration. | ||
32 | */ | ||
33 | # define CAP_INIT_BSET CAP_FULL_SET | ||
34 | #else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
35 | # define CAP_INIT_BSET CAP_INIT_EFF_SET | ||
36 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
37 | |||
38 | kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */ | ||
39 | EXPORT_SYMBOL(cap_bset); | ||
40 | |||
41 | /* Global security state */ | ||
42 | |||
43 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | ||
44 | EXPORT_SYMBOL(securebits); | ||
45 | |||
27 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | 46 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
28 | { | 47 | { |
29 | NETLINK_CB(skb).eff_cap = current->cap_effective; | 48 | NETLINK_CB(skb).eff_cap = current->cap_effective; |
@@ -73,14 +92,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective, | |||
73 | return 0; | 92 | return 0; |
74 | } | 93 | } |
75 | 94 | ||
95 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
96 | |||
97 | static inline int cap_block_setpcap(struct task_struct *target) | ||
98 | { | ||
99 | /* | ||
100 | * No support for remote process capability manipulation with | ||
101 | * filesystem capability support. | ||
102 | */ | ||
103 | return (target != current); | ||
104 | } | ||
105 | |||
106 | static inline int cap_inh_is_capped(void) | ||
107 | { | ||
108 | /* | ||
109 | * return 1 if changes to the inheritable set are limited | ||
110 | * to the old permitted set. | ||
111 | */ | ||
112 | return !cap_capable(current, CAP_SETPCAP); | ||
113 | } | ||
114 | |||
115 | #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
116 | |||
117 | static inline int cap_block_setpcap(struct task_struct *t) { return 0; } | ||
118 | static inline int cap_inh_is_capped(void) { return 1; } | ||
119 | |||
120 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
121 | |||
76 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | 122 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, |
77 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 123 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
78 | { | 124 | { |
79 | /* Derived from kernel/capability.c:sys_capset. */ | 125 | if (cap_block_setpcap(target)) { |
80 | /* verify restrictions on target's new Inheritable set */ | 126 | return -EPERM; |
81 | if (!cap_issubset (*inheritable, | 127 | } |
82 | cap_combine (target->cap_inheritable, | 128 | if (cap_inh_is_capped() |
83 | current->cap_permitted))) { | 129 | && !cap_issubset(*inheritable, |
130 | cap_combine(target->cap_inheritable, | ||
131 | current->cap_permitted))) { | ||
132 | /* incapable of using this inheritable set */ | ||
84 | return -EPERM; | 133 | return -EPERM; |
85 | } | 134 | } |
86 | 135 | ||
diff --git a/security/dummy.c b/security/dummy.c index bc43d4c7383e..6d895ade73de 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -37,15 +37,13 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective, | |||
37 | kernel_cap_t * inheritable, kernel_cap_t * permitted) | 37 | kernel_cap_t * inheritable, kernel_cap_t * permitted) |
38 | { | 38 | { |
39 | *effective = *inheritable = *permitted = 0; | 39 | *effective = *inheritable = *permitted = 0; |
40 | if (!issecure(SECURE_NOROOT)) { | 40 | if (target->euid == 0) { |
41 | if (target->euid == 0) { | 41 | *permitted |= (~0 & ~CAP_FS_MASK); |
42 | *permitted |= (~0 & ~CAP_FS_MASK); | 42 | *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); |
43 | *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); | 43 | } |
44 | } | 44 | if (target->fsuid == 0) { |
45 | if (target->fsuid == 0) { | 45 | *permitted |= CAP_FS_MASK; |
46 | *permitted |= CAP_FS_MASK; | 46 | *effective |= CAP_FS_MASK; |
47 | *effective |= CAP_FS_MASK; | ||
48 | } | ||
49 | } | 47 | } |
50 | return 0; | 48 | return 0; |
51 | } | 49 | } |