From: Oleg Nesterov <oleg@redhat.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Alex Kelly <alex.page.kelly@gmail.com>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Josh Triplett <josh@joshtriplett.org>,
Kees Cook <keescook@chromium.org>,
Petr Matousek <pmatouse@redhat.com>,
Vasily Kulikov <segoon@openwall.com>,
linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 1/3] set_dumpable: fix the theoretical race with itself
Date: Tue, 19 Nov 2013 15:43:15 +0100 [thread overview]
Message-ID: <20131119144315.GA28862@redhat.com> (raw)
In-Reply-To: <20131119144300.GA28842@redhat.com>
set_dumpable() updates MMF_DUMPABLE_MASK in a non-trivial way to
ensure that get_dumpable() can't observe the intermediate state,
but this all can't help if multiple threads call set_dumpable()
at the same time.
And in theory commit_creds()->set_dumpable(SUID_DUMP_ROOT) racing
with sys_prctl()->set_dumpable(SUID_DUMP_DISABLE) can result in
SUID_DUMP_USER.
Change this code to update both bits atomically via cmpxchg().
Note: this assumes that it is safe to mix bitops and cmpxchg. IOW,
if, say, an architecture implements cmpxchg() using the locking
(like arch/parisc/lib/bitops.c does), then it should use the same
locks for set_bit/etc.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
---
fs/exec.c | 49 +++++++++++++++----------------------------------
1 files changed, 15 insertions(+), 34 deletions(-)
diff --git a/fs/exec.c b/fs/exec.c
index bb8afc1..613c9dc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1621,43 +1621,24 @@ EXPORT_SYMBOL(set_binfmt);
/*
* set_dumpable converts traditional three-value dumpable to two flags and
- * stores them into mm->flags. It modifies lower two bits of mm->flags, but
- * these bits are not changed atomically. So get_dumpable can observe the
- * intermediate state. To avoid doing unexpected behavior, get get_dumpable
- * return either old dumpable or new one by paying attention to the order of
- * modifying the bits.
- *
- * dumpable | mm->flags (binary)
- * old new | initial interim final
- * ---------+-----------------------
- * 0 1 | 00 01 01
- * 0 2 | 00 10(*) 11
- * 1 0 | 01 00 00
- * 1 2 | 01 11 11
- * 2 0 | 11 10(*) 00
- * 2 1 | 11 11 01
- *
- * (*) get_dumpable regards interim value of 10 as 11.
+ * stores them into mm->flags.
*/
void set_dumpable(struct mm_struct *mm, int value)
{
- switch (value) {
- case SUID_DUMP_DISABLE:
- clear_bit(MMF_DUMPABLE, &mm->flags);
- smp_wmb();
- clear_bit(MMF_DUMP_SECURELY, &mm->flags);
- break;
- case SUID_DUMP_USER:
- set_bit(MMF_DUMPABLE, &mm->flags);
- smp_wmb();
- clear_bit(MMF_DUMP_SECURELY, &mm->flags);
- break;
- case SUID_DUMP_ROOT:
- set_bit(MMF_DUMP_SECURELY, &mm->flags);
- smp_wmb();
- set_bit(MMF_DUMPABLE, &mm->flags);
- break;
- }
+ unsigned long old, new;
+
+ do {
+ old = ACCESS_ONCE(mm->flags);
+ new = old & ~MMF_DUMPABLE_MASK;
+
+ switch (value) {
+ case SUID_DUMP_ROOT:
+ new |= (1 << MMF_DUMP_SECURELY);
+ case SUID_DUMP_USER:
+ new |= (1<< MMF_DUMPABLE);
+ }
+
+ } while (cmpxchg(&mm->flags, old, new) != old);
}
int __get_dumpable(unsigned long mm_flags)
--
1.5.5.1
next prev parent reply other threads:[~2013-11-19 14:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-19 14:43 [PATCH v2 0/3] get/set_dumpable() cleanups and theoretical fix Oleg Nesterov
2013-11-19 14:43 ` Oleg Nesterov [this message]
2013-11-19 22:20 ` [PATCH v2 1/3] set_dumpable: fix the theoretical race with itself Andrew Morton
2013-11-19 14:43 ` [PATCH v2 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY Oleg Nesterov
2013-11-19 14:43 ` [PATCH v2 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h Oleg Nesterov
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=20131119144315.GA28862@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=alex.page.kelly@gmail.com \
--cc=ebiederm@xmission.com \
--cc=josh@joshtriplett.org \
--cc=keescook@chromium.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pmatouse@redhat.com \
--cc=segoon@openwall.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).