summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch138
1 files changed, 138 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch
new file mode 100644
index 000000000..d6b60749d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0009-futex-Simplify-fixup_pi_state_owner.patch
@@ -0,0 +1,138 @@
+From 55ea172ce3ebe276e734352eb1b236b3065496c3 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 19 Jan 2021 16:26:38 +0100
+Subject: [PATCH] futex: Simplify fixup_pi_state_owner()
+
+commit f2dac39d93987f7de1e20b3988c8685523247ae2 upstream
+
+Too many gotos already and an upcoming fix would make it even more
+unreadable.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/futex.c | 53 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 26 insertions(+), 27 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 758deac71345..48c37ff4388d 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -2462,18 +2462,13 @@ static void unqueue_me_pi(struct futex_q *q)
+ spin_unlock(q->lock_ptr);
+ }
+
+-static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+- struct task_struct *argowner)
++static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
++ struct task_struct *argowner)
+ {
++ u32 uval, uninitialized_var(curval), newval, newtid;
+ struct futex_pi_state *pi_state = q->pi_state;
+- u32 uval, uninitialized_var(curval), newval;
+ struct task_struct *oldowner, *newowner;
+- u32 newtid;
+- int ret, err = 0;
+-
+- lockdep_assert_held(q->lock_ptr);
+-
+- raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
++ int err = 0;
+
+ oldowner = pi_state->owner;
+
+@@ -2507,14 +2502,12 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+ * We raced against a concurrent self; things are
+ * already fixed up. Nothing to do.
+ */
+- ret = 0;
+- goto out_unlock;
++ return 0;
+ }
+
+ if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) {
+ /* We got the lock. pi_state is correct. Tell caller. */
+- ret = 1;
+- goto out_unlock;
++ return 1;
+ }
+
+ /*
+@@ -2541,8 +2534,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+ * We raced against a concurrent self; things are
+ * already fixed up. Nothing to do.
+ */
+- ret = 1;
+- goto out_unlock;
++ return 1;
+ }
+ newowner = argowner;
+ }
+@@ -2573,7 +2565,6 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+ * itself.
+ */
+ pi_state_update_owner(pi_state, newowner);
+- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
+
+ return argowner == current;
+
+@@ -2596,17 +2587,16 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+
+ switch (err) {
+ case -EFAULT:
+- ret = fault_in_user_writeable(uaddr);
++ err = fault_in_user_writeable(uaddr);
+ break;
+
+ case -EAGAIN:
+ cond_resched();
+- ret = 0;
++ err = 0;
+ break;
+
+ default:
+ WARN_ON_ONCE(1);
+- ret = err;
+ break;
+ }
+
+@@ -2616,17 +2606,26 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+ /*
+ * Check if someone else fixed it for us:
+ */
+- if (pi_state->owner != oldowner) {
+- ret = argowner == current;
+- goto out_unlock;
+- }
++ if (pi_state->owner != oldowner)
++ return argowner == current;
+
+- if (ret)
+- goto out_unlock;
++ /* Retry if err was -EAGAIN or the fault in succeeded */
++ if (!err)
++ goto retry;
+
+- goto retry;
++ return err;
++}
+
+-out_unlock:
++static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
++ struct task_struct *argowner)
++{
++ struct futex_pi_state *pi_state = q->pi_state;
++ int ret;
++
++ lockdep_assert_held(q->lock_ptr);
++
++ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock);
++ ret = __fixup_pi_state_owner(uaddr, q, argowner);
+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
+ return ret;
+ }
+--
+2.17.1
+