summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch117
1 files changed, 117 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch
new file mode 100644
index 000000000..ae0f63a18
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2021-3347/0006-futex-Provide-and-use-pi_state_update_owner.patch
@@ -0,0 +1,117 @@
+From 015b6a4c2564a9385401a6105e80a20c333e1d44 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 19 Jan 2021 15:21:35 +0100
+Subject: [PATCH] futex: Provide and use pi_state_update_owner()
+
+commit c5cade200ab9a2a3be9e7f32a752c8d86b502ec7 upstream
+
+Updating pi_state::owner is done at several places with the same
+code. Provide a function for it and use that at the obvious places.
+
+This is also a preparation for a bug fix to avoid yet another copy of the
+same code or alternatively introducing a completely unpenetratable mess of
+gotos.
+
+Originally-by: Peter Zijlstra <peterz@infradead.org>
+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 | 66 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 33 insertions(+), 33 deletions(-)
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 8bfb16258ae7..69f62d0f5851 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -857,6 +857,29 @@ static struct futex_pi_state *alloc_pi_state(void)
+ return pi_state;
+ }
+
++static void pi_state_update_owner(struct futex_pi_state *pi_state,
++ struct task_struct *new_owner)
++{
++ struct task_struct *old_owner = pi_state->owner;
++
++ lockdep_assert_held(&pi_state->pi_mutex.wait_lock);
++
++ if (old_owner) {
++ raw_spin_lock(&old_owner->pi_lock);
++ WARN_ON(list_empty(&pi_state->list));
++ list_del_init(&pi_state->list);
++ raw_spin_unlock(&old_owner->pi_lock);
++ }
++
++ if (new_owner) {
++ raw_spin_lock(&new_owner->pi_lock);
++ WARN_ON(!list_empty(&pi_state->list));
++ list_add(&pi_state->list, &new_owner->pi_state_list);
++ pi_state->owner = new_owner;
++ raw_spin_unlock(&new_owner->pi_lock);
++ }
++}
++
+ static void get_pi_state(struct futex_pi_state *pi_state)
+ {
+ WARN_ON_ONCE(!refcount_inc_not_zero(&pi_state->refcount));
+@@ -1614,26 +1637,15 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_
+ ret = -EINVAL;
+ }
+
+- if (ret)
+- goto out_unlock;
+-
+- /*
+- * This is a point of no return; once we modify the uval there is no
+- * going back and subsequent operations must not fail.
+- */
+-
+- raw_spin_lock(&pi_state->owner->pi_lock);
+- WARN_ON(list_empty(&pi_state->list));
+- list_del_init(&pi_state->list);
+- raw_spin_unlock(&pi_state->owner->pi_lock);
+-
+- raw_spin_lock(&new_owner->pi_lock);
+- WARN_ON(!list_empty(&pi_state->list));
+- list_add(&pi_state->list, &new_owner->pi_state_list);
+- pi_state->owner = new_owner;
+- raw_spin_unlock(&new_owner->pi_lock);
+-
+- postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q);
++ if (!ret) {
++ /*
++ * This is a point of no return; once we modified the uval
++ * there is no going back and subsequent operations must
++ * not fail.
++ */
++ pi_state_update_owner(pi_state, new_owner);
++ postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q);
++ }
+
+ out_unlock:
+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
+@@ -2566,19 +2578,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
+ * We fixed up user space. Now we need to fix the pi_state
+ * itself.
+ */
+- if (pi_state->owner != NULL) {
+- raw_spin_lock(&pi_state->owner->pi_lock);
+- WARN_ON(list_empty(&pi_state->list));
+- list_del_init(&pi_state->list);
+- raw_spin_unlock(&pi_state->owner->pi_lock);
+- }
+-
+- pi_state->owner = newowner;
+-
+- raw_spin_lock(&newowner->pi_lock);
+- WARN_ON(!list_empty(&pi_state->list));
+- list_add(&pi_state->list, &newowner->pi_state_list);
+- raw_spin_unlock(&newowner->pi_lock);
++ pi_state_update_owner(pi_state, newowner);
+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
+
+ return argowner == current;
+--
+2.17.1
+