linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] get/set_dumpable() cleanups and theoretical fix
       [not found]       ` <CAGXu5j+=LZYAczLVawGPAxd=9VX1FupWZq+2858GsrD1YprL3w@mail.gmail.com>
@ 2013-11-16 19:00         ` Oleg Nesterov
  2013-11-16 19:01           ` [PATCH 1/3] set_dumpable: fix the theoretical race with itself Oleg Nesterov
                             ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-16 19:00 UTC (permalink / raw)
  To: Kees Cook, Andrew Morton
  Cc: security, Eric W. Biederman, Vasily Kulikov, Petr Matousek,
	linux-kernel, linux-arch, Alex Kelly, Josh Triplett

On 11/15, Kees Cook wrote:
>
> On Fri, Nov 15, 2013 at 12:36 PM, Oleg Nesterov <oleg@redhat.com> wrote:
> >
> > unless I missed something, this is the fix, not cleanup ?
> >
> > If commit_creds()->set_dumpable(SUID_DUMP_ROOT) races with
> > sys_prctl()->set_dumpable(SUID_DUMP_DISABLE), we can get
> > SUID_DUMP_USER afaics.
> >
> > Yes, yes, even if I am right this race is very unlikely.
>
> Hm, yes, that is a fix then. I struggle to imagine it being
> exploitable (i.e. control over both threads, one at least already with
> a different cred, etc), but it certainly does look like a bug.

Yes, yes, sure, this is only theoretical.

OK, I am sending the patches to lkml. I didn't dare to keep your ack,
please review v2 (v1 confused bit-mask with bit-number, and in theory
we need ACCESS_ONCE).

It would be really nice if someone can ack the "it is safe to mix
bitops and cmpxchg" assumption mentioned in the changelog.


Alex, Josh, this also partly reverts 179899fd5dc780fe "coredump:
update coredump-related headers", I think fs/coredump.h buys nothing.

Oleg.

 fs/coredump.c         |    1 -
 fs/coredump.h         |    6 -----
 fs/exec.c             |   61 +++++--------------------------------------------
 include/linux/sched.h |   25 ++++++++++++++-----
 4 files changed, 24 insertions(+), 69 deletions(-)


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] set_dumpable: fix the theoretical race with itself
  2013-11-16 19:00         ` [PATCH 0/3] get/set_dumpable() cleanups and theoretical fix Oleg Nesterov
@ 2013-11-16 19:01           ` Oleg Nesterov
  2013-11-18 16:36             ` Kees Cook
  2013-11-16 19:01           ` [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY Oleg Nesterov
  2013-11-16 19:02           ` [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h Oleg Nesterov
  2 siblings, 1 reply; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-16 19:01 UTC (permalink / raw)
  To: Kees Cook, Andrew Morton
  Cc: security, Eric W. Biederman, Vasily Kulikov, Petr Matousek,
	linux-kernel, linux-arch, Alex Kelly, Josh Triplett

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>
---
 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



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY
  2013-11-16 19:00         ` [PATCH 0/3] get/set_dumpable() cleanups and theoretical fix Oleg Nesterov
  2013-11-16 19:01           ` [PATCH 1/3] set_dumpable: fix the theoretical race with itself Oleg Nesterov
@ 2013-11-16 19:01           ` Oleg Nesterov
  2013-11-18 18:38             ` Kees Cook
  2013-11-16 19:02           ` [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h Oleg Nesterov
  2 siblings, 1 reply; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-16 19:01 UTC (permalink / raw)
  To: Kees Cook, Andrew Morton
  Cc: security, Eric W. Biederman, Vasily Kulikov, Petr Matousek,
	linux-kernel, linux-arch, Alex Kelly, Josh Triplett

Nobody actually needs MMF_DUMPABLE/MMF_DUMP_SECURELY, there
are only used to enforce the encoding of SUID_DUMP_* enum in
mm->flags & MMF_DUMPABLE_MASK.

Now that set_dumpable() updates both bits atomically we can
kill them and simply store the value "as is" in 2 lower bits.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 fs/exec.c             |   18 +++---------------
 include/linux/sched.h |    4 +---
 2 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 613c9dc..5303005 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1620,8 +1620,7 @@ void set_binfmt(struct linux_binfmt *new)
 EXPORT_SYMBOL(set_binfmt);
 
 /*
- * set_dumpable converts traditional three-value dumpable to two flags and
- * stores them into mm->flags.
+ * set_dumpable stores three-value SUID_DUMP_* into mm->flags.
  */
 void set_dumpable(struct mm_struct *mm, int value)
 {
@@ -1629,24 +1628,13 @@ void set_dumpable(struct mm_struct *mm, int value)
 
 	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);
-		}
-
+		new = (old & ~MMF_DUMPABLE_MASK) | value;
 	} while (cmpxchg(&mm->flags, old, new) != old);
 }
 
 int __get_dumpable(unsigned long mm_flags)
 {
-	int ret;
-
-	ret = mm_flags & MMF_DUMPABLE_MASK;
-	return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
+	return mm_flags & MMF_DUMPABLE_MASK;
 }
 
 /*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 838a3d9..828c00d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -326,10 +326,8 @@ extern int get_dumpable(struct mm_struct *mm);
 #define SUID_DUMP_ROOT		2	/* Dump as root */
 
 /* mm flags */
-/* dumpable bits */
-#define MMF_DUMPABLE      0  /* core dump is permitted */
-#define MMF_DUMP_SECURELY 1  /* core file is readable only by root */
 
+/* for SUID_DUMP_* above */
 #define MMF_DUMPABLE_BITS 2
 #define MMF_DUMPABLE_MASK ((1 << MMF_DUMPABLE_BITS) - 1)
 
-- 
1.5.5.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h
  2013-11-16 19:00         ` [PATCH 0/3] get/set_dumpable() cleanups and theoretical fix Oleg Nesterov
  2013-11-16 19:01           ` [PATCH 1/3] set_dumpable: fix the theoretical race with itself Oleg Nesterov
  2013-11-16 19:01           ` [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY Oleg Nesterov
@ 2013-11-16 19:02           ` Oleg Nesterov
  2013-11-18 18:39             ` Kees Cook
  2 siblings, 1 reply; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-16 19:02 UTC (permalink / raw)
  To: Kees Cook, Andrew Morton
  Cc: security, Eric W. Biederman, Vasily Kulikov, Petr Matousek,
	linux-kernel, linux-arch, Alex Kelly, Josh Triplett

1. Remove fs/coredump.h. It is not clear why do we need it,
   it only declares __get_dumpable(), signal.c includes it
   for no reason.

2. Now that get_dumpable() and __get_dumpable() are really
   trivial make them inline in linux/sched.h.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 fs/coredump.c         |    1 -
 fs/coredump.h         |    6 ------
 fs/exec.c             |   18 ------------------
 include/linux/sched.h |   21 +++++++++++++++++----
 4 files changed, 17 insertions(+), 29 deletions(-)
 delete mode 100644 fs/coredump.h

diff --git a/fs/coredump.c b/fs/coredump.c
index 9bdeca1..4bc92c7 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -40,7 +40,6 @@
 
 #include <trace/events/task.h>
 #include "internal.h"
-#include "coredump.h"
 
 #include <trace/events/sched.h>
 
diff --git a/fs/coredump.h b/fs/coredump.h
deleted file mode 100644
index e39ff07..0000000
--- a/fs/coredump.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _FS_COREDUMP_H
-#define _FS_COREDUMP_H
-
-extern int __get_dumpable(unsigned long mm_flags);
-
-#endif
diff --git a/fs/exec.c b/fs/exec.c
index 5303005..2196ef5 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -62,7 +62,6 @@
 
 #include <trace/events/task.h>
 #include "internal.h"
-#include "coredump.h"
 
 #include <trace/events/sched.h>
 
@@ -1616,7 +1615,6 @@ void set_binfmt(struct linux_binfmt *new)
 	if (new)
 		__module_get(new->module);
 }
-
 EXPORT_SYMBOL(set_binfmt);
 
 /*
@@ -1632,22 +1630,6 @@ void set_dumpable(struct mm_struct *mm, int value)
 	} while (cmpxchg(&mm->flags, old, new) != old);
 }
 
-int __get_dumpable(unsigned long mm_flags)
-{
-	return mm_flags & MMF_DUMPABLE_MASK;
-}
-
-/*
- * This returns the actual value of the suid_dumpable flag. For things
- * that are using this for checking for privilege transitions, it must
- * test against SUID_DUMP_USER rather than treating it as a boolean
- * value.
- */
-int get_dumpable(struct mm_struct *mm)
-{
-	return __get_dumpable(mm->flags);
-}
-
 SYSCALL_DEFINE3(execve,
 		const char __user *, filename,
 		const char __user *const __user *, argv,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 828c00d..34c1903 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -317,10 +317,6 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 static inline void arch_pick_mmap_layout(struct mm_struct *mm) {}
 #endif
 
-
-extern void set_dumpable(struct mm_struct *mm, int value);
-extern int get_dumpable(struct mm_struct *mm);
-
 #define SUID_DUMP_DISABLE	0	/* No setuid dumping */
 #define SUID_DUMP_USER		1	/* Dump as user of process */
 #define SUID_DUMP_ROOT		2	/* Dump as root */
@@ -331,6 +327,23 @@ extern int get_dumpable(struct mm_struct *mm);
 #define MMF_DUMPABLE_BITS 2
 #define MMF_DUMPABLE_MASK ((1 << MMF_DUMPABLE_BITS) - 1)
 
+extern void set_dumpable(struct mm_struct *mm, int value);
+/*
+ * This returns the actual value of the suid_dumpable flag. For things
+ * that are using this for checking for privilege transitions, it must
+ * test against SUID_DUMP_USER rather than treating it as a boolean
+ * value.
+ */
+static inline int __get_dumpable(unsigned long mm_flags)
+{
+	return mm_flags & MMF_DUMPABLE_MASK;
+}
+
+static inline int get_dumpable(struct mm_struct *mm)
+{
+	return __get_dumpable(mm->flags);
+}
+
 /* coredump filter bits */
 #define MMF_DUMP_ANON_PRIVATE	2
 #define MMF_DUMP_ANON_SHARED	3
-- 
1.5.5.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] set_dumpable: fix the theoretical race with itself
  2013-11-16 19:01           ` [PATCH 1/3] set_dumpable: fix the theoretical race with itself Oleg Nesterov
@ 2013-11-18 16:36             ` Kees Cook
  0 siblings, 0 replies; 10+ messages in thread
From: Kees Cook @ 2013-11-18 16:36 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On Sat, Nov 16, 2013 at 11:01 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> 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>

I can't speak to the bitops/cmpxchg, but the rest looks fine to me.

Acked-by: Kees Cook <keescook@chromium.org>

Thanks!

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY
  2013-11-16 19:01           ` [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY Oleg Nesterov
@ 2013-11-18 18:38             ` Kees Cook
  2013-11-18 19:16               ` Oleg Nesterov
  0 siblings, 1 reply; 10+ messages in thread
From: Kees Cook @ 2013-11-18 18:38 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On Sat, Nov 16, 2013 at 11:01 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> Nobody actually needs MMF_DUMPABLE/MMF_DUMP_SECURELY, there
> are only used to enforce the encoding of SUID_DUMP_* enum in
> mm->flags & MMF_DUMPABLE_MASK.
>
> Now that set_dumpable() updates both bits atomically we can
> kill them and simply store the value "as is" in 2 lower bits.
>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> ---
>  fs/exec.c             |   18 +++---------------
>  include/linux/sched.h |    4 +---
>  2 files changed, 4 insertions(+), 18 deletions(-)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 613c9dc..5303005 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -1620,8 +1620,7 @@ void set_binfmt(struct linux_binfmt *new)
>  EXPORT_SYMBOL(set_binfmt);
>
>  /*
> - * set_dumpable converts traditional three-value dumpable to two flags and
> - * stores them into mm->flags.
> + * set_dumpable stores three-value SUID_DUMP_* into mm->flags.
>   */
>  void set_dumpable(struct mm_struct *mm, int value)
>  {
> @@ -1629,24 +1628,13 @@ void set_dumpable(struct mm_struct *mm, int value)
>
>         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);
> -               }
> -
> +               new = (old & ~MMF_DUMPABLE_MASK) | value;

Just to make this safe against insane callers, perhaps mask the value as well?

    new = (old & ~MMF_DUMPABLE_MASK) | (value & MMF_DUMPABLE_MASK);

>         } while (cmpxchg(&mm->flags, old, new) != old);
>  }
>
>  int __get_dumpable(unsigned long mm_flags)
>  {
> -       int ret;
> -
> -       ret = mm_flags & MMF_DUMPABLE_MASK;
> -       return (ret > SUID_DUMP_USER) ? SUID_DUMP_ROOT : ret;
> +       return mm_flags & MMF_DUMPABLE_MASK;
>  }
>
>  /*
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 838a3d9..828c00d 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -326,10 +326,8 @@ extern int get_dumpable(struct mm_struct *mm);
>  #define SUID_DUMP_ROOT         2       /* Dump as root */
>
>  /* mm flags */
> -/* dumpable bits */
> -#define MMF_DUMPABLE      0  /* core dump is permitted */
> -#define MMF_DUMP_SECURELY 1  /* core file is readable only by root */
>
> +/* for SUID_DUMP_* above */
>  #define MMF_DUMPABLE_BITS 2
>  #define MMF_DUMPABLE_MASK ((1 << MMF_DUMPABLE_BITS) - 1)

Besides that, looks great.

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h
  2013-11-16 19:02           ` [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h Oleg Nesterov
@ 2013-11-18 18:39             ` Kees Cook
  0 siblings, 0 replies; 10+ messages in thread
From: Kees Cook @ 2013-11-18 18:39 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On Sat, Nov 16, 2013 at 11:02 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> 1. Remove fs/coredump.h. It is not clear why do we need it,
>    it only declares __get_dumpable(), signal.c includes it
>    for no reason.
>
> 2. Now that get_dumpable() and __get_dumpable() are really
>    trivial make them inline in linux/sched.h.
>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>

Acked-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY
  2013-11-18 18:38             ` Kees Cook
@ 2013-11-18 19:16               ` Oleg Nesterov
  2013-11-18 19:27                 ` Kees Cook
  0 siblings, 1 reply; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-18 19:16 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On 11/18, Kees Cook wrote:
>
> On Sat, Nov 16, 2013 at 11:01 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> > @@ -1629,24 +1628,13 @@ void set_dumpable(struct mm_struct *mm, int value)
> >
> >         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);
> > -               }
> > -
> > +               new = (old & ~MMF_DUMPABLE_MASK) | value;
>
> Just to make this safe against insane callers, perhaps mask the value as well?

Well yes, before this patch set_dumpable() silently ignored the wrong
value, perhaps you are right but see below.

>     new = (old & ~MMF_DUMPABLE_MASK) | (value & MMF_DUMPABLE_MASK);
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^

this doesn't really help, with this patch "mm->flags & MMF_DUMPABLE_MASK"
has a room for yet another SUID_DUMP == 4 we do not have yet.

And I don't really like the "silently ignore" logic, so perhaps

		if (WARN_ON(value > SUID_DUMP_ROOT))
			return;

at the start makes more sense?

Or perhaps we do not really need the additional check? suid_dumpable
is always sane, other callers can't use the wrong value.

But I am fine either way, please tell me what do you prefer.

Oleg.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY
  2013-11-18 19:16               ` Oleg Nesterov
@ 2013-11-18 19:27                 ` Kees Cook
  2013-11-18 19:37                   ` Oleg Nesterov
  0 siblings, 1 reply; 10+ messages in thread
From: Kees Cook @ 2013-11-18 19:27 UTC (permalink / raw)
  To: Oleg Nesterov
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On Mon, Nov 18, 2013 at 11:16 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> On 11/18, Kees Cook wrote:
>>
>> On Sat, Nov 16, 2013 at 11:01 AM, Oleg Nesterov <oleg@redhat.com> wrote:
>> > @@ -1629,24 +1628,13 @@ void set_dumpable(struct mm_struct *mm, int value)
>> >
>> >         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);
>> > -               }
>> > -
>> > +               new = (old & ~MMF_DUMPABLE_MASK) | value;
>>
>> Just to make this safe against insane callers, perhaps mask the value as well?
>
> Well yes, before this patch set_dumpable() silently ignored the wrong
> value, perhaps you are right but see below.
>
>>     new = (old & ~MMF_DUMPABLE_MASK) | (value & MMF_DUMPABLE_MASK);
>                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> this doesn't really help, with this patch "mm->flags & MMF_DUMPABLE_MASK"
> has a room for yet another SUID_DUMP == 4 we do not have yet.
>
> And I don't really like the "silently ignore" logic, so perhaps
>
>                 if (WARN_ON(value > SUID_DUMP_ROOT))
>                         return;

Ah, good point about == 4. Yeah, I like the WARN_ON. No reason not to
be defensive as long as this code is getting changed.

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY
  2013-11-18 19:27                 ` Kees Cook
@ 2013-11-18 19:37                   ` Oleg Nesterov
  0 siblings, 0 replies; 10+ messages in thread
From: Oleg Nesterov @ 2013-11-18 19:37 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, security, Eric W. Biederman, Vasily Kulikov,
	Petr Matousek, LKML, linux-arch, Alex Kelly, Josh Triplett

On 11/18, Kees Cook wrote:
>
> On Mon, Nov 18, 2013 at 11:16 AM, Oleg Nesterov <oleg@redhat.com> wrote:
> >
> > And I don't really like the "silently ignore" logic, so perhaps
> >
> >                 if (WARN_ON(value > SUID_DUMP_ROOT))
> >                         return;
>
> Ah, good point about == 4. Yeah, I like the WARN_ON. No reason not to
> be defensive as long as this code is getting changed.

OK. I'll send v2 tomorrow.


And I just noticed I forgot to remove security@kernel.org, sorry for
unnecessary noise.

Oleg.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-11-18 19:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20131101232521.GA23119@www.outflux.net>
     [not found] ` <20131114170337.GA11068@redhat.com>
     [not found]   ` <CAGXu5jLXpLqjCAMFwKp7t7GpMq4+WBqNzSFC=up+CBvgGDuFCw@mail.gmail.com>
     [not found]     ` <20131115203652.GA13476@redhat.com>
     [not found]       ` <CAGXu5j+=LZYAczLVawGPAxd=9VX1FupWZq+2858GsrD1YprL3w@mail.gmail.com>
2013-11-16 19:00         ` [PATCH 0/3] get/set_dumpable() cleanups and theoretical fix Oleg Nesterov
2013-11-16 19:01           ` [PATCH 1/3] set_dumpable: fix the theoretical race with itself Oleg Nesterov
2013-11-18 16:36             ` Kees Cook
2013-11-16 19:01           ` [PATCH 2/3] kill MMF_DUMPABLE and MMF_DUMP_SECURELY Oleg Nesterov
2013-11-18 18:38             ` Kees Cook
2013-11-18 19:16               ` Oleg Nesterov
2013-11-18 19:27                 ` Kees Cook
2013-11-18 19:37                   ` Oleg Nesterov
2013-11-16 19:02           ` [PATCH 3/3] make __get_dumpable/get_dumpable inline, kill fs/coredump.h Oleg Nesterov
2013-11-18 18:39             ` Kees Cook

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).