| Message ID | 20260808062029.2597581-1-lgs201920130244@gmail.com (mailing list archive) |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-sunxi+bounces-25068-sunxi=pue.re@lists.linux.dev>
X-Original-To: noreply@patchwork.local
Delivered-To: noreply@patchwork.local
Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])
by mxe881.netcup.net (Postfix) with ESMTPS id 316031C20AD
for <noreply@patchwork.local>; Sat, 8 Aug 2026 08:20:52 +0200 (CEST)
Authentication-Results: mxe881;
dkim=pass header.d=gmail.com;
spf=pass (sender IP is 172.234.253.10)
smtp.mailfrom=linux-sunxi+bounces-25068-noreply=patchwork.local@lists.linux.dev
smtp.helo=sea.lore.kernel.org
Received-SPF: pass (mxe881: domain of lists.linux.dev designates
172.234.253.10 as permitted sender) client-ip=172.234.253.10;
envelope-from=linux-sunxi+bounces-25068-noreply=patchwork.local@lists.linux.dev;
helo=sea.lore.kernel.org;
Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org
[100.90.174.1])
by sea.lore.kernel.org (Postfix) with ESMTP id 7AC09300FC78
for <noreply@patchwork.local>; Sat, 8 Aug 2026 06:20:47 +0000 (UTC)
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
by smtp.subspace.kernel.org (Postfix) with ESMTP id EBE2E369D56;
Sat, 8 Aug 2026 06:20:46 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com
header.b="NRuP4r2f"
X-Original-To: linux-sunxi@lists.linux.dev
Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com
[209.85.216.48])
(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 B781E2D9792
for <linux-sunxi@lists.linux.dev>; Sat, 8 Aug 2026 06:20:45 +0000 (UTC)
Authentication-Results: smtp.subspace.kernel.org;
arc=none smtp.client-ip=209.85.216.48
ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;
t=1786170046; cv=none;
b=KA4rtYz0HxDGR46jC96xHqoLRkqoIxULM2sBW0JNidRepTPMIaWPodWUgq+2ABd2Fj35BLTNUjv9dLG0oatMNwpd+f3A1i3/6DxqGFXCfvS74suM8QYm5qup3rfCtU+4sjtI4N0VPQ6SoiRPnpUJGiTOTsf88TH6dGMp/PmPF0I=
ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org;
s=arc-20240116; t=1786170046; c=relaxed/simple;
bh=NFa9GnuhwXPiI5dsbr0iH6GqeKKs5mM+DrvDRZs6m+Y=;
h=From:To:Cc:Subject:Date:Message-ID:MIME-Version;
b=sy5jDsMW668Y1WXZkdE/CI6hx3f3T3nAZSH73ljwdDa8vGtPgC5GapD4XuLN9ZX9Bhhr+8XnT9w0RaYiXLcLIAAMoQV2tIIjWVQKFr4WeD+RTy5kikxOao0gyiT5V/GzPXMfBsooERQ1JwtQ5EulmsVsEt25l5ILMVAywRdHa18=
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=NRuP4r2f; arc=none smtp.client-ip=209.85.216.48
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
Received: by mail-pj1-f48.google.com with SMTP id
98e67ed59e1d1-38125cebfdaso299420a91.1
for <linux-sunxi@lists.linux.dev>;
Fri, 07 Aug 2026 23:20:45 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20251104; t=1786170045; x=1786774845;
darn=lists.linux.dev;
h=content-transfer-encoding:mime-version:message-id:date:subject:cc
:to:from:from:to:cc:subject:date:message-id:reply-to:content-type;
bh=wKhyMQrWu8wbOkY8L+PT3L5GzBtcKEJdYmE407RmSq8=;
b=NRuP4r2fQfNWIyNDoY2N0AD/lK3N9q66dPN7DH3rA5EbCuP+dEXod5eFxE+ztXRaT2
HwZbb5kvDLMX1DJP4HKC+2ibR2IUQxKesp8JBcg/8vgeCs2aoo2nq/Tq4cOOxoExepae
c9DvmssZErupD0hDJhH+fKCsaZZ5bytLERSbeGwKGJcKxkGoeA+MTFBO4TtZiFUtvFL6
klcm37fo+F3D9N4J3TI1PA0JkMEDDw0FjYBmdRjjE6dKTaj3OdJ6FhsRfGJpuxp506LF
p+Bn9ZmmV9nxwhIq8/DG5rwV/wR1U4/MCw8m0LV0n/tpvR7mwQ4Y1951+s+JM/swG5E2
DKSg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20251104; t=1786170045; x=1786774845;
h=content-transfer-encoding:mime-version:message-id:date:subject:cc
:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date
:message-id:reply-to:content-type;
bh=wKhyMQrWu8wbOkY8L+PT3L5GzBtcKEJdYmE407RmSq8=;
b=HfcNQMc+OOgMvz2M1QTfghvmDwYg6wAAOHy+b7V9dWH91dmmEtIBII/tZHqU2HN+cx
ATWVyHNdLZi6ytPT8k7r8Tm9nCc79IgbXGWvCt9T8GbLR9pNtdo96hiSaxuotDgbuCPB
70N+ejxPr1cvLBVwXlc3sTsmIg5QicqXpIck+vgxYxWpX19kxB78ar8KX9JseF4josYh
7KAkylRzBn+qCnGLfWKkNHfgkFeqUNCD+JCjVXh101pNXMbf8BteEwGWPQn69gDteh2+
drAihINeEfDmyPlZQ2zPc0S2YHA/2mssCQzUehM0JLWajeiaJVfWExwhN4cnq/Dqbv3x
5ULw==
X-Forwarded-Encrypted: i=1;
AHgh+RphEGiPc3F9z6E8Ats31w4muh57IEHC8mjTGjwTKt4xwPHWNprcRo8hwl9aazS/LojQUD25POJYeayqhg==@lists.linux.dev
X-Gm-Message-State: AOJu0YwhFBj0DdrEt604rMlqbjWfZwGtd1ThT0EFyYXNopJWoXUOSJRB
x48aw2yXnGcSYVIXJwBTW09vyVfWRuPV8hJojO2yZ8qHWfFEnINwZFYW
X-Gm-Gg: AR+sD10dbsx7B/dh+Nwbip71MgmislzcjpFcBhnIl0KQWA9KFrwqhP5It5RWJg3zofX
PY6KHPZNV6n9j+AsgaTOUsi2EHn8vFg0QFOa4R2BImj6UfDRbEhROL7Hv3UuQaHIAWCly9+Cv70
t06Fi9ANeXiQExIn4IW+yyDfdVj/Mc80KGAu1KdC0k/yujNTqQKiJPYXkWeXHmyRo+ZtudBNrMW
BbJSgGRxI7q9tesIogPsaHQPKAp5rQEoFP83Y89ofBT/U4MKHf1UBNN8++AOAS1G31viYXhyTmL
0Nwa/xi0s0m7MmAtzrhcIi3tQ9ZwNiapzoMMK8o2BFJLkvrycpea6+uBt286yO/3oGuaEl7NEQV
GpW7Nhpcxk87DEGLyuHJiWN1+fQnE4TWeC4dTHp3nuVQLoX1Y7QRe9TjoMcje3Xx2xhx2QT6cSp
f3RcktexRSFj1xTW66fqKBdqlhNn+FH6Bc3Qk1X+vU7kEIPtIh7to=
X-Received: by 2002:a17:90b:3a10:b0:38e:70d5:b12d with SMTP id
98e67ed59e1d1-39261fbc353mr9787630a91.6.1786170044921;
Fri, 07 Aug 2026 23:20:44 -0700 (PDT)
Received: from lgs.. ([152.32.133.247])
by smtp.gmail.com with ESMTPSA id
98e67ed59e1d1-3925fc6dab4sm4996353a91.3.2026.08.07.23.20.41
(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
Fri, 07 Aug 2026 23:20:44 -0700 (PDT)
From: Guangshuo Li <lgs201920130244@gmail.com>
To: Chen-Yu Tsai <wens@kernel.org>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Samuel Holland <samuel@sholland.org>,
Guangshuo Li <lgs201920130244@gmail.com>,
Andrey Skvortsov <andrej.skvortzov@gmail.com>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Kees Cook <kees@kernel.org>,
Maxime Ripard <mripard@kernel.org>,
linux-arm-kernel@lists.infradead.org,
linux-sunxi@lists.linux.dev,
linux-kernel@vger.kernel.org
Cc: stable@vger.kernel.org
Subject: [PATCH] bus: sunxi-rsb: fix usage_count leak when autosuspend_delay
is negative
Date: Sat, 8 Aug 2026 14:20:29 +0800
Message-ID: <20260808062029.2597581-1-lgs201920130244@gmail.com>
X-Mailer: git-send-email 2.43.0
Precedence: bulk
X-Mailing-List: linux-sunxi@lists.linux.dev
List-Id: <linux-sunxi.lists.linux.dev>
List-Subscribe: <mailto:linux-sunxi+subscribe@lists.linux.dev>
List-Unsubscribe: <mailto:linux-sunxi+unsubscribe@lists.linux.dev>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-Rspamd-Server: rspamd-worker-8404
X-Spamd-Result: default: False [0.34 / 15.00];
BAYES_HAM(-5.50)[100.00%];
RBL_SENDERSCORE(2.00)[172.234.253.10:from];
SUSPICIOUS_RECIPS(1.50)[];
MID_CONTAINS_FROM(1.00)[];
DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed),
No valid DKIM,none];
R_MISSING_CHARSET(0.50)[];
MAILLIST(-0.15)[generic];
BAD_REP_POLICIES(0.10)[];
MIME_GOOD(-0.10)[text/plain];
HAS_LIST_UNSUB(-0.01)[];
FROM_HAS_DN(0.00)[];
FORGED_SENDER_MAILLIST(0.00)[];
PRECEDENCE_BULK(0.00)[];
DBL_BLOCKED_OPENRESOLVER(0.00)[sea.lore.kernel.org:rdns,sea.lore.kernel.org:helo];
TAGGED_RCPT(0.00)[];
RCPT_COUNT_TWELVE(0.00)[12];
RCVD_COUNT_FIVE(0.00)[6];
TAGGED_FROM(0.00)[bounces-25068-noreply=patchwork.local];
R_SPF_ALLOW(0.00)[+ip4:172.234.253.10];
FREEMAIL_TO(0.00)[kernel.org,gmail.com,sholland.org,linux.intel.com,lists.infradead.org,lists.linux.dev,vger.kernel.org];
FREEMAIL_FROM(0.00)[gmail.com];
TO_DN_SOME(0.00)[];
FROM_NEQ_ENVFROM(0.00)[lgs201920130244@gmail.com,linux-sunxi@lists.linux.dev];
FORGED_RECIPIENTS_MAILLIST(0.00)[];
RCVD_TLS_LAST(0.00)[];
MIME_TRACE(0.00)[0:+];
ASN(0.00)[asn:63949, ipnet:172.234.224.0/19, country:SG];
ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1];
RCVD_VIA_SMTP_AUTH(0.00)[]
X-Rspamd-Queue-Id: 316031C20AD
X-MORS-Enabled: yes
X-MORS-DOMAIN: patchwork.local
X-MORS-HOSTING: hosting172546
X-MORS-USER: hosting172546
X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?=
|
| Series |
bus: sunxi-rsb: fix usage_count leak when autosuspend_delay is negative
|
|
Commit Message
Guangshuo Li
Aug. 8, 2026, 6:20 a.m. UTC
sunxi_rsb_probe() calls pm_runtime_use_autosuspend(), but
sunxi_rsb_remove() does not call the matching
pm_runtime_dont_use_autosuspend() before disabling runtime PM.
If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during driver teardown, this reference is not dropped and usage_count
remains unbalanced.
Add the missing pm_runtime_dont_use_autosuspend() call before disabling
runtime PM.
This issue was found by manual code inspection.
Fixes: 4a0dbc12e618 ("bus: sunxi-rsb: Implement runtime power management")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/bus/sunxi-rsb.c | 1 +
1 file changed, 1 insertion(+)
Comments
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: Pre-existing issues: - [High] Clock enable count leak during system resume if the device was runtime-suspended. - [High] Division by zero if clock-frequency property is 0. - [High] Unclocked hardware access due to IRQ registration before clock enablement. - [High] Use-After-Free of child device `of_node` due to missing `of_node_get()`. - [High] Sleeping in atomic context within `.resume_noirq`. -- --- Patch [1]: [PATCH] bus: sunxi-rsb: fix usage_count leak when autosuspend_delay is negative --- commit 353b6956f11193cdddcc23fba6f083e34c249931 Author: Guangshuo Li <lgs201920130244@gmail.com> bus: sunxi-rsb: fix usage_count leak when autosuspend_delay is negative The patch adds pm_runtime_dont_use_autosuspend() in sunxi_rsb_remove() to fix a usage count leak when autosuspend delay is negative. > diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > index daf0ea563e477..cd4c857756cfa 100644 > --- a/drivers/bus/sunxi-rsb.c > +++ b/drivers/bus/sunxi-rsb.c [ ... ] > static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb, > struct device_node *node, u16 hwaddr, u8 rtaddr) > { [ ... ] > rdev->dev.bus = &sunxi_rsb_bus; > rdev->dev.parent = rsb->dev; > rdev->dev.of_node = node; > rdev->dev.release = sunxi_rsb_dev_release; [ ... ] > static int of_rsb_register_devices(struct sunxi_rsb *rsb) > { [ ... ] > for_each_available_child_of_node(np, child) { > struct sunxi_rsb_device *rdev; [ ... ] > rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr); [Severity: High] This isn't a bug introduced by this patch, but does this cause a use-after-free of the child device node? for_each_available_child_of_node() automatically drops the reference to the previous node on each iteration. Since sunxi_rsb_device_create() assigns it to rdev->dev.of_node without taking an extra reference via of_node_get(), the node could be freed when the loop advances. [ ... ] > static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) > { [ ... ] > /* reset the controller */ > writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL); > readl_poll_timeout(rsb->regs + RSB_CTRL, reg, > !(reg & RSB_CTRL_SOFT_RST), 1000, 100000); [ ... ] > static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = { > SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend, > sunxi_rsb_runtime_resume, NULL) > SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sunxi_rsb_suspend, sunxi_rsb_resume) > }; [Severity: High] This is a pre-existing issue, but does this sleep in an atomic context? sunxi_rsb_resume() is registered to run in the _noirq context via SET_NOIRQ_SYSTEM_SLEEP_PM_OPS, which executes with local interrupts disabled. However, it calls sunxi_rsb_hw_init(), which uses readl_poll_timeout() with a 1000us delay. This causes the macro to invoke usleep_range() and attempt to sleep in an atomic context, which will trigger a kernel panic during system resume. [ ... ] > static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) > { [ ... ] > p_clk_freq = clk_get_rate(rsb->clk); > clk_div = p_clk_freq / rsb->clk_freq / 2; [Severity: High] This is a pre-existing issue, but can this cause a division by zero exception? In sunxi_rsb_probe(), the clock-frequency from the device tree is checked against RSB_MAX_FREQ, but it's not checked for 0. If it is 0, the division p_clk_freq / rsb->clk_freq / 2 will trigger a division by zero panic. [ ... ] > static int __maybe_unused sunxi_rsb_runtime_resume(struct device *dev) > { > struct sunxi_rsb *rsb = dev_get_drvdata(dev); > > return clk_prepare_enable(rsb->clk); > } [ ... ] > static int __maybe_unused sunxi_rsb_resume(struct device *dev) > { > struct sunxi_rsb *rsb = dev_get_drvdata(dev); > > return sunxi_rsb_hw_init(rsb); > } [Severity: High] This isn't a bug introduced by this patch, but does this leak the clock enable count during system resume? If the device is runtime-suspended before a system suspend, sunxi_rsb_resume() calls sunxi_rsb_hw_init() which calls clk_prepare_enable(). Since it was runtime-suspended, a subsequent pm_runtime_resume_and_get() would call sunxi_rsb_runtime_resume() which enables the clock a second time, leaving the clock permanently enabled. [ ... ] > static int sunxi_rsb_probe(struct platform_device *pdev) > { [ ... ] > ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb); > if (ret) > return dev_err_probe(dev, ret, > "can't register interrupt handler irq %d\n", irq); > > ret = sunxi_rsb_hw_init(rsb); > if (ret) > return ret; [ ... ] > @@ -815,6 +815,7 @@ static void sunxi_rsb_remove(struct platform_device *pdev) > struct sunxi_rsb *rsb = platform_get_drvdata(pdev); > > device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices); > + pm_runtime_dont_use_autosuspend(&pdev->dev); > pm_runtime_disable(&pdev->dev); > sunxi_rsb_hw_exit(rsb); > } [Severity: High] This isn't a bug introduced by this patch, but can this lead to an unclocked hardware access? In sunxi_rsb_probe(), the IRQ handler is registered before sunxi_rsb_hw_init() enables the clock. If a pending interrupt triggers immediately upon request, sunxi_rsb_irq() could read memory-mapped registers while the clock is disabled. Similarly, in sunxi_rsb_remove() shown in the diff here, the hardware clock is disabled by sunxi_rsb_hw_exit(), but the devm-managed IRQ is still registered and active, creating another window where sunxi_rsb_irq() could execute after the clock is off.
On Sat, Aug 08, 2026 at 02:20:29PM +0800, Guangshuo Li wrote: > sunxi_rsb_probe() calls pm_runtime_use_autosuspend(), but > sunxi_rsb_remove() does not call the matching > pm_runtime_dont_use_autosuspend() before disabling runtime PM. > > If the autosuspend delay is set to a negative value while autosuspend > is enabled, the runtime PM core increments usage_count to prevent > runtime suspend. Without calling pm_runtime_dont_use_autosuspend() > during driver teardown, this reference is not dropped and usage_count > remains unbalanced. As I've explained elsewhere, this is just misleading. There is no usage count leak here as the count is balanced whenever the user re-enables autosuspend through sysfs (by writing a non-negative timeout). Drivers should clean up after themselves and disable autosuspend, but this is more of a clean up than a fix and should not be backported. You've sent upwards of 60 of these in the matter of just a few days, some of which have even been picked up. Please send follow-ups (replies or v2s) as soon as possible to prevent further of these from getting merged. > Add the missing pm_runtime_dont_use_autosuspend() call before disabling > runtime PM. > > This issue was found by manual code inspection. > > Fixes: 4a0dbc12e618 ("bus: sunxi-rsb: Implement runtime power management") > Cc: stable@vger.kernel.org > Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com> Johan
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index daf0ea563e47..cd4c857756cf 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -815,6 +815,7 @@ static void sunxi_rsb_remove(struct platform_device *pdev) struct sunxi_rsb *rsb = platform_get_drvdata(pdev); device_for_each_child(rsb->dev, NULL, sunxi_rsb_remove_devices); + pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev); sunxi_rsb_hw_exit(rsb); }