All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Jann Horn <jann@thejh.net>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 3.19 27/27] fs: take i_mutex during prepare_binprm for set[ug]id executables
Date: Sun, 26 Apr 2015 16:15:58 +0200	[thread overview]
Message-ID: <20150426134604.515778736@linuxfoundation.org> (raw)
In-Reply-To: <20150426134603.371719585@linuxfoundation.org>

3.19-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jann Horn <jann@thejh.net>

commit 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 upstream.

This prevents a race between chown() and execve(), where chowning a
setuid-user binary to root would momentarily make the binary setuid
root.

This patch was mostly written by Linus Torvalds.

Signed-off-by: Jann Horn <jann@thejh.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/exec.c |   76 +++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 48 insertions(+), 28 deletions(-)

--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1259,6 +1259,53 @@ static void check_unsafe_exec(struct lin
 	spin_unlock(&p->fs->lock);
 }
 
+static void bprm_fill_uid(struct linux_binprm *bprm)
+{
+	struct inode *inode;
+	unsigned int mode;
+	kuid_t uid;
+	kgid_t gid;
+
+	/* clear any previous set[ug]id data from a previous binary */
+	bprm->cred->euid = current_euid();
+	bprm->cred->egid = current_egid();
+
+	if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+		return;
+
+	if (task_no_new_privs(current))
+		return;
+
+	inode = file_inode(bprm->file);
+	mode = READ_ONCE(inode->i_mode);
+	if (!(mode & (S_ISUID|S_ISGID)))
+		return;
+
+	/* Be careful if suid/sgid is set */
+	mutex_lock(&inode->i_mutex);
+
+	/* reload atomically mode/uid/gid now that lock held */
+	mode = inode->i_mode;
+	uid = inode->i_uid;
+	gid = inode->i_gid;
+	mutex_unlock(&inode->i_mutex);
+
+	/* We ignore suid/sgid if there are no mappings for them in the ns */
+	if (!kuid_has_mapping(bprm->cred->user_ns, uid) ||
+		 !kgid_has_mapping(bprm->cred->user_ns, gid))
+		return;
+
+	if (mode & S_ISUID) {
+		bprm->per_clear |= PER_CLEAR_ON_SETID;
+		bprm->cred->euid = uid;
+	}
+
+	if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+		bprm->per_clear |= PER_CLEAR_ON_SETID;
+		bprm->cred->egid = gid;
+	}
+}
+
 /*
  * Fill the binprm structure from the inode.
  * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
@@ -1267,36 +1314,9 @@ static void check_unsafe_exec(struct lin
  */
 int prepare_binprm(struct linux_binprm *bprm)
 {
-	struct inode *inode = file_inode(bprm->file);
-	umode_t mode = inode->i_mode;
 	int retval;
 
-
-	/* clear any previous set[ug]id data from a previous binary */
-	bprm->cred->euid = current_euid();
-	bprm->cred->egid = current_egid();
-
-	if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) &&
-	    !task_no_new_privs(current) &&
-	    kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) &&
-	    kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) {
-		/* Set-uid? */
-		if (mode & S_ISUID) {
-			bprm->per_clear |= PER_CLEAR_ON_SETID;
-			bprm->cred->euid = inode->i_uid;
-		}
-
-		/* Set-gid? */
-		/*
-		 * If setgid is set but no group execute bit then this
-		 * is a candidate for mandatory locking, not a setgid
-		 * executable.
-		 */
-		if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
-			bprm->per_clear |= PER_CLEAR_ON_SETID;
-			bprm->cred->egid = inode->i_gid;
-		}
-	}
+	bprm_fill_uid(bprm);
 
 	/* fill in binprm security blob */
 	retval = security_bprm_set_creds(bprm);



  parent reply	other threads:[~2015-04-26 14:17 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-26 14:15 [PATCH 3.19 00/27] 3.19.6-stable review Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 01/27] tcp: prevent fetching dst twice in early demux code Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 02/27] rocker: handle non-bridge master change Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 03/27] net/mlx4_en: Call register_netdevice in the proper location Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 04/27] ipv6: Dont reduce hop limit for an interface Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 05/27] tun: return proper error code from tun_do_read Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 06/27] net: tcp6: fix double call of tcp_v6_fill_cb() Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 07/27] bonding: Bonding Overriding Configuration logic restored Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 08/27] openvswitch: Return vport module ref before destruction Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 09/27] xen-netfront: transmit fully GSO-sized packets Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 10/27] tcp: fix FRTO undo on cumulative ACK of SACKed range Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 11/27] ipv6: protect skb->sk accesses from recursive dereference inside the stack Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 12/27] net/mlx4_core: Fix error message deprecation for ConnectX-2 cards Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 13/27] tcp: tcp_make_synack() should clear skb->tstamp Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 14/27] bnx2x: Fix busy_poll vs netpoll Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 15/27] bpf: fix verifier memory corruption Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 16/27] Revert "net: Reset secmark when scrubbing packet" Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 18/27] udptunnels: Call handle_offloads after inserting vlan tag Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 21/27] tg3: Hold tp->lock before calling tg3_halt() from tg3_init_one() Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 23/27] staging: comedi: adv_pci1710: fix AI INSN_READ for non-zero channel Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 24/27] mm/hugetlb: reduce arch dependent code around follow_huge_* Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 25/27] mm/hugetlb: take page table lock in follow_huge_pmd() Greg Kroah-Hartman
2015-04-26 14:15 ` [PATCH 3.19 26/27] rtlwifi: rtl8192ee: Fix handling of new style descriptors Greg Kroah-Hartman
2015-04-26 14:15 ` Greg Kroah-Hartman [this message]
2015-04-26 20:04 ` [PATCH 3.19 00/27] 3.19.6-stable review Guenter Roeck
2015-04-27 17:20 ` Shuah Khan

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=20150426134604.515778736@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jann@thejh.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --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.