From: sashiko-bot@kernel.org
To: "James Hilliard" <james.hilliard1@gmail.com>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Richard Weinberger" <richard@nod.at>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"Brian Norris" <computersforpeace@gmail.com>,
"Boris Brezillon" <bbrezillon@kernel.org>,
"Arseniy Krasnov" <AVKrasnov@sberdevices.ru>,
"Chen-Yu Tsai" <wens@kernel.org>,
"Jernej Skrabec" <jernej.skrabec@gmail.com>,
"Samuel Holland" <samuel@sholland.org>,
"Thomas Gleixner" <tglx@kernel.org>,
"Vitaly Wool" <vitalywool@gmail.com>,
"David Woodhouse" <dwmw2@infradead.org>,
"Russell King" <rmk+kernel@arm.linux.org.uk>,
"David Woodhouse" <David.Woodhouse@intel.com>,
"Mike Rapoport" <rppt@kernel.org>,
"Maxime Coquelin" <mcoquelin.stm32@gmail.com>,
"Alexandre Torgue" <alexandre.torgue@foss.st.com>,
"Christophe Kerello" <christophe.kerello@st.com>,
"Jason Roberts" <jason.e.roberts@intel.com>,
"Michal Simek" <michal.simek@amd.com>,
"Boris Brezillon" <boris.brezillon@collabora.com>,
"Mason Yang" <masonccyang@mxic.com.tw>,
"Ramuthevar Vadivel Murugan"
<vadivel.muruganx.ramuthevar@linux.intel.com>,
"Stefan Agner" <stefan@agner.ch>, "Lucas Stach" <dev@lynxeye.de>,
"Thierry Reding" <thierry.reding@kernel.org>,
"Jonathan Hunter" <jonathanh@nvidia.com>,
"Dmitry Osipenko" <digetx@gmail.com>,
"Matthias Brugger" <matthias.bgg@gmail.com>,
"AngeloGioacchino Del Regno"
<angelogioacchino.delregno@collabora.com>,
"Jorge Ramirez-Ortiz" <jorge.ramirez@oss.qualcomm.com>,
"Heiko Stuebner" <heiko@sntech.de>,
"Yifeng Zhao" <yifeng.zhao@rock-chips.com>,
"Nicolas Ferre" <nicolas.ferre@microchip.com>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Claudiu Beznea" <claudiu.beznea@tuxon.dev>,
"Keguang Zhang" <keguang.zhang@gmail.com>,
"Jacky Huang" <ychuang3@nuvoton.com>,
"Shan-Chun Hung" <schung@nuvoton.com>,
"Frank Li" <Frank.Li@nxp.com>,
"Sascha Hauer" <s.hauer@pengutronix.de>,
"Pengutronix Kernel Team" <kernel@pengutronix.de>,
"Fabio Estevam" <festevam@gmail.com>, "Han Xu" <han.xu@nxp.com>,
"Liang Yang" <liang.yang@amlogic.com>,
"Neil Armstrong" <neil.armstrong@linaro.org>,
"Kevin Hilman" <khilman@baylibre.com>,
"Jerome Brunet" <jbrunet@baylibre.com>,
"Martin Blumenstingl" <martin.blumenstingl@googlemail.com>,
"Manivannan Sadhasivam" <mani@kernel.org>,
"Kamal Dasu" <kamal.dasu@broadcom.com>,
"Broadcom internal kernel review list"
<bcm-kernel-feedback-list@broadcom.com>,
"Vladimir Zapolskiy" <vz@mleia.com>,
"Piotr Wojtaszczyk" <piotr.wojtaszczyk@timesys.com>,
"Paul Cercueil" <paul@crapouillou.net>,
"Harvey Hunt" <harveyhuntnexus@gmail.com>,
"Maxim Levitsky" <maximlevitsky@gmail.com>,
"Michael Walle" <michael@walle.cc>,
"Srinivas Kandagatla" <srini@kernel.org>
Cc: "Tze Yee Ng" <tze.yee.ng@altera.com>,
linux-mtd@lists.infradead.org, linux-sunxi@lists.linux.dev,
imx@lists.linux.dev, linux-amlogic@lists.infradead.org,
Frank.Li@kernel.org, wsa+renesas@sang-engineering.com
Subject: Re: [PATCH 03/58] mtd: add opt-in lifetime ownership for backing objects
Date: Sat, 07 Nov 2026 20:50:21 +0000 [thread overview]
Message-ID: <sashiko-outbox-203330@kernel.org> (raw)
In-Reply-To: <20261107-submit-rawnand-retained-handle-lifetime-v1-v1-3-0181ef0cc4c8@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] mtd: refcount imbalance in __put_mtd_device() when
master->dev.type changes
- [Medium] mtd: mtd_add_partition() allows adding partitions to an
unregistered master
- [Medium] mtd: add_mtd_device() leaves mtd->dev.type set when
dev_set_name() fails
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [Critical] mtd: core: use-after-free in add_mtd_device() [1]
--
commit da12394511d438335fb25ce60156c3307163ed8f
Author: James Hilliard <james.hilliard1@gmail.com>
mtd: add opt-in lifetime ownership for backing objects
This commit introduces opt-in reference-counted lifetime management for
master MTD backing objects via mtd_set_release() and mtd_put_master(),
retaining the master and partition hierarchy while MTD handles, device
nodes, or OTP NVMEM providers remain active.
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 558a605ba7495..42c06a02cd99d 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
[ ... ]
> @@ -748,16 +840,28 @@ int add_mtd_device(struct mtd_info *mtd)
[ ... ]
> mtd->index = i;
> kref_init(&mtd->refcnt);
> + if (master->master.release) {
> + mtd_get_lifetime(master);
> + mtd->ref_master = master;
> + if (mtd->parent && mtd->parent != master)
> + get_device(&mtd->parent->dev);
> + }
[Severity: Medium]
Can a partition still be added through mtd_add_partition() after the
parent or master has been unregistered?
If a process keeps an open file descriptor to /dev/mtd0 across driver
unbind (mtd_device_unregister() and mtd_put_master()) and issues
BLKPG_ADD_PARTITION, mtdchar_blkpg_ioctl() -> mtd_add_partition() calls
add_mtd_device(child) without checking whether parent->registered is still
true. Because del_mtd_partitions() has already run, the new partition is
never cleaned up, leaking the partition, its MTD ID, THIS_MODULE, and
master.life_refcnt. Furthermore, once the open handle on the managed
master is closed, mtd_device_release() leaves master->dev.type set, so
opening and closing the leaked child partition will do kref_get() on a
zero master->refcnt and call mtd_device_release() a second time.
> @@ -839,29 +946,38 @@ int add_mtd_device(struct mtd_info *mtd)
> }
> }
>
> - /* We _know_ we aren't being removed, because
> - our caller is still holding us here. So none
> - of this try_ nonsense, and no bitching about it
> - either. :) */
> - __module_get(THIS_MODULE);
> return 0;
>
> fail_nvmem_add:
> device_del(&mtd->dev);
> fail_added:
> /*
> - * Clear type and set nop release to prevent mtd_release() ->
> + * Clear type and override release to prevent mtd_release() ->
> * release_mtd_partition() -> free_partition() from freeing mtd.
> * The caller handles cleanup on failure.
> */
> mtd->dev.type = NULL;
> - mtd->dev.release = mtd_dev_release_nop;
> + mtd->dev.release = mtd_dev_release_done;
> + dev_set_drvdata(&mtd->dev, &released);
> + wait_for_release = true;
> put_device(&mtd->dev);
> of_node_put(mtd_get_of_node(mtd));
> fail_devname:
> idr_remove(&mtd_idr, i);
> + ida_free(&mtd_ids, i);
> + if (mtd->ref_master) {
> + mtd->ref_master = NULL;
> + if (mtd->parent && mtd->parent != master)
> + put_device(&mtd->parent->dev);
> + mtd_put_lifetime(master);
> + }
[Severity: Critical]
This problem wasn't introduced by this patch, but can add_mtd_device()
trigger a use-after-free on the device_node [1] when
mtd_check_of_node() matches a partition node?
drivers/mtd/mtdcore.c:mtd_check_of_node() {
...
if (plen == mtd_name_len &&
!strncmp(mtd->name, pname + offset, plen)) {
mtd_set_of_node(mtd, mtd_dn);
of_node_put(mtd_dn);
break;
}
...
}
mtd_check_of_node() stores mtd_dn in mtd and immediately drops its
reference via of_node_put(mtd_dn) before add_mtd_device() calls
of_node_get(mtd_get_of_node(mtd)). In a dynamic DT environment, if the
node is removed in that window, of_node_put() frees mtd_dn and
of_node_get() dereferences freed memory.
[Severity: Medium]
Does jumping to fail_devname when dev_set_name() fails leave mtd->dev.type
set to &mtd_devtype?
mtd->dev.type is assigned right before dev_set_name(), and clearing it only
happens under fail_added. Leaving mtd->dev.type non-NULL causes any retry
of add_mtd_device() to fail at WARN_ONCE(mtd->dev.type, ...), and causes
__put_mtd_device() on an open partition to call kref_put(&master->refcnt,
mtd_device_release) on a master whose struct device was never registered.
[ ... ]
> @@ -1348,13 +1484,14 @@ int __get_mtd_device(struct mtd_info *mtd)
> return -ENODEV;
> }
>
> + mtd_get_lifetime(master);
> while (mtd) {
> if (mtd != master)
> kref_get(&mtd->refcnt);
> mtd = mtd->parent;
> }
>
> - if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> + if (master->dev.type)
> kref_get(&master->refcnt);
>
> return 0;
> @@ -1441,6 +1578,7 @@ void __put_mtd_device(struct mtd_info *mtd)
> struct mtd_info *master = mtd_get_master(mtd);
> /* master can be freed in _put_device */
> struct module *owner = master->owner;
> + bool managed = master->master.release;
>
> while (mtd) {
> /* kref_put() can relese mtd, so keep a reference mtd->parent */
> @@ -1451,12 +1589,14 @@ void __put_mtd_device(struct mtd_info *mtd)
> mtd = parent;
> }
>
> - if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
> + if (master->dev.type)
> kref_put(&master->refcnt, mtd_device_release);
[Severity: Medium]
Can master->dev.type change from NULL to non-NULL between
__get_mtd_device() and __put_mtd_device(), causing an unmatched
kref_put(&master->refcnt, mtd_device_release)?
When CONFIG_MTD_PARTITIONED_MASTER=n, master->dev.type is NULL while
mtd_device_parse_register() runs parse_mtd_partitions(). If a first
partition is registered and opened by a notifier or userspace (seeing
master->dev.type == NULL in __get_mtd_device()), and a later partition
fails to register in add_mtd_partitions(), del_mtd_partitions() unregisters
the first partition while it remains open:
drivers/mtd/mtdcore.c:mtd_device_parse_register() {
...
ret = parse_mtd_partitions(mtd, types, parser_data);
if (ret == -EPROBE_DEFER)
goto out;
if (ret > 0)
ret = 0;
else if (nr_parts)
ret = add_mtd_partitions(mtd, parts, nr_parts);
else if (!device_is_registered(&mtd->dev))
ret = add_mtd_device(mtd);
...
}
When nr_parts == 0 and parse_mtd_partitions() returns a non-defer error,
mtd_device_parse_register() falls back to add_mtd_device(mtd), which sets
master->dev.type = &mtd_devtype and initializes master->refcnt to 1.
Closing the open partition handle then sees master->dev.type != NULL in
__put_mtd_device() and drops master->refcnt to 0 while the master is still
registered.
[1] https://sashiko.dev/#/bug/linux-11fdb383-132f-473b-9284-101b4753fcd6
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261107-submit-rawnand-retained-handle-lifetime-v1-v1-0-0181ef0cc4c8@gmail.com?part=3
_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic
next prev parent reply other threads:[~2026-11-07 20:50 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 10:15 [PATCH 00/58] mtd: rawnand: retain chip and controller state across removal James Hilliard
2026-11-07 10:15 ` [PATCH 01/58] mtd: clear OTP provider pointers after unregistering them James Hilliard
2026-11-07 20:21 ` sashiko-bot
2026-11-07 10:15 ` [PATCH 02/58] nvmem: retain provider context through final device release James Hilliard
2026-11-07 20:26 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 03/58] mtd: add opt-in lifetime ownership for backing objects James Hilliard
2026-11-07 20:50 ` sashiko-bot [this message]
2026-11-07 10:16 ` [PATCH 04/58] mtd: rawnand: separate hardware disconnection from cleanup James Hilliard
2026-11-07 20:42 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 05/58] mtd: rawnand: share retained chip and controller ownership James Hilliard
2026-11-07 10:16 ` [PATCH 06/58] mtd: rawnand: macronix: serialize OTP access with NAND operations James Hilliard
2026-11-07 10:16 ` [PATCH 07/58] mtd: rawnand: sunxi: retain chip state until the final MTD put James Hilliard
2026-11-07 10:16 ` [PATCH 08/58] mtd: rawnand: plat_nand: retain open-handle state on removal James Hilliard
2026-11-07 10:16 ` [PATCH 09/58] mtd: rawnand: gpio: " James Hilliard
2026-11-07 10:16 ` [PATCH 10/58] mtd: rawnand: stm32_fmc2: " James Hilliard
2026-11-07 10:16 ` [PATCH 11/58] mtd: rawnand: denali: retain chips across controller removal James Hilliard
2026-11-07 20:25 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 12/58] mtd: rawnand: arasan: " James Hilliard
2026-11-07 10:16 ` [PATCH 13/58] mtd: rawnand: mxic: retain open-handle state on removal James Hilliard
2026-11-07 10:16 ` [PATCH 14/58] mtd: rawnand: intel: " James Hilliard
2026-11-07 20:31 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 15/58] mtd: rawnand: tegra: " James Hilliard
2026-11-07 20:32 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 16/58] mtd: rawnand: mtk: retain chips across controller removal James Hilliard
2026-11-07 10:16 ` [PATCH 17/58] mtd: rawnand: rockchip: " James Hilliard
2026-11-07 10:16 ` [PATCH 18/58] mtd: rawnand: atmel: " James Hilliard
2026-11-07 20:31 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 19/58] mtd: rawnand: orion: retain open-handle state on removal James Hilliard
2026-11-07 20:29 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 20/58] mtd: rawnand: socrates: " James Hilliard
2026-11-07 10:16 ` [PATCH 21/58] mtd: rawnand: fsl_upm: " James Hilliard
2026-11-07 10:16 ` [PATCH 22/58] mtd: rawnand: pasemi: " James Hilliard
2026-11-07 10:16 ` [PATCH 23/58] mtd: rawnand: ams-delta: " James Hilliard
2026-11-07 10:16 ` [PATCH 24/58] mtd: rawnand: xway: " James Hilliard
2026-11-07 10:16 ` [PATCH 27/58] mtd: rawnand: technologic: " James Hilliard
2026-11-07 10:16 ` [PATCH 28/58] mtd: rawnand: loongson: " James Hilliard
2026-11-07 10:16 ` [PATCH 29/58] mtd: rawnand: ma35d1: " James Hilliard
2026-11-07 10:16 ` [PATCH 30/58] mtd: rawnand: pl35x: " James Hilliard
2026-11-07 10:16 ` [PATCH 31/58] mtd: rawnand: mxc: " James Hilliard
2026-11-07 10:16 ` [PATCH 32/58] mtd: rawnand: fsmc: " James Hilliard
2026-11-07 10:16 ` [PATCH 33/58] mtd: rawnand: gpmi: " James Hilliard
2026-11-07 10:16 ` [PATCH 34/58] mtd: rawnand: omap2: " James Hilliard
2026-11-07 10:16 ` [PATCH 35/58] mtd: rawnand: marvell: " James Hilliard
2026-11-07 10:16 ` [PATCH 36/58] mtd: rawnand: renesas: " James Hilliard
2026-11-07 10:16 ` [PATCH 37/58] mtd: rawnand: meson: " James Hilliard
2026-11-07 10:16 ` [PATCH 38/58] mtd: rawnand: cadence: " James Hilliard
2026-11-07 10:16 ` [PATCH 39/58] mtd: rawnand: qcom: " James Hilliard
2026-11-07 20:47 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 40/58] mtd: rawnand: cafe: " James Hilliard
2026-11-07 10:16 ` [PATCH 41/58] mtd: rawnand: brcmnand: " James Hilliard
2026-11-07 10:16 ` [PATCH 42/58] mtd: rawnand: au1550nd: retain chip state across removal James Hilliard
2026-11-07 20:44 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 43/58] mtd: rawnand: sharpsl: " James Hilliard
2026-11-07 10:16 ` [PATCH 44/58] mtd: rawnand: davinci: " James Hilliard
2026-11-07 10:16 ` [PATCH 45/58] mtd: rawnand: sh_flctl: " James Hilliard
2026-11-07 10:16 ` [PATCH 46/58] mtd: rawnand: lpc32xx_slc: " James Hilliard
2026-11-07 10:16 ` [PATCH 47/58] mtd: rawnand: lpc32xx_mlc: " James Hilliard
2026-11-07 10:16 ` [PATCH 48/58] mtd: rawnand: ndfc: " James Hilliard
2026-11-07 10:16 ` [PATCH 49/58] mtd: rawnand: txx9ndfmc: " James Hilliard
2026-11-07 10:16 ` [PATCH 50/58] mtd: rawnand: ingenic: " James Hilliard
2026-11-07 10:16 ` [PATCH 51/58] mtd: rawnand: mpc5121: " James Hilliard
2026-11-07 20:48 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 52/58] mtd: rawnand: bcm47xxnflash: " James Hilliard
2026-11-07 10:16 ` [PATCH 53/58] mtd: rawnand: fsl_elbc: " James Hilliard
2026-11-07 10:16 ` [PATCH 54/58] mtd: rawnand: fsl_ifc: " James Hilliard
2026-11-07 10:16 ` [PATCH 55/58] mtd: rawnand: r852: " James Hilliard
2026-11-07 20:59 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 56/58] mtd: rawnand: nandsim: " James Hilliard
2026-11-07 20:52 ` sashiko-bot
2026-11-07 10:16 ` [PATCH 57/58] mtd: rawnand: cs553x: " James Hilliard
2026-11-07 10:16 ` [PATCH 58/58] mtd: rawnand: diskonchip: " James Hilliard
2026-11-07 19:33 ` [PATCH 25/58] mtd: rawnand: hisi504: retain open-handle state on removal James Hilliard
2026-11-07 19:33 ` [PATCH 26/58] mtd: rawnand: vf610: " James Hilliard
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=sashiko-outbox-203330@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=AVKrasnov@sberdevices.ru \
--cc=David.Woodhouse@intel.com \
--cc=Frank.Li@kernel.org \
--cc=Frank.Li@nxp.com \
--cc=alexandre.belloni@bootlin.com \
--cc=alexandre.torgue@foss.st.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=bbrezillon@kernel.org \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=boris.brezillon@collabora.com \
--cc=christophe.kerello@st.com \
--cc=claudiu.beznea@tuxon.dev \
--cc=computersforpeace@gmail.com \
--cc=dev@lynxeye.de \
--cc=digetx@gmail.com \
--cc=dwmw2@infradead.org \
--cc=festevam@gmail.com \
--cc=han.xu@nxp.com \
--cc=harveyhuntnexus@gmail.com \
--cc=heiko@sntech.de \
--cc=imx@lists.linux.dev \
--cc=james.hilliard1@gmail.com \
--cc=jason.e.roberts@intel.com \
--cc=jbrunet@baylibre.com \
--cc=jernej.skrabec@gmail.com \
--cc=jonathanh@nvidia.com \
--cc=jorge.ramirez@oss.qualcomm.com \
--cc=kamal.dasu@broadcom.com \
--cc=keguang.zhang@gmail.com \
--cc=kernel@pengutronix.de \
--cc=khilman@baylibre.com \
--cc=liang.yang@amlogic.com \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=mani@kernel.org \
--cc=martin.blumenstingl@googlemail.com \
--cc=masonccyang@mxic.com.tw \
--cc=matthias.bgg@gmail.com \
--cc=maximlevitsky@gmail.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=michael@walle.cc \
--cc=michal.simek@amd.com \
--cc=miquel.raynal@bootlin.com \
--cc=neil.armstrong@linaro.org \
--cc=nicolas.ferre@microchip.com \
--cc=paul@crapouillou.net \
--cc=piotr.wojtaszczyk@timesys.com \
--cc=richard@nod.at \
--cc=rmk+kernel@arm.linux.org.uk \
--cc=rppt@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=samuel@sholland.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=schung@nuvoton.com \
--cc=srini@kernel.org \
--cc=stefan@agner.ch \
--cc=tglx@kernel.org \
--cc=thierry.reding@kernel.org \
--cc=tze.yee.ng@altera.com \
--cc=vadivel.muruganx.ramuthevar@linux.intel.com \
--cc=vigneshr@ti.com \
--cc=vitalywool@gmail.com \
--cc=vz@mleia.com \
--cc=wens@kernel.org \
--cc=wsa+renesas@sang-engineering.com \
--cc=ychuang3@nuvoton.com \
--cc=yifeng.zhao@rock-chips.com \
/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
all inboxes | Powered by JetHome®