]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Jun 2014 23:26:03 +0000 (16:26 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Jun 2014 23:26:03 +0000 (16:26 -0700)
added patches:
futex-add-another-early-deadlock-detection-check.patch
futex-prevent-attaching-to-kernel-threads.patch
mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch

queue-3.14/futex-add-another-early-deadlock-detection-check.patch [new file with mode: 0644]
queue-3.14/futex-prevent-attaching-to-kernel-threads.patch [new file with mode: 0644]
queue-3.14/mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch [new file with mode: 0644]
queue-3.14/series

diff --git a/queue-3.14/futex-add-another-early-deadlock-detection-check.patch b/queue-3.14/futex-add-another-early-deadlock-detection-check.patch
new file mode 100644 (file)
index 0000000..75f67da
--- /dev/null
@@ -0,0 +1,163 @@
+From 866293ee54227584ffcb4a42f69c1f365974ba7f Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Mon, 12 May 2014 20:45:34 +0000
+Subject: futex: Add another early deadlock detection check
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+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 <tglx@linutronix.de>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Darren Hart <darren@dvhart.com>
+Cc: Davidlohr Bueso <davidlohr@hp.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Clark Williams <williams@redhat.com>
+Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
+Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
+Cc: Roland McGrath <roland@hack.frob.com>
+Cc: Carlos ODonell <carlos@redhat.com>
+Cc: Jakub Jelinek <jakub@redhat.com>
+Cc: Michael Kerrisk <mtk.manpages@gmail.com>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: http://lkml.kernel.org/r/20140512201701.097349971@linutronix.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/futex.c |   47 ++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 34 insertions(+), 13 deletions(-)
+
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -731,7 +731,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;
+@@ -772,6 +773,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;
+@@ -921,7 +932,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) {
+@@ -1333,7 +1344,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,
+@@ -1344,7 +1355,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;
+@@ -1372,11 +1383,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;
+ }
+@@ -1407,7 +1420,6 @@ static int futex_requeue(u32 __user *uad
+       struct futex_pi_state *pi_state = NULL;
+       struct futex_hash_bucket *hb1, *hb2;
+       struct futex_q *this, *next;
+-      u32 curval2;
+       if (requeue_pi) {
+               /*
+@@ -1495,16 +1507,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.14/futex-prevent-attaching-to-kernel-threads.patch b/queue-3.14/futex-prevent-attaching-to-kernel-threads.patch
new file mode 100644 (file)
index 0000000..5674cb1
--- /dev/null
@@ -0,0 +1,55 @@
+From f0d71b3dcb8332f7971b5f2363632573e6d9486a Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Mon, 12 May 2014 20:45:35 +0000
+Subject: futex: Prevent attaching to kernel threads
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+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 <tglx@linutronix.de>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Darren Hart <darren@dvhart.com>
+Cc: Davidlohr Bueso <davidlohr@hp.com>
+Cc: Steven Rostedt <rostedt@goodmis.org>
+Cc: Clark Williams <williams@redhat.com>
+Cc: Paul McKenney <paulmck@linux.vnet.ibm.com>
+Cc: Lai Jiangshan <laijs@cn.fujitsu.com>
+Cc: Roland McGrath <roland@hack.frob.com>
+Cc: Carlos ODonell <carlos@redhat.com>
+Cc: Jakub Jelinek <jakub@redhat.com>
+Cc: Michael Kerrisk <mtk.manpages@gmail.com>
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: http://lkml.kernel.org/r/20140512201701.194824402@linutronix.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/futex.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -800,6 +800,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.14/mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch b/queue-3.14/mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch
new file mode 100644 (file)
index 0000000..f431cc0
--- /dev/null
@@ -0,0 +1,75 @@
+From 8e8acb32960f42c81b1d50deac56a2c07bb6a18a Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Thu, 3 Apr 2014 22:24:01 +0300
+Subject: MIPS/loongson2_cpufreq: Fix CPU clock rate setting
+
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+
+commit 8e8acb32960f42c81b1d50deac56a2c07bb6a18a upstream.
+
+Loongson2 has been using (incorrectly) kHz for cpu_clk rate. This has
+been unnoticed, as loongson2_cpufreq was the only place where the rate
+was set/get. After commit 652ed95d5fa6074b3c4ea245deb0691f1acb6656
+(cpufreq: introduce cpufreq_generic_get() routine) things however broke,
+and now loops_per_jiffy adjustments are incorrect (1000 times too long).
+The patch fixes this by changing cpu_clk rate to Hz.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
+Cc: Viresh Kumar <viresh.kumar@linaro.org>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Cc: cpufreq@vger.kernel.org
+Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
+Patchwork: https://patchwork.linux-mips.org/patch/6678/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/loongson/lemote-2f/clock.c |    5 +++--
+ drivers/cpufreq/loongson2_cpufreq.c  |    4 ++--
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/loongson/lemote-2f/clock.c
++++ b/arch/mips/loongson/lemote-2f/clock.c
+@@ -91,6 +91,7 @@ EXPORT_SYMBOL(clk_put);
+ int clk_set_rate(struct clk *clk, unsigned long rate)
+ {
++      unsigned int rate_khz = rate / 1000;
+       int ret = 0;
+       int regval;
+       int i;
+@@ -111,10 +112,10 @@ int clk_set_rate(struct clk *clk, unsign
+               if (loongson2_clockmod_table[i].frequency ==
+                   CPUFREQ_ENTRY_INVALID)
+                       continue;
+-              if (rate == loongson2_clockmod_table[i].frequency)
++              if (rate_khz == loongson2_clockmod_table[i].frequency)
+                       break;
+       }
+-      if (rate != loongson2_clockmod_table[i].frequency)
++      if (rate_khz != loongson2_clockmod_table[i].frequency)
+               return -ENOTSUPP;
+       clk->rate = rate;
+--- a/drivers/cpufreq/loongson2_cpufreq.c
++++ b/drivers/cpufreq/loongson2_cpufreq.c
+@@ -62,7 +62,7 @@ static int loongson2_cpufreq_target(stru
+       set_cpus_allowed_ptr(current, &cpus_allowed);
+       /* setting the cpu frequency */
+-      clk_set_rate(policy->clk, freq);
++      clk_set_rate(policy->clk, freq * 1000);
+       return 0;
+ }
+@@ -92,7 +92,7 @@ static int loongson2_cpufreq_cpu_init(st
+            i++)
+               loongson2_clockmod_table[i].frequency = (rate * i) / 8;
+-      ret = clk_set_rate(cpuclk, rate);
++      ret = clk_set_rate(cpuclk, rate * 1000);
+       if (ret) {
+               clk_put(cpuclk);
+               return ret;
index 02f44cbbab6d67fcdefc01d1482aaedf22040542..556d9792c37edeacd4c1dd4573e130bee2bed256 100644 (file)
@@ -1,2 +1,3 @@
 futex-add-another-early-deadlock-detection-check.patch
 futex-prevent-attaching-to-kernel-threads.patch
+mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch