From ae837eff0dcf4ed79bb39ac5017e5337f77fffdb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Jun 2014 16:25:55 -0700 Subject: [PATCH] 3.10-stable patches added patches: futex-add-another-early-deadlock-detection-check.patch futex-prevent-attaching-to-kernel-threads.patch --- ...other-early-deadlock-detection-check.patch | 163 ++++++++++++++++++ ...-prevent-attaching-to-kernel-threads.patch | 55 ++++++ queue-3.10/series | 2 + queue-3.14/series | 2 + 4 files changed, 222 insertions(+) create mode 100644 queue-3.10/futex-add-another-early-deadlock-detection-check.patch create mode 100644 queue-3.10/futex-prevent-attaching-to-kernel-threads.patch create mode 100644 queue-3.10/series create mode 100644 queue-3.14/series diff --git a/queue-3.10/futex-add-another-early-deadlock-detection-check.patch b/queue-3.10/futex-add-another-early-deadlock-detection-check.patch new file mode 100644 index 00000000000..88c9d5f2ead --- /dev/null +++ b/queue-3.10/futex-add-another-early-deadlock-detection-check.patch @@ -0,0 +1,163 @@ +From 866293ee54227584ffcb4a42f69c1f365974ba7f Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 12 May 2014 20:45:34 +0000 +Subject: futex: Add another early deadlock detection check + +From: Thomas Gleixner + +commit 866293ee54227584ffcb4a42f69c1f365974ba7f upstream. + +Dave Jones trinity syscall fuzzer exposed an issue in the deadlock +detection code of rtmutex: + http://lkml.kernel.org/r/20140429151655.GA14277@redhat.com + +That underlying issue has been fixed with a patch to the rtmutex code, +but the futex code must not call into rtmutex in that case because + - it can detect that issue early + - it avoids a different and more complex fixup for backing out + +If the user space variable got manipulated to 0x80000000 which means +no lock holder, but the waiters bit set and an active pi_state in the +kernel is found we can figure out the recursive locking issue by +looking at the pi_state owner. If that is the current task, then we +can safely return -EDEADLK. + +The check should have been added in commit 59fa62451 (futex: Handle +futex_pi OWNER_DIED take over correctly) already, but I did not see +the above issue caused by user space manipulation back then. + +Signed-off-by: Thomas Gleixner +Cc: Dave Jones +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Darren Hart +Cc: Davidlohr Bueso +Cc: Steven Rostedt +Cc: Clark Williams +Cc: Paul McKenney +Cc: Lai Jiangshan +Cc: Roland McGrath +Cc: Carlos ODonell +Cc: Jakub Jelinek +Cc: Michael Kerrisk +Cc: Sebastian Andrzej Siewior +Link: http://lkml.kernel.org/r/20140512201701.097349971@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 47 ++++++++++++++++++++++++++++++++++------------- + 1 file changed, 34 insertions(+), 13 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -594,7 +594,8 @@ void exit_pi_state_list(struct task_stru + + static int + lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, +- union futex_key *key, struct futex_pi_state **ps) ++ union futex_key *key, struct futex_pi_state **ps, ++ struct task_struct *task) + { + struct futex_pi_state *pi_state = NULL; + struct futex_q *this, *next; +@@ -638,6 +639,16 @@ lookup_pi_state(u32 uval, struct futex_h + return -EINVAL; + } + ++ /* ++ * Protect against a corrupted uval. If uval ++ * is 0x80000000 then pid is 0 and the waiter ++ * bit is set. So the deadlock check in the ++ * calling code has failed and we did not fall ++ * into the check above due to !pid. ++ */ ++ if (task && pi_state->owner == task) ++ return -EDEADLK; ++ + atomic_inc(&pi_state->refcount); + *ps = pi_state; + +@@ -787,7 +798,7 @@ retry: + * We dont have the lock. Look up the PI state (or create it if + * we are the first waiter): + */ +- ret = lookup_pi_state(uval, hb, key, ps); ++ ret = lookup_pi_state(uval, hb, key, ps, task); + + if (unlikely(ret)) { + switch (ret) { +@@ -1197,7 +1208,7 @@ void requeue_pi_wake_futex(struct futex_ + * + * Return: + * 0 - failed to acquire the lock atomically; +- * 1 - acquired the lock; ++ * >0 - acquired the lock, return value is vpid of the top_waiter + * <0 - error + */ + static int futex_proxy_trylock_atomic(u32 __user *pifutex, +@@ -1208,7 +1219,7 @@ static int futex_proxy_trylock_atomic(u3 + { + struct futex_q *top_waiter = NULL; + u32 curval; +- int ret; ++ int ret, vpid; + + if (get_futex_value_locked(&curval, pifutex)) + return -EFAULT; +@@ -1236,11 +1247,13 @@ static int futex_proxy_trylock_atomic(u3 + * the contended case or if set_waiters is 1. The pi_state is returned + * in ps in contended cases. + */ ++ vpid = task_pid_vnr(top_waiter->task); + ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task, + set_waiters); +- if (ret == 1) ++ if (ret == 1) { + requeue_pi_wake_futex(top_waiter, key2, hb2); +- ++ return vpid; ++ } + return ret; + } + +@@ -1272,7 +1285,6 @@ static int futex_requeue(u32 __user *uad + struct futex_hash_bucket *hb1, *hb2; + struct plist_head *head1; + struct futex_q *this, *next; +- u32 curval2; + + if (requeue_pi) { + /* +@@ -1358,16 +1370,25 @@ retry_private: + * At this point the top_waiter has either taken uaddr2 or is + * waiting on it. If the former, then the pi_state will not + * exist yet, look it up one more time to ensure we have a +- * reference to it. ++ * reference to it. If the lock was taken, ret contains the ++ * vpid of the top waiter task. + */ +- if (ret == 1) { ++ if (ret > 0) { + WARN_ON(pi_state); + drop_count++; + task_count++; +- ret = get_futex_value_locked(&curval2, uaddr2); +- if (!ret) +- ret = lookup_pi_state(curval2, hb2, &key2, +- &pi_state); ++ /* ++ * If we acquired the lock, then the user ++ * space value of uaddr2 should be vpid. It ++ * cannot be changed by the top waiter as it ++ * is blocked on hb2 lock if it tries to do ++ * so. If something fiddled with it behind our ++ * back the pi state lookup might unearth ++ * it. So we rather use the known value than ++ * rereading and handing potential crap to ++ * lookup_pi_state. ++ */ ++ ret = lookup_pi_state(ret, hb2, &key2, &pi_state, NULL); + } + + switch (ret) { diff --git a/queue-3.10/futex-prevent-attaching-to-kernel-threads.patch b/queue-3.10/futex-prevent-attaching-to-kernel-threads.patch new file mode 100644 index 00000000000..313a13ee844 --- /dev/null +++ b/queue-3.10/futex-prevent-attaching-to-kernel-threads.patch @@ -0,0 +1,55 @@ +From f0d71b3dcb8332f7971b5f2363632573e6d9486a Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Mon, 12 May 2014 20:45:35 +0000 +Subject: futex: Prevent attaching to kernel threads + +From: Thomas Gleixner + +commit f0d71b3dcb8332f7971b5f2363632573e6d9486a upstream. + +We happily allow userspace to declare a random kernel thread to be the +owner of a user space PI futex. + +Found while analysing the fallout of Dave Jones syscall fuzzer. + +We also should validate the thread group for private futexes and find +some fast way to validate whether the "alleged" owner has RW access on +the file which backs the SHM, but that's a separate issue. + +Signed-off-by: Thomas Gleixner +Cc: Dave Jones +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Darren Hart +Cc: Davidlohr Bueso +Cc: Steven Rostedt +Cc: Clark Williams +Cc: Paul McKenney +Cc: Lai Jiangshan +Cc: Roland McGrath +Cc: Carlos ODonell +Cc: Jakub Jelinek +Cc: Michael Kerrisk +Cc: Sebastian Andrzej Siewior +Link: http://lkml.kernel.org/r/20140512201701.194824402@linutronix.de +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/futex.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -666,6 +666,11 @@ lookup_pi_state(u32 uval, struct futex_h + if (!p) + return -ESRCH; + ++ if (!p->mm) { ++ put_task_struct(p); ++ return -EPERM; ++ } ++ + /* + * We need to look at the task state flags to figure out, + * whether the task is exiting. To protect against the do_exit diff --git a/queue-3.10/series b/queue-3.10/series new file mode 100644 index 00000000000..02f44cbbab6 --- /dev/null +++ b/queue-3.10/series @@ -0,0 +1,2 @@ +futex-add-another-early-deadlock-detection-check.patch +futex-prevent-attaching-to-kernel-threads.patch diff --git a/queue-3.14/series b/queue-3.14/series new file mode 100644 index 00000000000..02f44cbbab6 --- /dev/null +++ b/queue-3.14/series @@ -0,0 +1,2 @@ +futex-add-another-early-deadlock-detection-check.patch +futex-prevent-attaching-to-kernel-threads.patch -- 2.47.3