aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:14 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:14 -0500
commit1cdcbec1a3372c0c49c59d292e708fd07b509f18 (patch)
treed1bd302c8d66862da45b494cbc766fb4caa5e23e /security
parent8bbf4976b59fc9fc2861e79cab7beb3f6d647640 (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.c29
-rw-r--r--security/security.c18
-rw-r--r--security/selinux/hooks.c10
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
99static 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
108static inline int cap_inh_is_capped(void) 99static 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
122static inline int cap_block_setpcap(struct task_struct *t) { return 0; }
123static inline int cap_inh_is_capped(void) { return 1; } 113static inline int cap_inh_is_capped(void) { return 1; }
124static inline int cap_limit_ptraced_target(void) 114static 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
131int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, 121int 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
166void cap_capset_set (struct task_struct *target, kernel_cap_t *effective, 153void 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
174static inline void bprm_clear_caps(struct linux_binprm *bprm) 161static 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
148int security_capset_check(struct task_struct *target, 148int 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
156void security_capset_set(struct task_struct *target, 155void 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
164int security_capable(struct task_struct *tsk, int cap) 162int 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
1793static int selinux_capset_check(struct task_struct *target, kernel_cap_t *effective, 1793static 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
1805static void selinux_capset_set(struct task_struct *target, kernel_cap_t *effective, 1805static 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
1811static int selinux_capable(struct task_struct *tsk, int cap, int audit) 1811static int selinux_capable(struct task_struct *tsk, int cap, int audit)