public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Felix Gu <gu_0233@qq.com>,
	Romain Gantois <romain.gantois@bootlin.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Sasha Levin <sashal@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-6.18] misc: ti_fpc202: fix a potential memory leak in probe function
Date: Wed, 18 Feb 2026 21:04:17 -0500	[thread overview]
Message-ID: <20260219020422.1539798-41-sashal@kernel.org> (raw)
In-Reply-To: <20260219020422.1539798-1-sashal@kernel.org>

From: Felix Gu <gu_0233@qq.com>

[ Upstream commit dad9f13d967b4e53e8eaf5f9c690f8e778ad9802 ]

Use for_each_child_of_node_scoped() to simplify the code and ensure the
device node reference is automatically released when the loop scope
ends.

Signed-off-by: Felix Gu <gu_0233@qq.com>
Reviewed-by: Romain Gantois <romain.gantois@bootlin.com>
Link: https://patch.msgid.link/tencent_FA1AC670F5CF49873F88A44424F866994A08@qq.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Good - `for_each_child_of_node_scoped()` was introduced before v6.15, so
it's available in all stable trees that have this driver.

## Analysis Summary

### What problem the commit solves

The `for_each_child_of_node()` macro takes a reference on each child
device node during iteration. When the loop exits early via `goto
unregister_chans` (which happens on three separate error paths at lines
367, 373, and 379), the reference on `i2c_handle` is never released
because there's no `of_node_put(i2c_handle)` call before the `goto`.
This causes a device_node reference count leak each time probe fails
during child iteration.

The fix is clean and well-established: switching to
`for_each_child_of_node_scoped()` which uses cleanup attributes to
automatically release the reference when the variable goes out of scope,
regardless of how the loop exits.

### Does it meet stable kernel rules?

1. **Obviously correct and tested**: Yes - reviewed by the subsystem
   reviewer (Romain Gantois), well-known pattern, minimal change.
2. **Fixes a real bug**: Yes - reference count leak on device_node
   objects during probe failure.
3. **Important issue**: This is a resource leak. While it only triggers
   on probe errors (not in a hot path), it's a genuine bug that leaks
   kernel memory. It's a minor resource leak rather than a critical
   issue.
4. **Small and contained**: Yes - one line changed plus removal of one
   variable declaration.
5. **No new features**: Correct - purely a bug fix.

### Risk vs Benefit

- **Risk**: Extremely low. The `for_each_child_of_node_scoped()` macro
  is a well-tested, widely-used pattern across the kernel. The change is
  minimal.
- **Benefit**: Fixes a real resource leak, though it only triggers on
  error paths during probe.

### Concerns

- The driver was only introduced in v6.16, so it only applies to very
  recent stable trees.
- The bug only triggers on probe failure, so user impact is relatively
  low - most users with working hardware would never hit this.
- This is a minor resource leak (not a crash, corruption, or security
  issue).

### Verdict

This is a legitimate bug fix - a device_node reference count leak on
probe error paths. The fix is minimal, obviously correct, and uses a
well-established pattern. However, the practical impact is low: it only
affects an obscure driver (TI FPC202 dual port controller) and only
triggers during probe failures. The leak is a few bytes of memory per
failed probe attempt, not in a hot path.

While the fix is technically correct and meets stable criteria for being
small and fixing a real bug, the overall user impact is minimal. The
driver itself is very new (v6.16) and the leak only triggers on error
paths. This is the kind of fix that is nice to have but not critical for
stable users.

Given that it does fix a real (if minor) bug, is reviewed, minimal in
scope, and has essentially zero regression risk, it meets the stable
criteria.

## Verification

- **Read the file**: Confirmed the `for_each_child_of_node()` loop at
  line 360 with three `goto unregister_chans` early exits (lines 367,
  373, 379) none of which call `of_node_put()`.
- **Driver introduction**: `git log --diff-filter=A` confirmed driver
  was added in commit 1e5c9b1efa1c3; `git merge-base --is-ancestor`
  confirmed it's in v6.16 but not v6.15.
- **Scoped macro availability**: `git log -S` found it was introduced in
  commit 34af4554fb0ce; `git merge-base --is-ancestor` confirmed it's
  available since before v6.15, so it's present in all stable trees that
  have this driver.
- **Patch correctness**: The `for_each_child_of_node_scoped()` pattern
  is a well-known and widely used approach for fixing this exact class
  of bug throughout the kernel.

**YES**

 drivers/misc/ti_fpc202.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/misc/ti_fpc202.c b/drivers/misc/ti_fpc202.c
index 7964e46c74482..8eb2b5ac98506 100644
--- a/drivers/misc/ti_fpc202.c
+++ b/drivers/misc/ti_fpc202.c
@@ -309,7 +309,6 @@ static void fpc202_remove_port(struct fpc202_priv *priv, int port_id)
 static int fpc202_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
-	struct device_node *i2c_handle;
 	struct fpc202_priv *priv;
 	int ret, port_id;
 
@@ -357,7 +356,7 @@ static int fpc202_probe(struct i2c_client *client)
 
 	bitmap_zero(priv->probed_ports, FPC202_NUM_PORTS);
 
-	for_each_child_of_node(dev->of_node, i2c_handle) {
+	for_each_child_of_node_scoped(dev->of_node, i2c_handle) {
 		ret = of_property_read_u32(i2c_handle, "reg", &port_id);
 		if (ret) {
 			if (ret == -EINVAL)
-- 
2.51.0


      parent reply	other threads:[~2026-02-19  2:05 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-19  2:03 [PATCH AUTOSEL 6.19] rust_binder: Fix build failure if !CONFIG_COMPAT Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] usb: chipidea: udc: fix DMA and SG cleanup in _ep_nuke() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] staging: rtl8723bs: fix memory leak on failure path Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] tty: vt/keyboard: Split apart vt_do_diacrit() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] fix it87_wdt early reboot by reporting running timer Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] misc: eeprom: Fix EWEN/EWDS/ERAL commands for 93xx56 and 93xx66 Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.15] mmc: rtsx_pci: add quirk to disable MMC_CAP_AGGRESSIVE_PM for RTS525A Sasha Levin
2026-02-19 10:29   ` Ulf Hansson
2026-02-26 13:23     ` Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] fpga: of-fpga-region: Fail if any bridge is missing Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] soundwire: intel_auxdevice: add cs42l45 codec to wake_capable_list Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] iio: magnetometer: Remove IRQF_ONESHOT Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] watchdog: imx7ulp_wdt: handle the nowayout option Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] serial: 8250_dw: handle clock enable errors in runtime_resume Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] most: core: fix resource leak in most_register_interface error paths Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] block: fix partial IOVA mapping cleanup in blk_rq_dma_map_iova Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] misc: bcm_vk: Fix possible null-pointer dereferences in bcm_vk_read() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] dmaengine: sun6i: Choose appropriate burst length under maxburst Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.1] mmc: rtsx: reset power state on suspend Sasha Levin
2026-02-19 10:27   ` Ulf Hansson
2026-02-26 13:24     ` Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19] serial: rsci: Add set_rtrg() callback Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-5.10] Revert "mfd: da9052-spi: Change read-mask to write-mask" Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.18] pinctrl: mediatek: make devm allocations safer and clearer in mtk_eint_do_init() Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] serial: 8250: 8250_omap.c: Add support for handling UART error conditions Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] usb: gadget: f_fs: Fix ioctl error handling Sasha Levin
2026-02-19  2:03 ` [PATCH AUTOSEL 6.19-6.12] phy: cadence-torrent: restore parent clock for refclk during resume Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] binder: don't use %pK through printk Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] iio: bmi270_i2c: Add MODULE_DEVICE_TABLE for BMI260/270 Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] iio: Use IRQF_NO_THREAD Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] mfd: intel-lpss: Add Intel Nova Lake-S PCI IDs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] phy: ti: phy-j721e-wiz: restore mux selection during resume Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] MIPS: Loongson: Make cpumask_of_node() robust against NUMA_NO_NODE Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] usb: gadget: f_fs: fix DMA-BUF OUT queues Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] phy: fsl-imx8mq-usb: disable bind/unbind platform driver feature Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] watchdog: rzv2h_wdt: Discard pm_runtime_put() return value Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] soundwire: dmi-quirks: add mapping for Avell B.ON (OEM rebranded of NUC15) Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.18] pinctrl: renesas: rzt2h: Allow .get_direction() for IRQ function GPIOs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.12] dmaengine: stm32-dma3: use module_platform_driver Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] staging: rtl8723bs: fix missing status update on sdio_alloc_irq() failure Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.15] phy: mvebu-cp110-utmi: fix dr_mode property read from dts Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] usb: typec: ucsi: psy: Fix voltage and current max for non-Fixed PDOs Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-5.10] serial: 8250: 8250_omap.c: Clear DMA RX running status only after DMA termination is done Sasha Levin
2026-02-19  2:04 ` [PATCH AUTOSEL 6.19-6.1] dmaengine: stm32-mdma: initialize m2m_hw_period and ccr to fix warnings Sasha Levin
2026-02-19  2:04 ` Sasha Levin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260219020422.1539798-41-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=gu_0233@qq.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=romain.gantois@bootlin.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox