Patch "futex: Fix pi_state->owner serialization" has been added to the 4.13-stable tree
This is a note to let you know that I've just added the patch titled
futex: Fix pi_state->owner serialization
to the 4.13-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-pi_state-owner-serialization.patch
and it can be found in the queue-4.13 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
c74aef2d06a9f59cece89093eecc552933cba72aMon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Fri, 22 Sep 2017 17:48:06 +0200
Subject: futex: Fix pi_state->owner serialization
From: Peter Zijlstra <[email protected]>
commit c74aef2d06a9f59cece89093eecc552933cba72a upstream.
There was a reported suspicion about a race between exit_pi_state_list() and put_pi_state(). The same report mentioned the comment with put_pi_state() said it should be called with hb->lock held, and it no longer is in all places.
As it turns out, the pi_state->owner serialization is indeed broken. As per the new rules:
734009e96d19 ("futex: Change locking rules")
pi_state->owner should be serialized by pi_state->pi_mutex.wait_lock. For the sites setting pi_state->owner we already hold wait_lock (where required) but exit_pi_state_list() and put_pi_state() were not and raced on clearing it.
--- kernel/futex.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-)
kernel/futex.c +22 -11
@@ -821,8 +821,6 @@ static void get_pi_state(struct futex_pi/* * Drops a reference to the pi_state object and frees or caches it * when the last reference is gone. -* -* Must be called with the hb lock held. */ static void put_pi_state (struct futex_pi_state *pi_state) {
@@ -837,16 +835,22 @@ static void put_pi_state(struct futex_pi* and has cleaned up the pi_state already */ if (pi_state->owner) { -raw_spin_lock_irq (&pi_state->owner->pi_lock); -list_del_init (&pi_state->list); -raw_spin_unlock_irq (&pi_state->owner->pi_lock); +struct task_struct *owner; -rt_mutex_proxy_unlock (&pi_state->pi_mutex, pi_state->owner); +raw_spin_lock_irq (&pi_state->pi_mutex.wait_lock); + owner = pi_state->owner; +if (owner) { +raw_spin_lock (&owner->pi_lock); +list_del_init (&pi_state->list); +raw_spin_unlock (&owner->pi_lock); + } +rt_mutex_proxy_unlock (&pi_state->pi_mutex, owner); +raw_spin_unlock_irq (&pi_state->pi_mutex.wait_lock); } -if (current->pi_state_cache) +if (current->pi_state_cache) {kfree (pi_state); -else { + }else {/* * pi_state->list is already empty. * clear pi_state->owner.
@@ -905,13 +909,14 @@ void exit_pi_state_list(struct task_struraw_spin_unlock_irq (&curr->pi_lock);spin_lock (&hb->lock); - -raw_spin_lock_irq (&curr->pi_lock); +raw_spin_lock_irq (&pi_state->pi_mutex.wait_lock); +raw_spin_lock (&curr->pi_lock);/* * We dropped the pi-lock, so re-check whether this * task still owns the PI-state: */ if (head->next != next) { +raw_spin_unlock (&pi_state->pi_mutex.wait_lock);spin_unlock (&hb->lock);continue ; }
@@ -920,9 +925,10 @@ void exit_pi_state_list(struct task_struWARN_ON (list_empty (&pi_state->list));list_del_init (&pi_state->list); pi_state->owner =NULL ; -raw_spin_unlock_irq (&curr->pi_lock); +raw_spin_unlock (&curr->pi_lock);get_pi_state (pi_state); +raw_spin_unlock_irq (&pi_state->pi_mutex.wait_lock);spin_unlock (&hb->lock);rt_mutex_futex_unlock (&pi_state->pi_mutex);
@@ -1204,6 +1210,10 @@ static int attach_to_pi_owner(u32 uval,WARN_ON (!list_empty (&pi_state->list));list_add (&pi_state->list, &p->pi_state_list); +/* +* Assignment without holding pi_state->pi_mutex.wait_lock is safe +* because there is no concurrency as the object is not published yet. +*/ pi_state->owner = p;raw_spin_unlock_irq (&p->pi_lock);
@@ -2820,6 +2830,7 @@ retry:raw_spin_lock_irq (&pi_state->pi_mutex.wait_lock);spin_unlock (&hb->lock); +/* drops pi_state->pi_mutex.wait_lock */ ret =wake_futex_pi (uaddr, uval, pi_state);put_pi_state (pi_state);
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/fs-proc-report-eip-esp-in-prod-pid-stat-for-coredumping.patch queue-4.13/genirq-fix-cpumask-check-in-__irq_startup_managed.patch queue-4.13/futex-fix-pi_state-owner-serialization.patch queue-4.13/kvm-x86-handle-async-pf-in-rcu-read-side-critical-sections.patch queue-4.13/sched-sysctl-check-user-input-value-of-sysctl_sched_time_avg.patch