From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (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 ADD373446A7 for ; Sat, 22 Aug 2026 05:37:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787377076; cv=none; b=t0XcvIyFiQrHRq4Soyef679zPWqh5gmlj1J16+rd/DxkUq/IV3+arImkqmTX+cmu3b+SLYE2yMjdqV4Pp5SN1dzm/mmsoYkG/SpOrxoKeYTF0wxkzTwPS22FwOuaIKIUdjhoI63j2tztKCVCG4F2TuntbGzSapiBBeHrmOhoQTU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787377076; c=relaxed/simple; bh=Pg5blXGo5aqPE7BiDRPq0QGGNbnstTMi5o+EW2/Exf8=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=Z8vxf6YJm7ml7sqEoeJjIbZScbZ+BeMGgMe1m3YV1Wh+kMlCEGPI+vP/+0XKr6SUYqqPUrW3zmWfHfFGouI8ekLKuQaI8ukkgeDNb8+915HavTKV+KpvbYFv6U9F5Ba0jK+5PELdnm4mGZ+ttzx3r0mBuoic4151CjWCF7rn6UU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bXDdV7II; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bXDdV7II" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-2ceb096e675so20800565ad.0 for ; Fri, 21 Aug 2026 22:37:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787377074; x=1787981874; darn=vger.kernel.org; h=content-disposition:content-type:mime-version:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hp7NQPx3vLl6VxijZLtJOuhB7i2Q9wC/ca4GkjFq1Zk=; b=bXDdV7IIr5MRyFKsy7VYVmcUtO5Wyh+Of+qLZXzZxNj9/ewoOqJtu3Wzk4pB2UPm9z cUtx7CpC0RHc/h4cnUqZAWjvXBd0di5YegAcfl6oZnxBp8MWxqld3LRdGLNP2kUWTAC4 5Vqj80ZKSC0WJlTNjP/ouZfejx4wUBUaLO1WEf5JNBsZnkVe9A1Z5KsIOPFoZ6uA927U wXRzlgoQliPDSLTLMTTYRYfmuRmNWEsX93xL0HN1Ib2PPf3oAfLd80CoFVJct9kWPNbz qeZ/CjmxlfPjgWfB+rRUryoaDBs+fGVeQgYU73Wbo/J3Fa6qZvWdAGhHSo0VOOQQZ19Q LT9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787377074; x=1787981874; h=content-disposition:content-type:mime-version:message-id:subject:cc :to:from:date:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hp7NQPx3vLl6VxijZLtJOuhB7i2Q9wC/ca4GkjFq1Zk=; b=OW8lt27QHPkWlXx61NWqYxqIMexrnNOyLZLO29tJ0viO18LB+RBrZgxMrOzBsgTL5N F7Rbc6A9nvyWDNEKq0gmCgfCc7xzAdDh8R4Fo341avJ5sKroXbPyLx6aNfJ2rLlkobux X2CBh64pMToRXcQ//3Sfmyn69wnC2qO5FJd1cOaf4yWPkpv0nchPfb3Hmm+wWZrKfpv1 5d1krUe/iGQYcUSajjgwyGYhwmKh5Lxa2koE2n9BRANB35lkE0ADxvcHACrXR0DDWJZN cnqzIbDrLpEz3etoSo/q/kM+LkoGOoVjecDCWCg40yjxR1RUNRI7SDLJwZumaQwJ/49X x04w== X-Gm-Message-State: AFuF++mUujMqysg9A4pelcNW7vj9tIsNOm9V8R5lbwQJWo1DTveFNzpJ lVJi54icAmS/8dlGwV2V88Rl8tKuF6vAE0H0uSJD/xfcFdWoEm0R6mQ3 X-Gm-Gg: AR+sD12j4Ze3y+4eEzY/VK264JZuf0Swu9KDp3BZTyww4RRhAmDVEPVrEDXrG9cYrrk k8lqEw7Oh/k0VQQBVv97umU6NjM8hDUmm+3zh1dO43CHbT9/xLiJiDOoL9yHcWLs42rHVmxy4o8 qmmdhwyz3SCwY8MRB79wkJS33eBqngjMhWr1C7YDQwn2s3Gr3/BJ7/sNhhK836swxk3zrMMCWny FINNs/b10nZYXLBUdbwbxKyCcQTTdx0rr5ZINzl2c268P73brXVRWmNoszEN/B7V3xjY3sTZcMe rsf9QbDJFinmIdADRs96hd1wlLwq+vyP+TLo0w6mBXT8oyGg46KTNhRnDj8a1dBn9HmVgX5l08L jwSx7Bod+eVY8d2eCpZid/StCRRHH8uoYYp66o1ugLY0G6np1D+iAnfHuq3i9C8a9HgtgMjp0Yt VkLEkQU58z6/eGc1jQ3IbjYiWG7wdhPnJ2WwZ7bMHjFDXaupAH8J0p8IAz9PV6RI5E7sqwiNU2X DgOU2eA X-Received: by 2002:a17:90b:280a:b0:38e:bfe:81e9 with SMTP id 98e67ed59e1d1-395dee56103mr7326517a91.1.1787377073796; Fri, 21 Aug 2026 22:37:53 -0700 (PDT) Received: from v4bel ([58.123.110.97]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-395e4b2b9c9sm1437325a91.15.2026.08.21.22.37.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2026 22:37:53 -0700 (PDT) Date: Sat, 22 Aug 2026 14:37:49 +0900 From: Hyunwoo Kim To: oleg@redhat.com, frederic@kernel.org, tglx@kernel.org, brauner@kernel.org, peterz@infradead.org, anna-maria@linutronix.de, ebiederm@xmission.com Cc: linux-kernel@vger.kernel.org, imv4bel@gmail.com Subject: [PATCH] signal: Use list_del_init_careful() in flush_sigqueue() Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline commit fb3bbcfe344e ("exit: change the release_task() paths to call flush_sigqueue() lockless") moved the ->pending flush from __exit_signal() to release_task(), where it runs without ->siglock. The justification was: after the exiting task passes __exit_signal() lock_task_sighand() can't succeed and pid_task(tmr->it_pid) will return NULL That second half does not hold for the old group leader in a non-leader exec(). de_thread() calls exchange_tids() before release_task(leader), so the struct pid held by a SIGEV_THREAD_ID timer created against the leader's tid now points to the thread which called execve(). pid_task() returns that thread and lock_task_sighand() on it succeeds. It uses the same sighand the leader used, so while the flush was still done in __exit_signal(), that one ->siglock serialized the two. If the timer signal is blocked, its sigqueue stays queued on the leader's ->pending. The next expiry of that timer can then run while release_task() flushes the queue. posixtimer_send_sigqueue() checks whether the sigqueue is already queued with a plain list_empty(), which only reads ->next. list_del_init() is not atomic and INIT_LIST_HEAD() stores ->next before ->prev, so the check can pass in between. list_add_tail() queues the entry on the ->pending of the live thread, and the ->prev store from the flush then overwrites the ->prev link that list_add_tail() has just set. __flush_itimer_signals() does not undo that either. With ->prev pointing at the entry itself, its list_del_init() only stores the same values again, so the entry is not removed from the list. It is still there after the last reference is dropped and the timer is freed by RCU, and the list_add_tail() of a later tgkill() follows that ->prev into the freed timer: BUG: KASAN: slab-use-after-free in __send_signal_locked+0xb27/0xba0 Write of size 8 at addr ffff888007ed80c8 by task poc/79 ... Call Trace: __send_signal_locked+0xb27/0xba0 do_send_sig_info+0xa7/0x160 do_send_specific+0x76/0xa0 __x64_sys_tgkill+0x193/0x270 ... Allocated by task 80: do_timer_create+0x1a4/0x1030 __x64_sys_timer_create+0x145/0x190 ... Freed by task 12: kmem_cache_free_bulk+0x1f8/0x4a0 kvfree_rcu_bulk+0x14f/0x1c0 kfree_rcu_work+0x128/0x1a0 ... Last potentially related work creation: kvfree_call_rcu+0x39/0x390 __flush_itimer_signals+0x211/0x320 flush_itimer_signals+0x47/0x90 begin_new_exec+0xa6b/0x28c0 ... The buggy address belongs to the object at ffff888007ed8040 which belongs to the cache posix_timers_cache of size 384 Use list_del_init_careful(), which stores ->next last. A list_empty() which sees the entry unqueued is then guaranteed that the flush will not store into the entry any more. Fixes: fb3bbcfe344e ("exit: change the release_task() paths to call flush_sigqueue() lockless") Cc: stable@vger.kernel.org Signed-off-by: Hyunwoo Kim --- kernel/signal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/signal.c b/kernel/signal.c index bbc0fd4cc4d7c1..ec9a0a0490d19f 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -482,7 +482,11 @@ void flush_sigqueue(struct sigpending *queue) sigemptyset(&queue->signal); while (!list_empty(&queue->list)) { q = list_entry(queue->list.next, struct sigqueue , list); - list_del_init(&q->list); + /* + * Pairs with the list_empty() in posixtimer_send_sigqueue(). + * release_task() gets here without ->siglock. + */ + list_del_init_careful(&q->list); __sigqueue_free(q); } } -- 2.43.0