[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <87eer4ysm5.fsf_-_@x220.int.ebiederm.org>
Date: Thu, 28 May 2020 10:41:22 -0500
From: ebiederm@...ssion.com (Eric W. Biederman)
To: <linux-kernel@...r.kernel.org>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
Oleg Nesterov <oleg@...hat.com>, Jann Horn <jannh@...gle.com>,
Kees Cook <keescook@...omium.org>,
Greg Ungerer <gerg@...ux-m68k.org>,
Rob Landley <rob@...dley.net>,
Bernd Edlinger <bernd.edlinger@...mail.de>,
<linux-fsdevel@...r.kernel.org>, Al Viro <viro@...IV.linux.org.uk>,
Alexey Dobriyan <adobriyan@...il.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Casey Schaufler <casey@...aufler-ca.com>,
linux-security-module@...r.kernel.org,
James Morris <jmorris@...ei.org>,
"Serge E. Hallyn" <serge@...lyn.com>,
Andy Lutomirski <luto@...capital.net>
Subject: [PATCH 01/11] exec: Reduce bprm->per_clear to a single bit
The bprm->per_clear field only takes the values 0 and
PER_CLEAR_ON_SETID. Reduce the field to a signle bit to make it clear
that the only question is should the dangerous personality bits be
cleared or not.
Update the documentation of the security lsm hooks.
Signed-off-by: "Eric W. Biederman" <ebiederm@...ssion.com>
---
fs/exec.c | 7 ++++---
include/linux/binfmts.h | 4 +++-
include/linux/lsm_hooks.h | 4 ++++
security/apparmor/domain.c | 2 +-
security/commoncap.c | 2 +-
security/selinux/hooks.c | 2 +-
security/smack/smack_lsm.c | 2 +-
7 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index c3c879a55d65..51fab62b9fca 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1354,7 +1354,8 @@ int begin_new_exec(struct linux_binprm * bprm)
me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD |
PF_NOFREEZE | PF_NO_SETAFFINITY);
flush_thread();
- me->personality &= ~bprm->per_clear;
+ if (bprm->per_clear)
+ me->personality &= ~PER_CLEAR_ON_SETID;
/*
* We have to apply CLOEXEC before we change whether the process is
@@ -1628,12 +1629,12 @@ static void bprm_fill_uid(struct linux_binprm *bprm)
return;
if (mode & S_ISUID) {
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
bprm->cred->euid = uid;
}
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
bprm->cred->egid = gid;
}
}
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 7fc05929c967..e7959a6a895a 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -26,6 +26,9 @@ struct linux_binprm {
unsigned long p; /* current top of mem */
unsigned long argmin; /* rlimit marker for copy_strings() */
unsigned int
+ /* Should unsafe personality bits be cleared? */
+ per_clear:1,
+
/* Should an execfd be passed to userspace? */
have_execfd:1,
@@ -55,7 +58,6 @@ struct linux_binprm {
struct file * file;
struct cred *cred; /* new credentials */
int unsafe; /* how unsafe this exec is (mask of LSM_UNSAFE_*) */
- unsigned int per_clear; /* bits to clear in current->personality */
int argc, envc;
const char * filename; /* Name of binary as seen by procps */
const char * interp; /* Name of the binary really executed. Most
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d618ecc4d660..0ca68ad53592 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -42,6 +42,8 @@
* (e.g. for transitions between security domains).
* The hook must set @bprm->secureexec to 1 if AT_SECURE should be set to
* request libc enable secure mode.
+ * The hook must set @bprm->per_clear to 1 if the dangerous personality
+ * bits must be cleared from current->personality.
* @bprm contains the linux_binprm structure.
* Return 0 if the hook is successful and permission is granted.
* @bprm_repopulate_creds:
@@ -55,6 +57,8 @@
* transitions between security domains).
* The hook must set @bprm->active_secureexec to 1 if AT_SECURE should be set to
* request libc enable secure mode.
+ * The hook must set @bprm->per_clear to 1 if the dangerous personality
+ * bits must be cleared from current->personality.
* @bprm contains the linux_binprm structure.
* Return 0 if the hook is successful and permission is granted.
* @bprm_check_security:
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 0b870a647488..c6d00735a40a 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -962,7 +962,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
aa_label_printk(new, GFP_KERNEL);
dbg_printk("\n");
}
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
}
aa_put_label(cred_label(bprm->cred));
/* transfer reference, released when cred is freed */
diff --git a/security/commoncap.c b/security/commoncap.c
index 77b04cb6feac..48b556046483 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -826,7 +826,7 @@ int cap_bprm_repopulate_creds(struct linux_binprm *bprm)
/* if we have fs caps, clear dangerous personality flags */
if (__cap_gained(permitted, new, old))
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
/* Don't let someone trace a set[ug]id/setpcap binary with the revised
* credentials unless they have the appropriate permit.
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 718345dd76bb..6bea1b879fdb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2385,7 +2385,7 @@ static int selinux_bprm_creds_for_exec(struct linux_binprm *bprm)
}
/* Clear any possibly unsafe personality bits on exec: */
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
/* Enable secure mode for SIDs transitions unless
the noatsecure permission is granted between
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 0ac8f4518d07..a0d2fad27b33 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -933,7 +933,7 @@ static int smack_bprm_creds_for_exec(struct linux_binprm *bprm)
return -EPERM;
bsp->smk_task = isp->smk_task;
- bprm->per_clear |= PER_CLEAR_ON_SETID;
+ bprm->per_clear = 1;
/* Decide if this is a secure exec. */
if (bsp->smk_task != bsp->smk_forked)
--
2.25.0
Powered by blists - more mailing lists