Patch "futex: Fix potential use-after-free in FUTEX_REQUEUE_PI" has been added to the 4.10-stable tree
This is a note to let you know that I've just added the patch titled
futex: Fix potential use-after-free in FUTEX_REQUEUE_PI
to the 4.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
futex-fix-potential-use-after-free-in-futex_requeue_pi.patch
and it can be found in the queue-4.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
c236c8e95a3d395b0494e7108f0d41cf36ec107cMon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Sat, 4 Mar 2017 10:27:18 +0100
Subject: futex: Fix potential use-after-free in FUTEX_REQUEUE_PI
From: Peter Zijlstra <[email protected]>
commit c236c8e95a3d395b0494e7108f0d41cf36ec107c upstream.
While working on the futex code, I stumbled over this potential use-after-free scenario. Dmitry triggered it later with syzkaller.
pi_mutex is a pointer into pi_state, which we drop the reference on in unqueue_me_pi(). So any access to that pointer after that is bad.
Since other sites already do rt_mutex_unlock() with hb->lock held, see for example futex_lock_pi(), simply move the unlock before unqueue_me_pi().
--- kernel/futex.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
kernel/futex.c +11 -9
@@ -2813,7 +2813,6 @@ static int futex_wait_requeue_pi(u32 __u {struct hrtimer_sleeper timeout, *to =NULL ;struct rt_mutex_waiter rt_waiter; -struct rt_mutex *pi_mutex =NULL ;struct futex_hash_bucket *hb;union futex_key key2 =FUTEX_KEY_INIT ;struct futex_q q = futex_q_init;
@@ -2905,6 +2904,8 @@ static int futex_wait_requeue_pi(u32 __uspin_unlock (q.lock_ptr); } }else { +struct rt_mutex *pi_mutex; +/* * We have been woken up by futex_unlock_pi(), a timeout, or a * signal. futex_unlock_pi() will not destroy the lock_ptr nor
@@ -2928,18 +2929,19 @@ static int futex_wait_requeue_pi(u32 __uif (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 (pi_mutex) == current) +rt_mutex_unlock (pi_mutex); +/* Unqueue and drop the lock. */ unqueue_me_pi (&q); } -/* -* 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 == -EFAULT ) { -if (pi_mutex &&rt_mutex_owner (pi_mutex) == current) -rt_mutex_unlock (pi_mutex); - }else if (ret == -EINTR ) { +if (ret == -EINTR ) {/* * We've already been requeued, but cannot restart by calling * futex_lock_pi() directly. We could restart this syscall, but
Patches currently in stable-queue which might be from [email protected] are
queue-4.10/futex-fix-potential-use-after-free-in-futex_requeue_pi.patch queue-4.10/futex-add-missing-error-handling-to-futex_requeue_pi.patch queue-4.10/x86-perf-fix-cr4.pce-propagation-to-use-active_mm-instead-of-mm.patch queue-4.10/x86-intel_rdt-put-group-node-in-rdtgroup_kn_unlock.patch queue-4.10/locking-rwsem-fix-down_write_killable-for-config_rwsem_generic_spinlock-y.patch queue-4.10/x86-tsc-fix-art-for-tsc_known_freq.patch