All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Kees Cook <keescook@chromium.org>,
	Serge Hallyn <serge@hallyn.com>,
	Andy Lutomirski <luto@kernel.org>,
	David Howells <dhowells@redhat.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	John Johansen <john.johansen@canonical.com>,
	Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <sds@tycho.nsa.gov>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
	James Morris <james.l.morris@oracle.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-fsdevel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v3 06/15] commoncap: Refactor to remove bprm_secureexec hook
Date: Tue, 18 Jul 2017 15:25:27 -0700	[thread overview]
Message-ID: <1500416736-49829-7-git-send-email-keescook@chromium.org> (raw)
In-Reply-To: <1500416736-49829-1-git-send-email-keescook@chromium.org>

The commoncap implementation of the bprm_secureexec hook is the only LSM
that depends on the final call to its bprm_set_creds hook (since it may
be called for multiple files, it ignores bprm->called_set_creds). As a
result, it cannot safely _clear_ bprm->secureexec since other LSMs may
have set it.  Instead, remove the bprm_secureexec hook by introducing a
new flag to bprm specific to commoncap: cap_elevated. This is similar to
cap_effective, but that is used for a specific subset of elevated
privileges, and exists solely to track state from bprm_set_creds to
bprm_secureexec. As such, it will be removed in the next patch.

Here, set the new bprm->cap_elevated flag when setuid/setgid has happened
from bprm_fill_uid() or fscapabilities have been prepared. This temporarily
moves the bprm_secureexec hook to a static inline. The helper will be
removed in the next patch; this makes the step easier to review and bisect,
since this does not introduce any changes to inputs nor outputs to the
"elevated privileges" calculation.

The new flag is merged with the bprm->secureexec flag in setup_new_exec()
since this marks the end of any further prepare_binprm() calls.

Cc: Serge Hallyn <serge@hallyn.com>
Cc: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/exec.c               |  7 +++++++
 include/linux/binfmts.h |  7 +++++++
 security/commoncap.c    | 12 ++++++++----
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 925c85a45d97..53ffa739fb58 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1330,6 +1330,13 @@ EXPORT_SYMBOL(would_dump);
 
 void setup_new_exec(struct linux_binprm * bprm)
 {
+	/*
+	 * Once here, prepare_binrpm() will not be called any more, so
+	 * the final state of setuid/setgid/fscaps can be merged into the
+	 * secureexec flag.
+	 */
+	bprm->secureexec |= bprm->cap_elevated;
+
 	arch_pick_mmap_layout(current->mm);
 
 	/* This is the point of no return */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 36be5a67517a..a82f5edf23f9 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -35,6 +35,13 @@ struct linux_binprm {
 				 * false if not; except for init which inherits
 				 * its parent's caps anyway */
 		/*
+		 * True if most recent call to the commoncaps bprm_set_creds
+		 * hook (due to multiple prepare_binprm() calls from the
+		 * binfmt_script/misc handlers) resulted in elevated
+		 * privileges.
+		 */
+		cap_elevated:1,
+		/*
 		 * Set by bprm_set_creds hook to indicate a privilege-gaining
 		 * exec has happened. Used to sanitize execution environment
 		 * and to set AT_SECURE auxv for glibc.
diff --git a/security/commoncap.c b/security/commoncap.c
index 7abebd782d5e..abb6050c8083 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -481,6 +481,8 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
 	return rc;
 }
 
+static int is_secureexec(struct linux_binprm *bprm);
+
 /**
  * cap_bprm_set_creds - Set up the proposed credentials for execve().
  * @bprm: The execution parameters, including the proposed creds
@@ -614,11 +616,14 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 	if (WARN_ON(!cap_ambient_invariant_ok(new)))
 		return -EPERM;
 
+	/* Check for privilege-elevated exec. */
+	bprm->cap_elevated = is_secureexec(bprm);
+
 	return 0;
 }
 
 /**
- * cap_bprm_secureexec - Determine whether a secure execution is required
+ * is_secureexec - Determine whether a secure execution is required
  * @bprm: The execution parameters
  *
  * Determine whether a secure execution is required, return 1 if it is, and 0
@@ -627,9 +632,9 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
  * The credentials have been committed by this point, and so are no longer
  * available through @bprm->cred.
  */
-int cap_bprm_secureexec(struct linux_binprm *bprm)
+static int is_secureexec(struct linux_binprm *bprm)
 {
-	const struct cred *cred = current_cred();
+	const struct cred *cred = bprm->cred;
 	kuid_t root_uid = make_kuid(cred->user_ns, 0);
 
 	if (!uid_eq(cred->uid, root_uid)) {
@@ -1079,7 +1084,6 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
 	LSM_HOOK_INIT(capget, cap_capget),
 	LSM_HOOK_INIT(capset, cap_capset),
 	LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
-	LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
 	LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
 	LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
 	LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: keescook@chromium.org (Kees Cook)
To: linux-security-module@vger.kernel.org
Subject: [PATCH v3 06/15] commoncap: Refactor to remove bprm_secureexec hook
Date: Tue, 18 Jul 2017 15:25:27 -0700	[thread overview]
Message-ID: <1500416736-49829-7-git-send-email-keescook@chromium.org> (raw)
In-Reply-To: <1500416736-49829-1-git-send-email-keescook@chromium.org>

The commoncap implementation of the bprm_secureexec hook is the only LSM
that depends on the final call to its bprm_set_creds hook (since it may
be called for multiple files, it ignores bprm->called_set_creds). As a
result, it cannot safely _clear_ bprm->secureexec since other LSMs may
have set it.  Instead, remove the bprm_secureexec hook by introducing a
new flag to bprm specific to commoncap: cap_elevated. This is similar to
cap_effective, but that is used for a specific subset of elevated
privileges, and exists solely to track state from bprm_set_creds to
bprm_secureexec. As such, it will be removed in the next patch.

Here, set the new bprm->cap_elevated flag when setuid/setgid has happened
from bprm_fill_uid() or fscapabilities have been prepared. This temporarily
moves the bprm_secureexec hook to a static inline. The helper will be
removed in the next patch; this makes the step easier to review and bisect,
since this does not introduce any changes to inputs nor outputs to the
"elevated privileges" calculation.

The new flag is merged with the bprm->secureexec flag in setup_new_exec()
since this marks the end of any further prepare_binprm() calls.

Cc: Serge Hallyn <serge@hallyn.com>
Cc: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/exec.c               |  7 +++++++
 include/linux/binfmts.h |  7 +++++++
 security/commoncap.c    | 12 ++++++++----
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 925c85a45d97..53ffa739fb58 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1330,6 +1330,13 @@ EXPORT_SYMBOL(would_dump);
 
 void setup_new_exec(struct linux_binprm * bprm)
 {
+	/*
+	 * Once here, prepare_binrpm() will not be called any more, so
+	 * the final state of setuid/setgid/fscaps can be merged into the
+	 * secureexec flag.
+	 */
+	bprm->secureexec |= bprm->cap_elevated;
+
 	arch_pick_mmap_layout(current->mm);
 
 	/* This is the point of no return */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 36be5a67517a..a82f5edf23f9 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -35,6 +35,13 @@ struct linux_binprm {
 				 * false if not; except for init which inherits
 				 * its parent's caps anyway */
 		/*
+		 * True if most recent call to the commoncaps bprm_set_creds
+		 * hook (due to multiple prepare_binprm() calls from the
+		 * binfmt_script/misc handlers) resulted in elevated
+		 * privileges.
+		 */
+		cap_elevated:1,
+		/*
 		 * Set by bprm_set_creds hook to indicate a privilege-gaining
 		 * exec has happened. Used to sanitize execution environment
 		 * and to set AT_SECURE auxv for glibc.
diff --git a/security/commoncap.c b/security/commoncap.c
index 7abebd782d5e..abb6050c8083 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -481,6 +481,8 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
 	return rc;
 }
 
+static int is_secureexec(struct linux_binprm *bprm);
+
 /**
  * cap_bprm_set_creds - Set up the proposed credentials for execve().
  * @bprm: The execution parameters, including the proposed creds
@@ -614,11 +616,14 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 	if (WARN_ON(!cap_ambient_invariant_ok(new)))
 		return -EPERM;
 
+	/* Check for privilege-elevated exec. */
+	bprm->cap_elevated = is_secureexec(bprm);
+
 	return 0;
 }
 
 /**
- * cap_bprm_secureexec - Determine whether a secure execution is required
+ * is_secureexec - Determine whether a secure execution is required
  * @bprm: The execution parameters
  *
  * Determine whether a secure execution is required, return 1 if it is, and 0
@@ -627,9 +632,9 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
  * The credentials have been committed by this point, and so are no longer
  * available through @bprm->cred.
  */
-int cap_bprm_secureexec(struct linux_binprm *bprm)
+static int is_secureexec(struct linux_binprm *bprm)
 {
-	const struct cred *cred = current_cred();
+	const struct cred *cred = bprm->cred;
 	kuid_t root_uid = make_kuid(cred->user_ns, 0);
 
 	if (!uid_eq(cred->uid, root_uid)) {
@@ -1079,7 +1084,6 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
 	LSM_HOOK_INIT(capget, cap_capget),
 	LSM_HOOK_INIT(capset, cap_capset),
 	LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
-	LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
 	LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
 	LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
 	LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2017-07-18 22:26 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-18 22:25 [PATCH v3 00/15] exec: Use sane stack rlimit under secureexec Kees Cook
2017-07-18 22:25 ` Kees Cook
2017-07-18 22:25 ` [PATCH v3 01/15] binfmt: Introduce secureexec flag Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  0:05   ` John Johansen
2017-07-19  0:05     ` John Johansen
2017-07-19  1:01   ` Andy Lutomirski
2017-07-19  1:01     ` Andy Lutomirski
2017-07-18 22:25 ` [PATCH v3 02/15] exec: Rename bprm->cred_prepared to called_set_creds Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  0:08   ` John Johansen
2017-07-19  0:08     ` John Johansen
2017-07-19  1:06   ` Andy Lutomirski
2017-07-19  1:06     ` Andy Lutomirski
2017-07-19  4:40     ` Kees Cook
2017-07-19  4:40       ` Kees Cook
2017-07-19  9:19   ` James Morris
2017-07-19  9:19     ` James Morris
2017-07-19 23:56   ` Paul Moore
2017-07-19 23:56     ` Paul Moore
2017-07-18 22:25 ` [PATCH v3 03/15] apparmor: Refactor to remove bprm_secureexec hook Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  0:00   ` John Johansen
2017-07-19  0:00     ` John Johansen
2017-07-19  9:21   ` James Morris
2017-07-19  9:21     ` James Morris
2017-07-18 22:25 ` [PATCH v3 04/15] selinux: " Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-20  0:03   ` Paul Moore
2017-07-20  0:03     ` Paul Moore
2017-07-20  0:19     ` Paul Moore
2017-07-20  0:19       ` Paul Moore
2017-07-20  1:37       ` Kees Cook
2017-07-20  1:37         ` Kees Cook
2017-07-20 13:42         ` Paul Moore
2017-07-20 13:42           ` Paul Moore
2017-07-20 17:06           ` Kees Cook
2017-07-20 17:06             ` Kees Cook
2017-07-20 20:42             ` Paul Moore
2017-07-20 20:42               ` Paul Moore
2017-07-21 15:40               ` Paul Moore
2017-07-21 15:40                 ` Paul Moore
2017-07-21 17:37                 ` Kees Cook
2017-07-21 17:37                   ` Kees Cook
2017-07-21 19:16                   ` Paul Moore
2017-07-21 19:16                     ` Paul Moore
2017-07-18 22:25 ` [PATCH v3 05/15] smack: " Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-26  3:58   ` Kees Cook
2017-07-26  3:58     ` Kees Cook
2017-07-26 15:24     ` Casey Schaufler
2017-07-26 15:24       ` Casey Schaufler
2017-07-18 22:25 ` Kees Cook [this message]
2017-07-18 22:25   ` [PATCH v3 06/15] commoncap: " Kees Cook
2017-07-19  1:10   ` Andy Lutomirski
2017-07-19  1:10     ` Andy Lutomirski
2017-07-19  4:41     ` Kees Cook
2017-07-19  4:41       ` Kees Cook
2017-07-20  4:53     ` Andy Lutomirski
2017-07-20  4:53       ` Andy Lutomirski
2017-07-31 22:43       ` Kees Cook
2017-07-31 22:43         ` Kees Cook
2017-08-01 13:12         ` Andy Lutomirski
2017-08-01 13:12           ` Andy Lutomirski
2017-07-19  9:26   ` James Morris
2017-07-19  9:26     ` James Morris
2017-07-18 22:25 ` [PATCH v3 07/15] commoncap: Move cap_elevated calculation into bprm_set_creds Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  1:52   ` Andy Lutomirski
2017-07-19  1:52     ` Andy Lutomirski
2017-07-19  9:28   ` James Morris
2017-07-19  9:28     ` James Morris
2017-07-18 22:25 ` [PATCH v3 08/15] LSM: drop bprm_secureexec hook Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  0:02   ` John Johansen
2017-07-19  0:02     ` John Johansen
2017-07-19  9:29   ` James Morris
2017-07-19  9:29     ` James Morris
2017-07-18 22:25 ` [PATCH v3 09/15] exec: Correct comments about "point of no return" Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  0:45   ` Eric W. Biederman
2017-07-19  0:45     ` Eric W. Biederman
2017-07-18 22:25 ` [PATCH v3 10/15] exec: Use secureexec for setting dumpability Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-26  3:59   ` Kees Cook
2017-07-26  3:59     ` Kees Cook
2017-07-18 22:25 ` [PATCH v3 11/15] exec: Use secureexec for clearing pdeath_signal Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-18 22:25 ` [PATCH v3 12/15] smack: Remove redundant pdeath_signal clearing Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-18 22:25 ` [PATCH v3 13/15] exec: Consolidate dumpability logic Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-18 22:25 ` [PATCH v3 14/15] exec: Use sane stack rlimit under secureexec Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-19  9:42   ` James Morris
2017-07-19  9:42     ` James Morris
2017-07-18 22:25 ` [PATCH v3 15/15] exec: Consolidate pdeath_signal clearing Kees Cook
2017-07-18 22:25   ` Kees Cook
2017-07-18 23:03 ` [PATCH v3 00/15] exec: Use sane stack rlimit under secureexec Linus Torvalds
2017-07-18 23:03   ` Linus Torvalds
2017-07-19  3:22 ` Serge E. Hallyn
2017-07-19  3:22   ` Serge E. Hallyn
2017-07-19  5:23   ` Kees Cook
2017-07-19  5:23     ` Kees Cook

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1500416736-49829-7-git-send-email-keescook@chromium.org \
    --to=keescook@chromium.org \
    --cc=akpm@linux-foundation.org \
    --cc=casey@schaufler-ca.com \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=james.l.morris@oracle.com \
    --cc=john.johansen@canonical.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    --cc=sds@tycho.nsa.gov \
    --cc=serge@hallyn.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.