From nobody Sun Feb 8 07:14:42 2026 Received: from mail-il1-f173.google.com (mail-il1-f173.google.com [209.85.166.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40FFC14F9FB for ; Wed, 15 Jan 2025 16:05:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.166.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736957121; cv=none; b=Ue209G6m3zAZ47K41owkOOrIel3d8hxr/1HY9v2EXH4UiVPriJtBHTpRbN2Z1pSoapDy4QUKn8MDq3U3MJqy837OkReo6DeujFLsj2RQZFAtDZJVqlooxNlm4GphJYsvnp0Dhz9q0t20943CgvTezs/rZezGHnq85tS+SFJ6dJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736957121; c=relaxed/simple; bh=o5vwDfAr+/fXZIriPjbI1zi6BlcwHR/3Fn7WT6FYBBk=; h=Message-ID:Date:MIME-Version:To:Cc:From:Subject:Content-Type; b=bA3JqNAcb115zzfXjnuArxWa7cDLndGirAhF6IE3vZt+V6tUp3Yk7+gYylZp4Svrw7e3PZfeKJvBKpMEjxujF2BOTXJNX0gezNOA3aZCL3lC7YukhHAvi+kbTi9ICjNPP0BQca6V3yxik2xUJdyzJJm4MM59Dj/Ltm5fpVVtS1g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk; spf=pass smtp.mailfrom=kernel.dk; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b=GTic3QEY; arc=none smtp.client-ip=209.85.166.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.dk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kernel.dk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel-dk.20230601.gappssmtp.com header.i=@kernel-dk.20230601.gappssmtp.com header.b="GTic3QEY" Received: by mail-il1-f173.google.com with SMTP id e9e14a558f8ab-3cddfa9a331so24251915ab.3 for ; Wed, 15 Jan 2025 08:05:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20230601.gappssmtp.com; s=20230601; t=1736957117; x=1737561917; darn=vger.kernel.org; h=content-transfer-encoding:subject:from:cc:to:content-language :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=vv3WZXcTuXVrMegkZgjtpW7iFoRNlG89jCJPCPX4ZZo=; b=GTic3QEYnlZf/O5ZuO/cem9blOWpzX/vUhko+ALkeNJ7CNG7W4YXZrY4tI445CCPVA kShcztKrRjpuzE3GQHVijnbA6D16G3QmZ9MhrySjQP38qQ65FE8ejcHC1h/GJXMNDTJe 4grJlSvlCTjC2sBQAFfeKkW2/XSoUosr0Ov0db5tX03j4IyntJVdjpC4NQ/zhesv7a9j T++xyI4zSPdsgwv1y9EAfcGpH1UlzNtGwuqHCRyXedUjnhEkQqbtErH56YzFpI90hjVh Imq1sZVXZlEEscwQ4TjDiFlIlYg26DduRvYgai2XzWMPsZN0jcWHCGkMXxVjX0EyQ0zt uZ9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736957117; x=1737561917; h=content-transfer-encoding:subject:from:cc:to:content-language :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=vv3WZXcTuXVrMegkZgjtpW7iFoRNlG89jCJPCPX4ZZo=; b=qv7ZkwAeOAHR2X3K7kDiBuNzZ7ZcOwI7p/dhy+3ibDTQ/TLPtxpjtAxUE5koVOiJFh 4l38oCeQhm3s4I5l27C6u7FjIU9I0yNMC8vzmk+YNRi+u8z5YJrBqoO3XBNqW8gypZ3i Gic4L3poUY543VuytchBfkUImdm2HJ/crkZoeUKgn6/8/7GcxSZbPiNSBQk38U+TTM5d B3ZVtAq3bNn/TJjeQEwF3BbAmFVhL0E8AWd+wcF/cWNKb70mUmNQUR5/nYkvYDVnADpM U+BJeCxohKC71zYjPWUzWsU/uz5WruGlw/zadBxxBoOehe2Cs2rsrQipJOWz6lrPs71y wyng== X-Gm-Message-State: AOJu0YyX9chNs+pM+T/SyNTHpVMxcPE8mRt7K5pwKuRFsvkWtFigdxcb kR028InDKR/XvQStyrL2ILqvmg6PSK8DO/44QO//MO9oLfWfGMpTsDqSygNmwys= X-Gm-Gg: ASbGncs1Kcx5HhdeoYl6RNv6ZqDHT4kBfk90YBkokH5THEKvwyOdxNuH+jaSEAtNT3u pLI9vstlK387FVcL8e8z3Vyq4iWYeuxmjL3p6MIPD3TQ4ncORjvYzCcuTzHjq/VC1UNEXqmGzqa hpjMbnrcRxIT0xl6WH+W2cjXzvXOMU9a3OPmL8VjS3ol/up/1KiVayQoOw2Hn0oDzWmRcUhEyG4 VqdAJU7xX+sMCql23wp+5IjbZTOAbefe5TGDB4KpuWIa8kIkop/ X-Google-Smtp-Source: AGHT+IH+53cZ0VuhIx8Gm1gZVlkNV4dH2nrW7Su8DPZrBGjxW10SjBHmmFAQx7MBw4JxuT/wI107Bw== X-Received: by 2002:a05:6e02:160e:b0:3a7:e86a:e80f with SMTP id e9e14a558f8ab-3ce3a9a5b0cmr249532665ab.3.1736957117272; Wed, 15 Jan 2025 08:05:17 -0800 (PST) Received: from [192.168.1.116] ([96.43.243.2]) by smtp.gmail.com with ESMTPSA id 8926c6da1cb9f-4ea1b613118sm4199442173.36.2025.01.15.08.05.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 15 Jan 2025 08:05:16 -0800 (PST) Message-ID: <22484a23-542c-4003-b721-400688a0d055@kernel.dk> Date: Wed, 15 Jan 2025 09:05:15 -0700 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: Thomas Gleixner , Peter Zijlstra Cc: LKML , Jann Horn From: Jens Axboe Subject: [PATCH for-next] futex: pass in task to futex_queue() Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" futex_queue() -> __futex_queue() uses 'current' as the task to store in the struct futex_q->task field. This is fine for synchronous usage of the futex infrastructure, but it's not always correct when used by io_uring where the task doing the initial futex_queue() might not be available later on. This doesn't lead to any issues currently, as the io_uring side doesn't support PI futexes, but it does leave a potentially dangling pointer which is never a good idea. Have futex_queue() take a task_struct argument, and have the regular callers pass in 'current' for that. Meanwhile io_uring can just pass in NULL, as the task should never be used off that path. In theory req->tctx->task could be used here, but there's no point populating it with a task field that will never be used anyway. Reported-by: Jann Horn Signed-off-by: Jens Axboe --- I didn't mark this one for stable as it isn't fixing a real issue, and because I'm assuming it might cause some rejects there on the futex front. diff --git a/io_uring/futex.c b/io_uring/futex.c index e29662f039e1..f108da4ff863 100644 --- a/io_uring/futex.c +++ b/io_uring/futex.c @@ -349,7 +349,7 @@ int io_futex_wait(struct io_kiocb *req, unsigned int is= sue_flags) hlist_add_head(&req->hash_node, &ctx->futex_list); io_ring_submit_unlock(ctx, issue_flags); =20 - futex_queue(&ifd->q, hb); + futex_queue(&ifd->q, hb, NULL); return IOU_ISSUE_SKIP_COMPLETE; } =20 diff --git a/kernel/futex/core.c b/kernel/futex/core.c index ebdd76b4ecbb..3db8567f5a44 100644 --- a/kernel/futex/core.c +++ b/kernel/futex/core.c @@ -532,7 +532,8 @@ void futex_q_unlock(struct futex_hash_bucket *hb) futex_hb_waiters_dec(hb); } =20 -void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb) +void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb, + struct task_struct *task) { int prio; =20 @@ -548,7 +549,7 @@ void __futex_queue(struct futex_q *q, struct futex_hash= _bucket *hb) =20 plist_node_init(&q->list, prio); plist_add(&q->list, &hb->chain); - q->task =3D current; + q->task =3D task; } =20 /** diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h index 618ce1fe870e..11de6405c4e3 100644 --- a/kernel/futex/futex.h +++ b/kernel/futex/futex.h @@ -285,13 +285,15 @@ static inline int futex_get_value_locked(u32 *dest, u= 32 __user *from) } =20 extern void __futex_unqueue(struct futex_q *q); -extern void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb); +extern void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb, + struct task_struct *task); extern int futex_unqueue(struct futex_q *q); =20 /** * futex_queue() - Enqueue the futex_q on the futex_hash_bucket * @q: The futex_q to enqueue * @hb: The destination hash bucket + * @task: Task queueing this futex * * The hb->lock must be held by the caller, and is released here. A call to * futex_queue() is typically paired with exactly one call to futex_unqueu= e(). The @@ -299,11 +301,14 @@ extern int futex_unqueue(struct futex_q *q); * or nothing if the unqueue is done as part of the wake process and the u= nqueue * state is implicit in the state of woken task (see futex_wait_requeue_pi= () for * an example). + * + * Note that @task may be NULL, for async usage of futexes. */ -static inline void futex_queue(struct futex_q *q, struct futex_hash_bucket= *hb) +static inline void futex_queue(struct futex_q *q, struct futex_hash_bucket= *hb, + struct task_struct *task) __releases(&hb->lock) { - __futex_queue(q, hb); + __futex_queue(q, hb, task); spin_unlock(&hb->lock); } =20 diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c index d62cca5ed8f4..635c7d5d4222 100644 --- a/kernel/futex/pi.c +++ b/kernel/futex/pi.c @@ -982,7 +982,7 @@ int futex_lock_pi(u32 __user *uaddr, unsigned int flags= , ktime_t *time, int tryl /* * Only actually queue now that the atomic ops are done: */ - __futex_queue(&q, hb); + __futex_queue(&q, hb, current); =20 if (trylock) { ret =3D rt_mutex_futex_trylock(&q.pi_state->pi_mutex); diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c index 3a10375d9521..a9056acb75ee 100644 --- a/kernel/futex/waitwake.c +++ b/kernel/futex/waitwake.c @@ -350,7 +350,7 @@ void futex_wait_queue(struct futex_hash_bucket *hb, str= uct futex_q *q, * access to the hash list and forcing another memory barrier. */ set_current_state(TASK_INTERRUPTIBLE|TASK_FREEZABLE); - futex_queue(q, hb); + futex_queue(q, hb, current); =20 /* Arm the timer */ if (timeout) @@ -461,7 +461,7 @@ int futex_wait_multiple_setup(struct futex_vector *vs, = int count, int *woken) * next futex. Queue each futex at this moment so hb can * be unlocked. */ - futex_queue(q, hb); + futex_queue(q, hb, current); continue; } =20 --=20 Jens Axboe