diff options
Diffstat (limited to 'security/commoncap.c')
-rw-r--r-- | security/commoncap.c | 59 |
1 files changed, 54 insertions, 5 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 | ||