From: Greg Kroah-Hartman Date: Mon, 2 Jun 2014 23:26:03 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.14.6~100 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ecc34f416be244b3938a8c0a15525976e3a2fb63;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches 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 --- 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 index 00000000000..75f67dad533 --- /dev/null +++ b/queue-3.14/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 +@@ -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 index 00000000000..5674cb10913 --- /dev/null +++ b/queue-3.14/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 +@@ -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 index 00000000000..f431cc0c285 --- /dev/null +++ b/queue-3.14/mips-loongson2_cpufreq-fix-cpu-clock-rate-setting.patch @@ -0,0 +1,75 @@ +From 8e8acb32960f42c81b1d50deac56a2c07bb6a18a Mon Sep 17 00:00:00 2001 +From: Aaro Koskinen +Date: Thu, 3 Apr 2014 22:24:01 +0300 +Subject: MIPS/loongson2_cpufreq: Fix CPU clock rate setting + +From: Aaro Koskinen + +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 +Cc: Rafael J. Wysocki +Cc: Viresh Kumar +Cc: linux-mips@linux-mips.org +Cc: linux-kernel@vger.kernel.org +Cc: cpufreq@vger.kernel.org +Cc: Aaro Koskinen +Patchwork: https://patchwork.linux-mips.org/patch/6678/ +Signed-off-by: Ralf Baechle +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.14/series b/queue-3.14/series index 02f44cbbab6..556d9792c37 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -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