Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fixes from Thomas Gleixner:
"Three fixes related to locking:

- fix a SIGKILL issue for RWSEM_GENERIC_SPINLOCK which has been fixed
for the XCHGADD variant already

- plug a potential use after free in the futex code

- prevent leaking a held spinlock in an futex error handling code
path"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/rwsem: Fix down_write_killable() for CONFIG_RWSEM_GENERIC_SPINLOCK=y
futex: Add missing error handling to FUTEX_REQUEUE_PI
futex: Fix potential use-after-free in FUTEX_REQUEUE_PI

+24 -14
+13 -9
kernel/futex.c
··· 2815 2815 { 2816 2816 struct hrtimer_sleeper timeout, *to = NULL; 2817 2817 struct rt_mutex_waiter rt_waiter; 2818 - struct rt_mutex *pi_mutex = NULL; 2819 2818 struct futex_hash_bucket *hb; 2820 2819 union futex_key key2 = FUTEX_KEY_INIT; 2821 2820 struct futex_q q = futex_q_init; ··· 2898 2899 if (q.pi_state && (q.pi_state->owner != current)) { 2899 2900 spin_lock(q.lock_ptr); 2900 2901 ret = fixup_pi_state_owner(uaddr2, &q, current); 2902 + if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) 2903 + rt_mutex_unlock(&q.pi_state->pi_mutex); 2901 2904 /* 2902 2905 * Drop the reference to the pi state which 2903 2906 * the requeue_pi() code acquired for us. ··· 2908 2907 spin_unlock(q.lock_ptr); 2909 2908 } 2910 2909 } else { 2910 + struct rt_mutex *pi_mutex; 2911 + 2911 2912 /* 2912 2913 * We have been woken up by futex_unlock_pi(), a timeout, or a 2913 2914 * signal. futex_unlock_pi() will not destroy the lock_ptr nor ··· 2933 2930 if (res) 2934 2931 ret = (res < 0) ? res : 0; 2935 2932 2933 + /* 2934 + * If fixup_pi_state_owner() faulted and was unable to handle 2935 + * the fault, unlock the rt_mutex and return the fault to 2936 + * userspace. 2937 + */ 2938 + if (ret && rt_mutex_owner(pi_mutex) == current) 2939 + rt_mutex_unlock(pi_mutex); 2940 + 2936 2941 /* Unqueue and drop the lock. */ 2937 2942 unqueue_me_pi(&q); 2938 2943 } 2939 2944 2940 - /* 2941 - * If fixup_pi_state_owner() faulted and was unable to handle the 2942 - * fault, unlock the rt_mutex and return the fault to userspace. 2943 - */ 2944 - if (ret == -EFAULT) { 2945 - if (pi_mutex && rt_mutex_owner(pi_mutex) == current) 2946 - rt_mutex_unlock(pi_mutex); 2947 - } else if (ret == -EINTR) { 2945 + if (ret == -EINTR) { 2948 2946 /* 2949 2947 * We've already been requeued, but cannot restart by calling 2950 2948 * futex_lock_pi() directly. We could restart this syscall, but
+11 -5
kernel/locking/rwsem-spinlock.c
··· 213 213 */ 214 214 if (sem->count == 0) 215 215 break; 216 - if (signal_pending_state(state, current)) { 217 - ret = -EINTR; 218 - goto out; 219 - } 216 + if (signal_pending_state(state, current)) 217 + goto out_nolock; 218 + 220 219 set_current_state(state); 221 220 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); 222 221 schedule(); ··· 223 224 } 224 225 /* got the lock */ 225 226 sem->count = -1; 226 - out: 227 227 list_del(&waiter.list); 228 228 229 229 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); 230 230 231 231 return ret; 232 + 233 + out_nolock: 234 + list_del(&waiter.list); 235 + if (!list_empty(&sem->wait_list)) 236 + __rwsem_do_wake(sem, 1); 237 + raw_spin_unlock_irqrestore(&sem->wait_lock, flags); 238 + 239 + return -EINTR; 232 240 } 233 241 234 242 void __sched __down_write(struct rw_semaphore *sem)