From nobody Fri Apr 3 20:53:02 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 486193890EE for ; Mon, 23 Mar 2026 10:18:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774261134; cv=none; b=tFMKagoEkZCizWaghwhB544WzJJNvbLrPjU1IluXgX4X21xsdkWZmg1GqmWcGzEfdeCE5gQNiW5eOT98XgNeG0a8tHIbLQmPzpk0H8yTWmMmXJPinsTKl+dW/x4POpLrHVTFWfp5Fda2u+IgSlYvO8ElZlE77tosVeRZatZktpM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774261134; c=relaxed/simple; bh=GdL+Ed1U3cuJA1l3BjShq0EXY3rJt1G9OpI17Ek+RQQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=aHcbinX+f94aXGgeG138dfHd8wO/310MtsczoBR27crCFAQThBxjlOIhE5lDcBHplppd12toL1nAG86lE7RSrT72nIIcRiGgGYioFb4wdM0xQgUeiSLADck1PI+LRN5+Fyy1ST/D/4yQxvHVIdzikS5NpZWtn6uMrDpMwkCCaPM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org; spf=none smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=GB9NYXtV; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="GB9NYXtV" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From: Reply-To:Content-ID:Content-Description:In-Reply-To:References; bh=sW4KLPIsdMqKcuTe+dCrme/HSyW04OH+WgxdZ62Wgio=; b=GB9NYXtV1lDabKLCpmKhk88pZd sfPV9ru6HFUFQhEpIzjOjXkNuSIgZ+5bcI+P+AlTcuaZurtLp3XSO7V/+zxXRmLKjDeO7KZdGsWfO iBqOjx69omHrc3r1GGJYHYr+IuwRnG6bHfasvE5UWyUg3GMqgYziWhqmOv8zNDK6hDaT+jCfyUoln gwkvaXHW9UUWMOxs7Wf08SplZRDp0iqMalAPoAuk0HIlel/yXT3kRjNJZ+eCDT+T1d3kQQGreSn9P KeQM+jt9mvMj+icKVtWsoalE2AFqnftSHvud06ITnZOXToLfBfQDDym4/IXBmiC5BMF2urz56LIDk yL6OUX7w==; Received: from authenticated user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94.2) (envelope-from ) id 1w4cMy-007SYL-24; Mon, 23 Mar 2026 10:18:46 +0000 From: Breno Leitao Date: Mon, 23 Mar 2026 03:18:36 -0700 Subject: [PATCH] workqueue: unlink pwqs from wq->pwqs list in alloc_and_link_pwqs() error path 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="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260323-workqueue_link-v1-1-d32873f6c4a7@debian.org> X-B4-Tracking: v=1; b=H4sIAHwTwWkC/yXMQQqDMBBG4asM/9qAjraFXKWIVB3bqSVq0qgg3 l1sl+8tvg1BvEqApQ1eZg06OFjKEkLzerinGG1hCZzyNc05N8vg+ylKlOqjrjdtdjn3reOCkRB GL52uP/Be/jvE+i3N91Sw7wfSuO3pcgAAAA== X-Change-ID: 20260323-workqueue_link-d1503237f242 To: Tejun Heo , Lai Jiangshan Cc: linux-kernel@vger.kernel.org, kernel-team@meta.com, Breno Leitao X-Mailer: b4 0.15-dev-363b9 X-Developer-Signature: v=1; a=openpgp-sha256; l=1807; i=leitao@debian.org; h=from:subject:message-id; bh=GdL+Ed1U3cuJA1l3BjShq0EXY3rJt1G9OpI17Ek+RQQ=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBpwROD554ELSYhxxtbDAF1uAjlUMAscFMChip0W 0dpOkxqMs+JAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCacETgwAKCRA1o5Of/Hh3 bRYcEACxLCX//xhPdqz4l/iLwUMkLrp6tw7J/vCZkZMs3C5qUzTL52QojGzLdg5guK1Ey0swvSw x5TVsOkJ9N18uG5BCPj5SEiINcKN+uclM0tIE8MseDF1HUq/UOCDKSXlZCH6ttacmCVuRap0Iqt hFWfnDq6dqwKwoWa/dFkUzjG7QVnfG9XeKrnO+hLKVY//6QJFnMvDfRr+RYC9tmIu7CohbuHDd7 1QH2GW9z7QbLyIKr0TZ3lEvVkC4FqYiw7gvG301pVCDrEDut2nHb/9G+IlP1p5oB5BtXjWjCctg zByCV3aDlyqXHPMvJovjS0QPX+huS0l6QRIa3+vkLWe61FivlyRYXettCfwywyffz12kOQlc1QR FFCvR8YvDbjPj5neoHM36ZqOgxd53A860ONMHNgHIfkcly5Zf4HeHUf2IJC0ZsFlZNni9bZTWnW tMM6M5t5of6DDO9L52WvBrywW9VPoowua+ID00weI832sdWKkCuGgd/X0kALb+J9ixLbh9oiMqL 7Nideb57O9rtXWi4GeKawcJDaXYi98UrqfwFPcWfchzHfEr6UcNmL31/CAEYmgY0WZIpNLeKyiJ 65ZKF86sMO0iuAIW0xG20VkI82oRUC2JgT9tO3b0tW4AfIzvw6+B8haLUSzoFkv+/Uu6IOuBpVu 43+aXgzSF5Bw5QA== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao When alloc_and_link_pwqs() fails partway through the per-cpu allocation loop, some pool_workqueues may have already been linked into wq->pwqs via link_pwq(). The error path frees these pwqs with kmem_cache_free() but never removes them from the wq->pwqs list, leaving dangling pointers in the list. Currently this is not exploitable because the workqueue was never added to the global workqueues list and the caller frees the wq immediately after. However, this makes sure that alloc_and_link_pwqs() doesn't leave any half baked structure, which may have side effect is not properly used. Fix this by unlinking each pwq from wq->pwqs before freeing it. No locking is needed as the workqueue has not been published yet, thus no concurrency is possible. Signed-off-by: Breno Leitao --- kernel/workqueue.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b77119d71641a..70581fa7b4e24 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5623,8 +5623,16 @@ static int alloc_and_link_pwqs(struct workqueue_stru= ct *wq) for_each_possible_cpu(cpu) { struct pool_workqueue *pwq =3D *per_cpu_ptr(wq->cpu_pwq, cpu); =20 - if (pwq) + if (pwq) { + /* + * Unlink pwq from wq->pwqs since link_pwq() + * may have already added it. wq->mutex is not + * needed as the wq has not been published yet. + */ + if (!list_empty(&pwq->pwqs_node)) + list_del_rcu(&pwq->pwqs_node); kmem_cache_free(pwq_cache, pwq); + } } free_percpu(wq->cpu_pwq); wq->cpu_pwq =3D NULL; --- base-commit: c369299895a591d96745d6492d4888259b004a9e change-id: 20260323-workqueue_link-d1503237f242 Best regards, -- =20 Breno Leitao