From: Greg Kroah-Hartman Date: Fri, 29 Jan 2021 10:11:43 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.254~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0d84b3ec4cd3ded4d0e22e25b862f3db37a558f0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: futex_Ensure_the_correct_return_value_from_futex_lock_pi_.patch futex_Handle_faults_correctly_for_PI_futexes.patch futex_Provide_and_use_pi_state_update_owner_.patch futex_Replace_pointless_printk_in_fixup_owner_.patch futex_Simplify_fixup_pi_state_owner_.patch futex_Use_pi_state_update_owner__in_put_pi_state_.patch io_uring-fix-current-fs-handling-in-io_sq_wq_submit_work.patch rtmutex_Remove_unused_argument_from_rt_mutex_proxy_unlock_.patch --- diff --git a/queue-4.14/futex-futex_wake_op-fix-sign_extend32-sign-bits.patch b/queue-4.14/futex-futex_wake_op-fix-sign_extend32-sign-bits.patch index 17517132214..8b9491521fb 100644 --- a/queue-4.14/futex-futex_wake_op-fix-sign_extend32-sign-bits.patch +++ b/queue-4.14/futex-futex_wake_op-fix-sign_extend32-sign-bits.patch @@ -20,12 +20,8 @@ Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Darren Hart Signed-off-by: Linus Torvalds +Signed-off-by: Thomas Gleixner Signed-off-by: Greg Kroah-Hartman - ---- - kernel/futex.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1725,8 +1725,8 @@ static int futex_atomic_op_inuser(unsign diff --git a/queue-4.14/futex_Ensure_the_correct_return_value_from_futex_lock_pi_.patch b/queue-4.14/futex_Ensure_the_correct_return_value_from_futex_lock_pi_.patch new file mode 100644 index 00000000000..63d1f21a1fc --- /dev/null +++ b/queue-4.14/futex_Ensure_the_correct_return_value_from_futex_lock_pi_.patch @@ -0,0 +1,134 @@ +Subject: futex: Ensure the correct return value from futex_lock_pi() +From: Thomas Gleixner +Date: Wed Jan 20 16:00:24 2021 +0100 + +From: Thomas Gleixner + +commit 12bb3f7f1b03d5913b3f9d4236a488aa7774dfe9 upstream + +In case that futex_lock_pi() was aborted by a signal or a timeout and the +task returned without acquiring the rtmutex, but is the designated owner of +the futex due to a concurrent futex_unlock_pi() fixup_owner() is invoked to +establish consistent state. In that case it invokes fixup_pi_state_owner() +which in turn tries to acquire the rtmutex again. If that succeeds then it +does not propagate this success to fixup_owner() and futex_lock_pi() +returns -EINTR or -ETIMEOUT despite having the futex locked. + +Return success from fixup_pi_state_owner() in all cases where the current +task owns the rtmutex and therefore the futex and propagate it correctly +through fixup_owner(). Fixup the other callsite which does not expect a +positive return value. + +Fixes: c1e2f0eaf015 ("futex: Avoid violating the 10th rule of futex") +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2507,8 +2507,8 @@ retry: + } + + if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) { +- /* We got the lock after all, nothing to fix. */ +- ret = 0; ++ /* We got the lock. pi_state is correct. Tell caller. */ ++ ret = 1; + goto out_unlock; + } + +@@ -2536,7 +2536,7 @@ retry: + * We raced against a concurrent self; things are + * already fixed up. Nothing to do. + */ +- ret = 0; ++ ret = 1; + goto out_unlock; + } + newowner = argowner; +@@ -2582,7 +2582,7 @@ retry: + raw_spin_unlock(&newowner->pi_lock); + raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + +- return 0; ++ return argowner == current; + + /* + * In order to reschedule or handle a page fault, we need to drop the +@@ -2624,7 +2624,7 @@ handle_err: + * Check if someone else fixed it for us: + */ + if (pi_state->owner != oldowner) { +- ret = 0; ++ ret = argowner == current; + goto out_unlock; + } + +@@ -2657,8 +2657,6 @@ static long futex_wait_restart(struct re + */ + static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) + { +- int ret = 0; +- + if (locked) { + /* + * Got the lock. We might not be the anticipated owner if we +@@ -2669,8 +2667,8 @@ static int fixup_owner(u32 __user *uaddr + * stable state, anything else needs more attention. + */ + if (q->pi_state->owner != current) +- ret = fixup_pi_state_owner(uaddr, q, current); +- goto out; ++ return fixup_pi_state_owner(uaddr, q, current); ++ return 1; + } + + /* +@@ -2681,10 +2679,8 @@ static int fixup_owner(u32 __user *uaddr + * Another speculative read; pi_state->owner == current is unstable + * but needs our attention. + */ +- if (q->pi_state->owner == current) { +- ret = fixup_pi_state_owner(uaddr, q, NULL); +- goto out; +- } ++ if (q->pi_state->owner == current) ++ return fixup_pi_state_owner(uaddr, q, NULL); + + /* + * Paranoia check. If we did not take the lock, then we should not be +@@ -2697,8 +2693,7 @@ static int fixup_owner(u32 __user *uaddr + q->pi_state->owner); + } + +-out: +- return ret ? ret : locked; ++ return 0; + } + + /** +@@ -3429,7 +3424,7 @@ static int futex_wait_requeue_pi(u32 __u + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); +- if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { ++ if (ret < 0 && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { + pi_state = q.pi_state; + get_pi_state(pi_state); + } +@@ -3439,6 +3434,11 @@ static int futex_wait_requeue_pi(u32 __u + */ + put_pi_state(q.pi_state); + spin_unlock(q.lock_ptr); ++ /* ++ * Adjust the return value. It's either -EFAULT or ++ * success (1) but the caller expects 0 for success. ++ */ ++ ret = ret < 0 ? ret : 0; + } + } else { + struct rt_mutex *pi_mutex; diff --git a/queue-4.14/futex_Handle_faults_correctly_for_PI_futexes.patch b/queue-4.14/futex_Handle_faults_correctly_for_PI_futexes.patch new file mode 100644 index 00000000000..4f3aa55b33f --- /dev/null +++ b/queue-4.14/futex_Handle_faults_correctly_for_PI_futexes.patch @@ -0,0 +1,160 @@ +Subject: futex: Handle faults correctly for PI futexes +From: Thomas Gleixner +Date: Mon Jan 18 19:01:21 2021 +0100 + +From: Thomas Gleixner + +commit 34b1a1ce1458f50ef27c54e28eb9b1947012907a upstream + +fixup_pi_state_owner() tries to ensure that the state of the rtmutex, +pi_state and the user space value related to the PI futex are consistent +before returning to user space. In case that the user space value update +faults and the fault cannot be resolved by faulting the page in via +fault_in_user_writeable() the function returns with -EFAULT and leaves +the rtmutex and pi_state owner state inconsistent. + +A subsequent futex_unlock_pi() operates on the inconsistent pi_state and +releases the rtmutex despite not owning it which can corrupt the RB tree of +the rtmutex and cause a subsequent kernel stack use after free. + +It was suggested to loop forever in fixup_pi_state_owner() if the fault +cannot be resolved, but that results in runaway tasks which is especially +undesired when the problem happens due to a programming error and not due +to malice. + +As the user space value cannot be fixed up, the proper solution is to make +the rtmutex and the pi_state consistent so both have the same owner. This +leaves the user space value out of sync. Any subsequent operation on the +futex will fail because the 10th rule of PI futexes (pi_state owner and +user space value are consistent) has been violated. + +As a consequence this removes the inept attempts of 'fixing' the situation +in case that the current task owns the rtmutex when returning with an +unresolvable fault by unlocking the rtmutex which left pi_state::owner and +rtmutex::owner out of sync in a different and only slightly less dangerous +way. + +Fixes: 1b7558e457ed ("futexes: fix fault handling in futex_lock_pi") +Reported-by: gzobqq@gmail.com +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 56 ++++++++++++++++++++------------------------------------ + 1 file changed, 20 insertions(+), 36 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1052,7 +1052,8 @@ static inline void exit_pi_state_list(st + * FUTEX_OWNER_DIED bit. See [4] + * + * [10] There is no transient state which leaves owner and user space +- * TID out of sync. ++ * TID out of sync. Except one error case where the kernel is denied ++ * write access to the user address, see fixup_pi_state_owner(). + * + * + * Serialization and lifetime rules: +@@ -2614,6 +2615,24 @@ handle_err: + if (!err) + goto retry; + ++ /* ++ * fault_in_user_writeable() failed so user state is immutable. At ++ * best we can make the kernel state consistent but user state will ++ * be most likely hosed and any subsequent unlock operation will be ++ * rejected due to PI futex rule [10]. ++ * ++ * Ensure that the rtmutex owner is also the pi_state owner despite ++ * the user space value claiming something different. There is no ++ * point in unlocking the rtmutex if current is the owner as it ++ * would need to wait until the next waiter has taken the rtmutex ++ * to guarantee consistent state. Keep it simple. Userspace asked ++ * for this wreckaged state. ++ * ++ * The rtmutex has an owner - either current or some other ++ * task. See the EAGAIN loop above. ++ */ ++ pi_state_update_owner(pi_state, rt_mutex_owner(&pi_state->pi_mutex)); ++ + return err; + } + +@@ -2903,7 +2922,6 @@ static int futex_lock_pi(u32 __user *uad + ktime_t *time, int trylock) + { + struct hrtimer_sleeper timeout, *to = NULL; +- struct futex_pi_state *pi_state = NULL; + struct task_struct *exiting = NULL; + struct rt_mutex_waiter rt_waiter; + struct futex_hash_bucket *hb; +@@ -3046,23 +3064,9 @@ no_block: + if (res) + ret = (res < 0) ? res : 0; + +- /* +- * If fixup_owner() faulted and was unable to handle the fault, unlock +- * it and return the fault to userspace. +- */ +- if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) { +- pi_state = q.pi_state; +- get_pi_state(pi_state); +- } +- + /* Unqueue and drop the lock */ + unqueue_me_pi(&q); + +- if (pi_state) { +- rt_mutex_futex_unlock(&pi_state->pi_mutex); +- put_pi_state(pi_state); +- } +- + goto out_put_key; + + out_unlock_put_key: +@@ -3328,7 +3332,6 @@ static int futex_wait_requeue_pi(u32 __u + u32 __user *uaddr2) + { + struct hrtimer_sleeper timeout, *to = NULL; +- struct futex_pi_state *pi_state = NULL; + struct rt_mutex_waiter rt_waiter; + struct futex_hash_bucket *hb; + union futex_key key2 = FUTEX_KEY_INIT; +@@ -3413,10 +3416,6 @@ static int futex_wait_requeue_pi(u32 __u + if (q.pi_state && (q.pi_state->owner != current)) { + spin_lock(q.lock_ptr); + ret = fixup_pi_state_owner(uaddr2, &q, current); +- if (ret < 0 && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { +- pi_state = q.pi_state; +- get_pi_state(pi_state); +- } + /* + * Drop the reference to the pi state which + * the requeue_pi() code acquired for us. +@@ -3458,25 +3457,10 @@ static int futex_wait_requeue_pi(u32 __u + if (res) + ret = (res < 0) ? res : 0; + +- /* +- * If fixup_pi_state_owner() faulted and was unable to handle +- * the fault, unlock the rt_mutex and return the fault to +- * userspace. +- */ +- if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { +- pi_state = q.pi_state; +- get_pi_state(pi_state); +- } +- + /* Unqueue and drop the lock. */ + unqueue_me_pi(&q); + } + +- if (pi_state) { +- rt_mutex_futex_unlock(&pi_state->pi_mutex); +- put_pi_state(pi_state); +- } +- + if (ret == -EINTR) { + /* + * We've already been requeued, but cannot restart by calling diff --git a/queue-4.14/futex_Provide_and_use_pi_state_update_owner_.patch b/queue-4.14/futex_Provide_and_use_pi_state_update_owner_.patch new file mode 100644 index 00000000000..a965e4dc30d --- /dev/null +++ b/queue-4.14/futex_Provide_and_use_pi_state_update_owner_.patch @@ -0,0 +1,113 @@ +Subject: futex: Provide and use pi_state_update_owner() +From: Thomas Gleixner +Date: Tue Jan 19 15:21:35 2021 +0100 + +From: Thomas Gleixner + +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 +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 66 ++++++++++++++++++++++++++++----------------------------- + 1 file changed, 33 insertions(+), 33 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -839,6 +839,29 @@ static struct futex_pi_state *alloc_pi_s + 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(!atomic_inc_not_zero(&pi_state->refcount)); +@@ -1615,26 +1638,15 @@ static int wake_futex_pi(u32 __user *uad + 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); +@@ -2567,19 +2579,7 @@ retry: + * 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; diff --git a/queue-4.14/futex_Replace_pointless_printk_in_fixup_owner_.patch b/queue-4.14/futex_Replace_pointless_printk_in_fixup_owner_.patch new file mode 100644 index 00000000000..fe767660fdb --- /dev/null +++ b/queue-4.14/futex_Replace_pointless_printk_in_fixup_owner_.patch @@ -0,0 +1,40 @@ +Subject: futex: Replace pointless printk in fixup_owner() +From: Thomas Gleixner +Date: Tue Jan 19 16:06:10 2021 +0100 + +From: Thomas Gleixner + +commit 04b79c55201f02ffd675e1231d731365e335c307 upstream + +If that unexpected case of inconsistent arguments ever happens then the +futex state is left completely inconsistent and the printk is not really +helpful. Replace it with a warning and make the state consistent. + +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2684,14 +2684,10 @@ static int fixup_owner(u32 __user *uaddr + + /* + * Paranoia check. If we did not take the lock, then we should not be +- * the owner of the rt_mutex. ++ * the owner of the rt_mutex. Warn and establish consistent state. + */ +- if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) { +- printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " +- "pi-state %p\n", ret, +- q->pi_state->pi_mutex.owner, +- q->pi_state->owner); +- } ++ if (WARN_ON_ONCE(rt_mutex_owner(&q->pi_state->pi_mutex) == current)) ++ return fixup_pi_state_owner(uaddr, q, current); + + return 0; + } diff --git a/queue-4.14/futex_Simplify_fixup_pi_state_owner_.patch b/queue-4.14/futex_Simplify_fixup_pi_state_owner_.patch new file mode 100644 index 00000000000..6c1d0dff23d --- /dev/null +++ b/queue-4.14/futex_Simplify_fixup_pi_state_owner_.patch @@ -0,0 +1,134 @@ +Subject: futex: Simplify fixup_pi_state_owner() +From: Thomas Gleixner +Date: Tue Jan 19 16:26:38 2021 +0100 + +From: Thomas Gleixner + +commit f2dac39d93987f7de1e20b3988c8685523247ae2 upstream + +Too many gotos already and an upcoming fix would make it even more +unreadable. + +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 53 ++++++++++++++++++++++++++--------------------------- + 1 file changed, 26 insertions(+), 27 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2463,18 +2463,13 @@ static void unqueue_me_pi(struct futex_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; + +@@ -2508,14 +2503,12 @@ retry: + * 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; + } + + /* +@@ -2542,8 +2535,7 @@ retry: + * We raced against a concurrent self; things are + * already fixed up. Nothing to do. + */ +- ret = 1; +- goto out_unlock; ++ return 1; + } + newowner = argowner; + } +@@ -2574,7 +2566,6 @@ retry: + * itself. + */ + pi_state_update_owner(pi_state, newowner); +- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + + return argowner == current; + +@@ -2597,17 +2588,16 @@ handle_err: + + 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; + } + +@@ -2617,17 +2607,26 @@ handle_err: + /* + * 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; + } diff --git a/queue-4.14/futex_Use_pi_state_update_owner__in_put_pi_state_.patch b/queue-4.14/futex_Use_pi_state_update_owner__in_put_pi_state_.patch new file mode 100644 index 00000000000..4078ee372b4 --- /dev/null +++ b/queue-4.14/futex_Use_pi_state_update_owner__in_put_pi_state_.patch @@ -0,0 +1,38 @@ +Subject: futex: Use pi_state_update_owner() in put_pi_state() +From: Thomas Gleixner +Date: Wed Jan 20 11:35:19 2021 +0100 + +From: Thomas Gleixner + +commit 6ccc84f917d33312eb2846bd7b567639f585ad6d upstream + +No point in open coding it. This way it gains the extra sanity checks. + +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -884,16 +884,10 @@ static void put_pi_state(struct futex_pi + * and has cleaned up the pi_state already + */ + if (pi_state->owner) { +- struct task_struct *owner; + unsigned long flags; + + raw_spin_lock_irqsave(&pi_state->pi_mutex.wait_lock, flags); +- owner = pi_state->owner; +- if (owner) { +- raw_spin_lock(&owner->pi_lock); +- list_del_init(&pi_state->list); +- raw_spin_unlock(&owner->pi_lock); +- } ++ pi_state_update_owner(pi_state, NULL); + rt_mutex_proxy_unlock(&pi_state->pi_mutex); + raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags); + } diff --git a/queue-4.14/gpio-mvebu-fix-pwm-.get_state-period-calculation.patch b/queue-4.14/gpio-mvebu-fix-pwm-.get_state-period-calculation.patch index a95711ba308..6a333e855e2 100644 --- a/queue-4.14/gpio-mvebu-fix-pwm-.get_state-period-calculation.patch +++ b/queue-4.14/gpio-mvebu-fix-pwm-.get_state-period-calculation.patch @@ -29,7 +29,6 @@ Signed-off-by: Bartosz Golaszewski Reviewed-by: Uwe Kleine-König Signed-off-by: Baruch Siach Signed-off-by: Greg Kroah-Hartman - --- drivers/gpio/gpio-mvebu.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/queue-4.14/io_uring-fix-current-fs-handling-in-io_sq_wq_submit_work.patch b/queue-4.14/io_uring-fix-current-fs-handling-in-io_sq_wq_submit_work.patch new file mode 100644 index 00000000000..b53ff03023c --- /dev/null +++ b/queue-4.14/io_uring-fix-current-fs-handling-in-io_sq_wq_submit_work.patch @@ -0,0 +1,93 @@ +From nstange@suse.de Fri Jan 29 11:09:13 2021 +From: Nicolai Stange +Date: Wed, 27 Jan 2021 14:34:43 +0100 +Subject: [PATCH for stable 5.4] io_uring: Fix current->fs handling in io_sq_wq_submit_work() +To: stable@vger.kernel.org +Cc: Jens Axboe , Nicolai Stange +Message-ID: <20210127133443.2413-1-nstange@suse.de> + +From: Nicolai Stange + +No upstream commit, this is a fix to a stable 5.4 specific backport. + +The intention of backport commit cac68d12c531 ("io_uring: grab ->fs as part +of async offload") as found in the stable 5.4 tree was to make +io_sq_wq_submit_work() to switch the workqueue task's ->fs over to the +submitting task's one during the IO operation. + +However, due to a small logic error, this change turned out to not have any +actual effect. From a high level, the relevant code in +io_sq_wq_submit_work() looks like + + old_fs_struct = current->fs; + do { + ... + if (req->fs != current->fs && current->fs != old_fs_struct) { + task_lock(current); + if (req->fs) + current->fs = req->fs; + else + current->fs = old_fs_struct; + task_unlock(current); + } + ... + } while (req); + +The if condition is supposed to cover the case that current->fs doesn't +match what's needed for processing the request, but observe how it fails +to ever evaluate to true due to the second clause: +current->fs != old_fs_struct will be false in the first iteration as per +the initialization of old_fs_struct and because this prevents current->fs +from getting replaced, the same follows inductively for all subsequent +iterations. + +Fix said if condition such that +- if req->fs is set and doesn't match current->fs, the latter will be + switched to the former +- or if req->fs is unset, the switch back to the initial old_fs_struct + will be made, if necessary. + +While at it, also correct the condition for the ->fs related cleanup right +before the return of io_sq_wq_submit_work(): currently, old_fs_struct is +restored only if it's non-NULL. It is always non-NULL though and thus, the +if-condition is rendundant. Supposedly, the motivation had been to optimize +and avoid switching current->fs back to the initial old_fs_struct in case +it is found to have the desired value already. Make it so. + +Cc: stable@vger.kernel.org # v5.4 +Fixes: cac68d12c531 ("io_uring: grab ->fs as part of async offload") +Reviewed-by: Jens Axboe +Signed-off-by: Nicolai Stange +Signed-off-by: Greg Kroah-Hartman +--- +Tested on top of v5.4.90. + + fs/io_uring.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 4127ea027a14..478df7e10767 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2226,7 +2226,8 @@ static void io_sq_wq_submit_work(struct work_struct *work) + /* Ensure we clear previously set non-block flag */ + req->rw.ki_flags &= ~IOCB_NOWAIT; + +- if (req->fs != current->fs && current->fs != old_fs_struct) { ++ if ((req->fs && req->fs != current->fs) || ++ (!req->fs && current->fs != old_fs_struct)) { + task_lock(current); + if (req->fs) + current->fs = req->fs; +@@ -2351,7 +2352,7 @@ static void io_sq_wq_submit_work(struct work_struct *work) + mmput(cur_mm); + } + revert_creds(old_cred); +- if (old_fs_struct) { ++ if (old_fs_struct != current->fs) { + task_lock(current); + current->fs = old_fs_struct; + task_unlock(current); +-- +2.26.2 + diff --git a/queue-4.14/revert-mm-slub-fix-a-memory-leak-in-sysfs_slab_add.patch b/queue-4.14/revert-mm-slub-fix-a-memory-leak-in-sysfs_slab_add.patch index 35b793db7a0..940afffaaf0 100644 --- a/queue-4.14/revert-mm-slub-fix-a-memory-leak-in-sysfs_slab_add.patch +++ b/queue-4.14/revert-mm-slub-fix-a-memory-leak-in-sysfs_slab_add.patch @@ -36,7 +36,6 @@ Signed-off-by: Wang Hai Cc: Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman - --- mm/slub.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/queue-4.14/rtmutex_Remove_unused_argument_from_rt_mutex_proxy_unlock_.patch b/queue-4.14/rtmutex_Remove_unused_argument_from_rt_mutex_proxy_unlock_.patch new file mode 100644 index 00000000000..92f275b1bd6 --- /dev/null +++ b/queue-4.14/rtmutex_Remove_unused_argument_from_rt_mutex_proxy_unlock_.patch @@ -0,0 +1,56 @@ +Subject: rtmutex: Remove unused argument from rt_mutex_proxy_unlock() +From: Thomas Gleixner +Date: Wed Jan 20 11:32:07 2021 +0100 + +From: Thomas Gleixner + +commit 2156ac1934166d6deb6cd0f6ffc4c1076ec63697 upstream + +Nothing uses the argument. Remove it as preparation to use +pi_state_update_owner(). + +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 2 +- + kernel/locking/rtmutex.c | 3 +-- + kernel/locking/rtmutex_common.h | 3 +-- + 3 files changed, 3 insertions(+), 5 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -894,7 +894,7 @@ static void put_pi_state(struct futex_pi + list_del_init(&pi_state->list); + raw_spin_unlock(&owner->pi_lock); + } +- rt_mutex_proxy_unlock(&pi_state->pi_mutex, owner); ++ rt_mutex_proxy_unlock(&pi_state->pi_mutex); + raw_spin_unlock_irqrestore(&pi_state->pi_mutex.wait_lock, flags); + } + +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -1719,8 +1719,7 @@ void rt_mutex_init_proxy_locked(struct r + * possible because it belongs to the pi_state which is about to be freed + * and it is not longer visible to other tasks. + */ +-void rt_mutex_proxy_unlock(struct rt_mutex *lock, +- struct task_struct *proxy_owner) ++void rt_mutex_proxy_unlock(struct rt_mutex *lock) + { + debug_rt_mutex_proxy_unlock(lock); + rt_mutex_set_owner(lock, NULL); +--- a/kernel/locking/rtmutex_common.h ++++ b/kernel/locking/rtmutex_common.h +@@ -132,8 +132,7 @@ enum rtmutex_chainwalk { + extern struct task_struct *rt_mutex_next_owner(struct rt_mutex *lock); + extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, + struct task_struct *proxy_owner); +-extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, +- struct task_struct *proxy_owner); ++extern void rt_mutex_proxy_unlock(struct rt_mutex *lock); + extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); + extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, + struct rt_mutex_waiter *waiter, diff --git a/queue-4.14/series b/queue-4.14/series index dc67601df4b..5a7814cc382 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -36,3 +36,11 @@ net-dsa-b53-fix-an-off-by-one-in-checking-vlan-vid.patch futex-futex_wake_op-fix-sign_extend32-sign-bits.patch gpio-mvebu-fix-pwm-.get_state-period-calculation.patch revert-mm-slub-fix-a-memory-leak-in-sysfs_slab_add.patch +futex_Ensure_the_correct_return_value_from_futex_lock_pi_.patch +futex_Replace_pointless_printk_in_fixup_owner_.patch +futex_Provide_and_use_pi_state_update_owner_.patch +rtmutex_Remove_unused_argument_from_rt_mutex_proxy_unlock_.patch +futex_Use_pi_state_update_owner__in_put_pi_state_.patch +futex_Simplify_fixup_pi_state_owner_.patch +futex_Handle_faults_correctly_for_PI_futexes.patch +io_uring-fix-current-fs-handling-in-io_sq_wq_submit_work.patch