Skip to content

Commit fa76887

Browse files
committed
Merge tag 'locking-urgent-2025-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fix from Ingo Molnar: "Fix a dangling pointer bug in the futex code used by the uring code. It isn't causing problems at the moment due to uring ABI limitations leaving it essentially unused in current usages, but is a good idea to fix nevertheless" * tag 'locking-urgent-2025-02-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: futex: Pass in task to futex_queue()
2 parents 8f6629c + 5e0e02f commit fa76887

File tree

5 files changed

+15
-9
lines changed

5 files changed

+15
-9
lines changed

io_uring/futex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ int io_futex_wait(struct io_kiocb *req, unsigned int issue_flags)
338338
hlist_add_head(&req->hash_node, &ctx->futex_list);
339339
io_ring_submit_unlock(ctx, issue_flags);
340340

341-
futex_queue(&ifd->q, hb);
341+
futex_queue(&ifd->q, hb, NULL);
342342
return IOU_ISSUE_SKIP_COMPLETE;
343343
}
344344

kernel/futex/core.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,8 @@ void futex_q_unlock(struct futex_hash_bucket *hb)
532532
futex_hb_waiters_dec(hb);
533533
}
534534

535-
void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb)
535+
void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb,
536+
struct task_struct *task)
536537
{
537538
int prio;
538539

@@ -548,7 +549,7 @@ void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb)
548549

549550
plist_node_init(&q->list, prio);
550551
plist_add(&q->list, &hb->chain);
551-
q->task = current;
552+
q->task = task;
552553
}
553554

554555
/**

kernel/futex/futex.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,25 +285,30 @@ static inline int futex_get_value_locked(u32 *dest, u32 __user *from)
285285
}
286286

287287
extern void __futex_unqueue(struct futex_q *q);
288-
extern void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb);
288+
extern void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb,
289+
struct task_struct *task);
289290
extern int futex_unqueue(struct futex_q *q);
290291

291292
/**
292293
* futex_queue() - Enqueue the futex_q on the futex_hash_bucket
293294
* @q: The futex_q to enqueue
294295
* @hb: The destination hash bucket
296+
* @task: Task queueing this futex
295297
*
296298
* The hb->lock must be held by the caller, and is released here. A call to
297299
* futex_queue() is typically paired with exactly one call to futex_unqueue(). The
298300
* exceptions involve the PI related operations, which may use futex_unqueue_pi()
299301
* or nothing if the unqueue is done as part of the wake process and the unqueue
300302
* state is implicit in the state of woken task (see futex_wait_requeue_pi() for
301303
* an example).
304+
*
305+
* Note that @task may be NULL, for async usage of futexes.
302306
*/
303-
static inline void futex_queue(struct futex_q *q, struct futex_hash_bucket *hb)
307+
static inline void futex_queue(struct futex_q *q, struct futex_hash_bucket *hb,
308+
struct task_struct *task)
304309
__releases(&hb->lock)
305310
{
306-
__futex_queue(q, hb);
311+
__futex_queue(q, hb, task);
307312
spin_unlock(&hb->lock);
308313
}
309314

kernel/futex/pi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,7 @@ int futex_lock_pi(u32 __user *uaddr, unsigned int flags, ktime_t *time, int tryl
982982
/*
983983
* Only actually queue now that the atomic ops are done:
984984
*/
985-
__futex_queue(&q, hb);
985+
__futex_queue(&q, hb, current);
986986

987987
if (trylock) {
988988
ret = rt_mutex_futex_trylock(&q.pi_state->pi_mutex);

kernel/futex/waitwake.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ void futex_wait_queue(struct futex_hash_bucket *hb, struct futex_q *q,
349349
* access to the hash list and forcing another memory barrier.
350350
*/
351351
set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE);
352-
futex_queue(q, hb);
352+
futex_queue(q, hb, current);
353353

354354
/* Arm the timer */
355355
if (timeout)
@@ -460,7 +460,7 @@ int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *woken)
460460
* next futex. Queue each futex at this moment so hb can
461461
* be unlocked.
462462
*/
463-
futex_queue(q, hb);
463+
futex_queue(q, hb, current);
464464
continue;
465465
}
466466

0 commit comments

Comments
 (0)