This reduces the kernel size by 289 bytes.
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
security/commoncap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/security/commoncap.c b/security/commoncap.c
index 9bfef94..d48fdd8 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -512,7 +512,7 @@ int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid,
* yet with increased caps.
* So we check for increased caps on the target process.
*/
-static inline int cap_safe_nice(struct task_struct *p)
+static int cap_safe_nice(struct task_struct *p)
{
if (!cap_issubset(p->cap_permitted, current->cap_permitted) &&
!capable(CAP_SYS_NICE))
--
1.5.1.1.GIT
--
Clean up the sys_capset codepath a bit to account for the fact
that you can now not ever, never, capset on another task.
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
kernel/capability.c | 83 +++++++++++++++++++-------------------------------
1 files changed, 32 insertions(+), 51 deletions(-)
diff --git a/kernel/capability.c b/kernel/capability.c
index d39c989..92dd85b 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -132,46 +132,31 @@ static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
* process. The net result is that we can limit our use of locks to
* when we are reading the caps of another process.
*/
-static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
+static int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
kernel_cap_t *pIp, kernel_cap_t *pPp)
{
int ret;
+ struct task_struct *target;
- if (pid && (pid != task_pid_vnr(current))) {
- struct task_struct *target;
+ if (!pid || pid == task_pid_vnr(current))
+ return security_capget(current, pEp, pIp, pPp);
- spin_lock(&task_capability_lock);
- read_lock(&tasklist_lock);
+ spin_lock(&task_capability_lock);
+ read_lock(&tasklist_lock);
- target = find_task_by_vpid(pid);
- if (!target)
- ret = -ESRCH;
- else
- ret = security_capget(target, pEp, pIp, pPp);
+ target = find_task_by_vpid(pid);
+ if (!target)
+ ret = -ESRCH;
+ else
+ ret = security_capget(target, pEp, pIp, pPp);
- read_unlock(&tasklist_lock);
- spin_unlock(&task_capability_lock);
- } else
- ret = security_capget(current, pEp, pIp, pPp);
+ read_unlock(&tasklist_lock);
+ spin_unlock(&task_capability_lock);
return ret;
}
/*
- * With filesystem capability support configured, the kernel does not
- * permit the changing of capabilities in one process by another
- * process. (CAP_SETPCAP has much less broad semantics when configured
- * this way.)
- */
-static inline int do_sys_capset_other_tasks(pid_t pid,
- ...cap_limit_ptraced_target always returns 1, so nix it.
cap_block_setpcap can't return 1 any more, because
kernel/capabilities.c:sys_capset() will return -EPERM
if it is called on a task other than current, and will
never get to cap_capset_check.
This brings the vmlinux size with my config down another
16 bytes (making up for the 8 byte increase from the
last patch).
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
security/commoncap.c | 22 +++-------------------
1 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/security/commoncap.c b/security/commoncap.c
index d48fdd8..e5afb7c 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -93,15 +93,6 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective,
return 0;
}
-static inline int cap_block_setpcap(struct task_struct *target)
-{
- /*
- * No support for remote process capability manipulation with
- * filesystem capability support.
- */
- return (target != current);
-}
-
static inline int cap_inh_is_capped(void)
{
/*
@@ -112,14 +103,9 @@ static inline int cap_inh_is_capped(void)
return (cap_capable(current, CAP_SETPCAP) != 0);
}
-static inline int cap_limit_ptraced_target(void) { return 1; }
-
int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
kernel_cap_t *inheritable, kernel_cap_t *permitted)
{
- if (cap_block_setpcap(target)) {
- return -EPERM;
- }
if (cap_inh_is_capped()
&& !cap_issubset(*inheritable,
cap_combine(target->cap_inheritable,
@@ -343,11 +329,9 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
bprm->e_uid = current->uid;
bprm->e_gid = current->gid;
}
- if (cap_limit_ptraced_target()) {
- bprm->cap_post_exec_permitted = cap_intersect(
- bprm->cap_post_exec_permitted,
- current->cap_permitted);
- }
+ bprm->cap_post_exec_permitted = cap_intersect(
+ bprm->cap_post_exec_permitted,
+ current->cap_permitted);
}
...Two error conditions at the top of get_file_caps() call
bprm_clear_caps(). However, the bprm capabilities have not
yet been set at this point.
Remove those calls (saving another 16 bytes on vmlinux).
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
security/commoncap.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/security/commoncap.c b/security/commoncap.c
index e5afb7c..43bba7a 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -250,15 +250,11 @@ static int get_file_caps(struct linux_binprm *bprm)
struct vfs_cap_data vcaps;
struct inode *inode;
- if (!file_caps_enabled) {
- bprm_clear_caps(bprm);
+ if (!file_caps_enabled)
return 0;
- }
- if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
- bprm_clear_caps(bprm);
+ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
return 0;
- }
dentry = dget(bprm->file->f_dentry);
inode = dentry->d_inode;
--
1.5.1.1.GIT
--
Andrew Morgan, if you have a moment, please do take a close look and make sure I'm not doing anything stupid/wrong in the cleanups! However ltp shows no difference with and without the patchset. Following are the kernel sizes after some of the patches. original, pre-patch, with file capabilities compiled out: text data bss dec hex filename 4188468 234432 316472 4739372 48512c vmlinux original, pre-patch, with file capabilities compiled in: 4189356 234432 316472 4740260 4854a4 vmlinux plain with fcaps always-on: 4189392 234456 316472 4740320 4854e0 vmlinux with non-inline cap_safe_nice: 4189112 234456 316472 4740040 4853c8 vmlinux with cleaned-up setcap: 4189120 234456 316472 4740048 4853d0 vmlinux with needless check for target!=current removed from cap_capset: 4189104 234456 316472 4740032 4853c0 vmlinux with needless(?) bprm_clear_caps calls removed: 4189088 234456 316472 4740016 4853b0 vmlinux thanks, -serge --
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Serge, I'd much rather simply remove the target argument from the security_capset_check() call. Relying on the caller to not do something bad seems fragile... If the code internally operates on current only, then it doesn't need a target argument... No? (Evidently, such a change is also needed to selinux_capset_check() too, but this doesn't look like it will pose a problem for the selinux code.) Cheers Andrew -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFI3bjz+bHCR3gb8jsRAqJpAJ9Ca1pADkG5BnGoOVZA+EmZbuRPfgCgoQ95 ljvsvj7Ssp+0mXDuCy0/TnU= =79ni -----END PGP SIGNATURE----- --
Yes, I did do that in a patch on top of all of these. It increased the kernel size by 8 (or was it 16) bytes :) I assume that was because now there were more references to 'current' which is inlined? So I should be able to fix that by saving current() away at the top of the fn. Will try that. thanks, --
Here is a patch (on top of the others) doing that. thanks, -serge Subject: [PATCH] capabilities: remove target argument from capset_check and set Since it is no longer possible to set capabilities on another task, remove the 'target' option from capset_set and capset_check. Since the userspace API shouldn't change, we maintain 'pid' as a valid option to the actual sys_capset(), continuing to return -EPERM when pid is not current's pid. Signed-off-by: Serge E. Hallyn <serue@us.ibm.com> --- include/linux/security.h | 49 ++++++++++++++++------------------------------ kernel/capability.c | 6 ++---- security/commoncap.c | 29 +++++++++++++++------------ security/security.c | 18 ++++++++--------- security/selinux/hooks.c | 15 ++++++++------ 5 files changed, 51 insertions(+), 66 deletions(-) 35b1a7906d26fd10da34e5cd350470abb812a91c diff --git a/include/linux/security.h b/include/linux/security.h index 80c4d00..7b9f7a2 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -49,8 +49,8 @@ extern int cap_settime(struct timespec * extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); extern int cap_ptrace_traceme(struct task_struct *parent); extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); -extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); -extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); +extern int cap_capset_check(kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); +extern void cap_capset_set(kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern int cap_bprm_set_security(struct linux_binprm *bprm); extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); extern int ...
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Serge, I have to say I'm a bit confused by this one. Specifically, the cap_get_target_pid() change. In your 5/6 patch, you say this change ("the previous patch") makes the kernel bigger? Is this because of the cap_get_target_pid() changes? Since you are fighting to reduce space, if it bloats the code does the cap_get_target_pid() part of the change make sense? Cheers Andrew -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFI3b1s+bHCR3gb8jsRAkWCAJ4j5Q5NQc2TD8B+WOYJ1JIqV1GdqQCg1qQU +qzZPOvwo/W/73BuA+HvuxQ= =fRje -----END PGP SIGNATURE----- --
Yes I think it does. Yes my goal was to decrease the kernel size, but having cleaner code - and getting rid of dead codepaths - is more important. It may be hard to tell by looking at the patch, but I think the end-result is really far better. thanks, -serge --
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Acked-by: Andrew G. Morgan <morgan@kernel.org> Cheers -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFI3bX0+bHCR3gb8jsRApVqAKCuFmvJTlIiAYxXW5W3JNncFYmmrQCfa95h Ik/MLVnpPtZdmuInkJSOof4= =3aYe -----END PGP SIGNATURE----- --
This one makes sense on its own, applied to: git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6#next - James -- James Morris <jmorris@namei.org> --
