diff options
author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:14 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:14 -0500 |
commit | 1cdcbec1a3372c0c49c59d292e708fd07b509f18 (patch) | |
tree | d1bd302c8d66862da45b494cbc766fb4caa5e23e /security | |
parent | 8bbf4976b59fc9fc2861e79cab7beb3f6d647640 (diff) |
CRED: Neuter sys_capset()
Take away the ability for sys_capset() to affect processes other than current.
This means that current will not need to lock its own credentials when reading
them against interference by other processes.
This has effectively been the case for a while anyway, since:
(1) Without LSM enabled, sys_capset() is disallowed.
(2) With file-based capabilities, sys_capset() is neutered.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Acked-by: Andrew G. Morgan <morgan@kernel.org>
Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/commoncap.c | 29 | ||||
-rw-r--r-- | security/security.c | 18 | ||||
-rw-r--r-- | security/selinux/hooks.c | 10 |
3 files changed, 21 insertions, 36 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 8283271f0768..e3f36ef629fa 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -96,15 +96,6 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective, | |||
96 | 96 | ||
97 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | 97 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES |
98 | 98 | ||
99 | static inline int cap_block_setpcap(struct task_struct *target) | ||
100 | { | ||
101 | /* | ||
102 | * No support for remote process capability manipulation with | ||
103 | * filesystem capability support. | ||
104 | */ | ||
105 | return (target != current); | ||
106 | } | ||
107 | |||
108 | static inline int cap_inh_is_capped(void) | 99 | static inline int cap_inh_is_capped(void) |
109 | { | 100 | { |
110 | /* | 101 | /* |
@@ -119,7 +110,6 @@ static inline int cap_limit_ptraced_target(void) { return 1; } | |||
119 | 110 | ||
120 | #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | 111 | #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ |
121 | 112 | ||
122 | static inline int cap_block_setpcap(struct task_struct *t) { return 0; } | ||
123 | static inline int cap_inh_is_capped(void) { return 1; } | 113 | static inline int cap_inh_is_capped(void) { return 1; } |
124 | static inline int cap_limit_ptraced_target(void) | 114 | static inline int cap_limit_ptraced_target(void) |
125 | { | 115 | { |
@@ -128,21 +118,18 @@ static inline int cap_limit_ptraced_target(void) | |||
128 | 118 | ||
129 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | 119 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ |
130 | 120 | ||
131 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | 121 | int cap_capset_check (kernel_cap_t *effective, |
132 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 122 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
133 | { | 123 | { |
134 | if (cap_block_setpcap(target)) { | ||
135 | return -EPERM; | ||
136 | } | ||
137 | if (cap_inh_is_capped() | 124 | if (cap_inh_is_capped() |
138 | && !cap_issubset(*inheritable, | 125 | && !cap_issubset(*inheritable, |
139 | cap_combine(target->cap_inheritable, | 126 | cap_combine(current->cap_inheritable, |
140 | current->cap_permitted))) { | 127 | current->cap_permitted))) { |
141 | /* incapable of using this inheritable set */ | 128 | /* incapable of using this inheritable set */ |
142 | return -EPERM; | 129 | return -EPERM; |
143 | } | 130 | } |
144 | if (!cap_issubset(*inheritable, | 131 | if (!cap_issubset(*inheritable, |
145 | cap_combine(target->cap_inheritable, | 132 | cap_combine(current->cap_inheritable, |
146 | current->cap_bset))) { | 133 | current->cap_bset))) { |
147 | /* no new pI capabilities outside bounding set */ | 134 | /* no new pI capabilities outside bounding set */ |
148 | return -EPERM; | 135 | return -EPERM; |
@@ -150,7 +137,7 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | |||
150 | 137 | ||
151 | /* verify restrictions on target's new Permitted set */ | 138 | /* verify restrictions on target's new Permitted set */ |
152 | if (!cap_issubset (*permitted, | 139 | if (!cap_issubset (*permitted, |
153 | cap_combine (target->cap_permitted, | 140 | cap_combine (current->cap_permitted, |
154 | current->cap_permitted))) { | 141 | current->cap_permitted))) { |
155 | return -EPERM; | 142 | return -EPERM; |
156 | } | 143 | } |
@@ -163,12 +150,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | |||
163 | return 0; | 150 | return 0; |
164 | } | 151 | } |
165 | 152 | ||
166 | void cap_capset_set (struct task_struct *target, kernel_cap_t *effective, | 153 | void cap_capset_set (kernel_cap_t *effective, |
167 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 154 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
168 | { | 155 | { |
169 | target->cap_effective = *effective; | 156 | current->cap_effective = *effective; |
170 | target->cap_inheritable = *inheritable; | 157 | current->cap_inheritable = *inheritable; |
171 | target->cap_permitted = *permitted; | 158 | current->cap_permitted = *permitted; |
172 | } | 159 | } |
173 | 160 | ||
174 | static inline void bprm_clear_caps(struct linux_binprm *bprm) | 161 | static inline void bprm_clear_caps(struct linux_binprm *bprm) |
diff --git a/security/security.c b/security/security.c index 346f21e0ec2c..dca37381e2a7 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -145,20 +145,18 @@ int security_capget(struct task_struct *target, | |||
145 | return security_ops->capget(target, effective, inheritable, permitted); | 145 | return security_ops->capget(target, effective, inheritable, permitted); |
146 | } | 146 | } |
147 | 147 | ||
148 | int security_capset_check(struct task_struct *target, | 148 | int security_capset_check(kernel_cap_t *effective, |
149 | kernel_cap_t *effective, | 149 | kernel_cap_t *inheritable, |
150 | kernel_cap_t *inheritable, | 150 | kernel_cap_t *permitted) |
151 | kernel_cap_t *permitted) | ||
152 | { | 151 | { |
153 | return security_ops->capset_check(target, effective, inheritable, permitted); | 152 | return security_ops->capset_check(effective, inheritable, permitted); |
154 | } | 153 | } |
155 | 154 | ||
156 | void security_capset_set(struct task_struct *target, | 155 | void security_capset_set(kernel_cap_t *effective, |
157 | kernel_cap_t *effective, | 156 | kernel_cap_t *inheritable, |
158 | kernel_cap_t *inheritable, | 157 | kernel_cap_t *permitted) |
159 | kernel_cap_t *permitted) | ||
160 | { | 158 | { |
161 | security_ops->capset_set(target, effective, inheritable, permitted); | 159 | security_ops->capset_set(effective, inheritable, permitted); |
162 | } | 160 | } |
163 | 161 | ||
164 | int security_capable(struct task_struct *tsk, int cap) | 162 | int security_capable(struct task_struct *tsk, int cap) |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 378dc53c08e8..df9986940e9c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1790,22 +1790,22 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective, | |||
1790 | return secondary_ops->capget(target, effective, inheritable, permitted); | 1790 | return secondary_ops->capget(target, effective, inheritable, permitted); |
1791 | } | 1791 | } |
1792 | 1792 | ||
1793 | static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective, | 1793 | static int selinux_capset_check(kernel_cap_t *effective, |
1794 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 1794 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
1795 | { | 1795 | { |
1796 | int error; | 1796 | int error; |
1797 | 1797 | ||
1798 | error = secondary_ops->capset_check(target, effective, inheritable, permitted); | 1798 | error = secondary_ops->capset_check(effective, inheritable, permitted); |
1799 | if (error) | 1799 | if (error) |
1800 | return error; | 1800 | return error; |
1801 | 1801 | ||
1802 | return task_has_perm(current, target, PROCESS__SETCAP); | 1802 | return task_has_perm(current, current, PROCESS__SETCAP); |
1803 | } | 1803 | } |
1804 | 1804 | ||
1805 | static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, | 1805 | static void selinux_capset_set(kernel_cap_t *effective, |
1806 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 1806 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
1807 | { | 1807 | { |
1808 | secondary_ops->capset_set(target, effective, inheritable, permitted); | 1808 | secondary_ops->capset_set(effective, inheritable, permitted); |
1809 | } | 1809 | } |
1810 | 1810 | ||
1811 | static int selinux_capable(struct task_struct *tsk, int cap, int audit) | 1811 | static int selinux_capable(struct task_struct *tsk, int cap, int audit) |