Merge tag 'locking_urgent_for_v6.17_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fixes from Borislav Petkov:

- Make sure sanity checks down in the mutex lock path happen on the
correct type of task so that they don't trigger falsely

- Use the write unsafe user access pairs when writing a futex value to
prevent an error on PowerPC which does user read and write accesses
differently

* tag 'locking_urgent_for_v6.17_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking: Fix __clear_task_blocked_on() warning from __ww_mutex_wound() path
futex: Use user_write_access_begin/_end() in futex_put_value()

Changed files
+25 -16
include
linux
kernel
futex
locking
+17 -12
include/linux/sched.h
··· 2152 2152 2153 2153 static inline void __set_task_blocked_on(struct task_struct *p, struct mutex *m) 2154 2154 { 2155 + struct mutex *blocked_on = READ_ONCE(p->blocked_on); 2156 + 2155 2157 WARN_ON_ONCE(!m); 2156 2158 /* The task should only be setting itself as blocked */ 2157 2159 WARN_ON_ONCE(p != current); ··· 2164 2162 * with a different mutex. Note, setting it to the same 2165 2163 * lock repeatedly is ok. 2166 2164 */ 2167 - WARN_ON_ONCE(p->blocked_on && p->blocked_on != m); 2168 - p->blocked_on = m; 2165 + WARN_ON_ONCE(blocked_on && blocked_on != m); 2166 + WRITE_ONCE(p->blocked_on, m); 2169 2167 } 2170 2168 2171 2169 static inline void set_task_blocked_on(struct task_struct *p, struct mutex *m) ··· 2176 2174 2177 2175 static inline void __clear_task_blocked_on(struct task_struct *p, struct mutex *m) 2178 2176 { 2179 - WARN_ON_ONCE(!m); 2180 - /* Currently we serialize blocked_on under the mutex::wait_lock */ 2181 - lockdep_assert_held_once(&m->wait_lock); 2182 - /* 2183 - * There may be cases where we re-clear already cleared 2184 - * blocked_on relationships, but make sure we are not 2185 - * clearing the relationship with a different lock. 2186 - */ 2187 - WARN_ON_ONCE(m && p->blocked_on && p->blocked_on != m); 2188 - p->blocked_on = NULL; 2177 + if (m) { 2178 + struct mutex *blocked_on = READ_ONCE(p->blocked_on); 2179 + 2180 + /* Currently we serialize blocked_on under the mutex::wait_lock */ 2181 + lockdep_assert_held_once(&m->wait_lock); 2182 + /* 2183 + * There may be cases where we re-clear already cleared 2184 + * blocked_on relationships, but make sure we are not 2185 + * clearing the relationship with a different lock. 2186 + */ 2187 + WARN_ON_ONCE(blocked_on && blocked_on != m); 2188 + } 2189 + WRITE_ONCE(p->blocked_on, NULL); 2189 2190 } 2190 2191 2191 2192 static inline void clear_task_blocked_on(struct task_struct *p, struct mutex *m)
+3 -3
kernel/futex/futex.h
··· 319 319 { 320 320 if (can_do_masked_user_access()) 321 321 to = masked_user_access_begin(to); 322 - else if (!user_read_access_begin(to, sizeof(*to))) 322 + else if (!user_write_access_begin(to, sizeof(*to))) 323 323 return -EFAULT; 324 324 unsafe_put_user(val, to, Efault); 325 - user_read_access_end(); 325 + user_write_access_end(); 326 326 return 0; 327 327 Efault: 328 - user_read_access_end(); 328 + user_write_access_end(); 329 329 return -EFAULT; 330 330 } 331 331
+5 -1
kernel/locking/ww_mutex.h
··· 342 342 * When waking up the task to wound, be sure to clear the 343 343 * blocked_on pointer. Otherwise we can see circular 344 344 * blocked_on relationships that can't resolve. 345 + * 346 + * NOTE: We pass NULL here instead of lock, because we 347 + * are waking the mutex owner, who may be currently 348 + * blocked on a different mutex. 345 349 */ 346 - __clear_task_blocked_on(owner, lock); 350 + __clear_task_blocked_on(owner, NULL); 347 351 wake_q_add(wake_q, owner); 348 352 } 349 353 return true;