* FAILED: patch "[PATCH] i2c: core: fix adapter registration race" failed to apply to 5.15-stable tree
@ 2026-07-02 13:53 gregkh
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
0 siblings, 1 reply; 6+ messages in thread
From: gregkh @ 2026-07-02 13:53 UTC (permalink / raw)
To: johan, wsa+renesas; +Cc: stable
The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x ba14d7cf2fe7284610a29854bdff22b2537d3ce6
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026070232-opal-musky-5819@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ba14d7cf2fe7284610a29854bdff22b2537d3ce6 Mon Sep 17 00:00:00 2001
From: Johan Hovold <johan@kernel.org>
Date: Mon, 11 May 2026 16:37:12 +0200
Subject: [PATCH] i2c: core: fix adapter registration race
Adapters can be looked up based on their id using i2c_get_adapter()
which takes a reference to the embedded struct device.
Make sure that the adapter (including its struct device) has been
initialised before adding it to the IDR to avoid accessing uninitialised
data which could, for example, lead to NULL-pointer dereferences or
use-after-free.
Note that the i2c-dev chardev, which is registered from a bus notifier,
currently uses i2c_get_adapter() so the adapter needs to be added to the
IDR before registration.
Fixes: 6e13e6418418 ("i2c: Add i2c_add_numbered_adapter()")
Cc: stable@vger.kernel.org # 2.6.22
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index fdf7d7d50f79..01a984d3ca0e 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1580,6 +1580,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
+ mutex_lock(&core_lock);
+ idr_replace(&i2c_adapter_idr, adap, adap->nr);
+ mutex_unlock(&core_lock);
+
res = device_add(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
@@ -1638,7 +1642,7 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
int id;
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
+ id = idr_alloc(&i2c_adapter_idr, NULL, adap->nr, adap->nr + 1, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
return id == -ENOSPC ? -EBUSY : id;
@@ -1672,7 +1676,7 @@ int i2c_add_adapter(struct i2c_adapter *adapter)
}
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adapter,
+ id = idr_alloc(&i2c_adapter_idr, NULL,
__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure
2026-07-02 13:53 FAILED: patch "[PATCH] i2c: core: fix adapter registration race" failed to apply to 5.15-stable tree gregkh
@ 2026-07-05 14:00 ` Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 2/5] i2c: core: fix hang " Sasha Levin
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-05 14:00 UTC (permalink / raw)
To: stable; +Cc: Johan Hovold, Benjamin Tissoires, Wolfram Sang, Sasha Levin
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 8ce19524e4cc2462685f596a6402fbd8fb984ab2 ]
Make sure to tear down the host notify irq domain on adapter
registration failure to avoid leaking it.
This issue was flagged by Sashiko when reviewing another adapter
registration fix.
Fixes: 4d5538f5882a ("i2c: use an IRQ to report Host Notify events, not alert")
Cc: stable@vger.kernel.org # 4.10
Cc: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 265b7f7f38c6eb..3761c922d01fff 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1554,7 +1554,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
res = device_register(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
- goto out_list;
+ goto err_remove_irq_domain;
}
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
@@ -1601,6 +1601,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
wait_for_completion(&adap->dev_released);
+err_remove_irq_domain:
+ i2c_host_notify_irq_teardown(adap);
out_list:
mutex_lock(&core_lock);
idr_remove(&i2c_adapter_idr, adap->nr);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 2/5] i2c: core: fix hang on adapter registration failure
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
@ 2026-07-05 14:00 ` Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 3/5] i2c: core: fix NULL-deref " Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-05 14:00 UTC (permalink / raw)
To: stable; +Cc: Johan Hovold, Phil Reid, Wolfram Sang, Sasha Levin
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 3c7e164344e5bcf6f274bbf59a3274f5caad9bc1 ]
Clients may be registered from bus notifier callbacks when the adapter
is registered. On a subsequent error during registration, the adapter
references taken by such clients prevent the wait for the references to
be released from ever completing.
Fix this by refactoring client deregistration and deregistering also on
late adapter registration failures.
Fixes: f8756c67b3de ("i2c: core: call of_i2c_setup_smbus_alert in i2c_register_adapter")
Cc: stable@vger.kernel.org # 4.15
Cc: Phil Reid <preid@electromag.com.au>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 49 ++++++++++++++++++++++---------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 3761c922d01fff..8bf8d395807f6f 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -62,6 +62,7 @@
static DEFINE_MUTEX(core_lock);
static DEFINE_IDR(i2c_adapter_idr);
+static void i2c_deregister_clients(struct i2c_adapter *adap);
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key);
@@ -1597,6 +1598,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
return 0;
out_reg:
+ i2c_deregister_clients(adap);
debugfs_remove_recursive(adap->debugfs);
init_completion(&adap->dev_released);
device_unregister(&adap->dev);
@@ -1740,29 +1742,10 @@ static int __process_removed_adapter(struct device_driver *d, void *data)
return 0;
}
-/**
- * i2c_del_adapter - unregister I2C adapter
- * @adap: the adapter being unregistered
- * Context: can sleep
- *
- * This unregisters an I2C adapter which was previously registered
- * by @i2c_add_adapter or @i2c_add_numbered_adapter.
- */
-void i2c_del_adapter(struct i2c_adapter *adap)
+static void i2c_deregister_clients(struct i2c_adapter *adap)
{
- struct i2c_adapter *found;
struct i2c_client *client, *next;
- /* First make sure that this adapter was ever added */
- mutex_lock(&core_lock);
- found = idr_find(&i2c_adapter_idr, adap->nr);
- mutex_unlock(&core_lock);
- if (found != adap) {
- pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
- return;
- }
-
- i2c_acpi_remove_space_handler(adap);
/* Tell drivers about this removal */
mutex_lock(&core_lock);
bus_for_each_drv(&i2c_bus_type, NULL, adap,
@@ -1788,6 +1771,32 @@ void i2c_del_adapter(struct i2c_adapter *adap)
* them up properly, so we give them a chance to do that first. */
device_for_each_child(&adap->dev, NULL, __unregister_client);
device_for_each_child(&adap->dev, NULL, __unregister_dummy);
+}
+
+/**
+ * i2c_del_adapter - unregister I2C adapter
+ * @adap: the adapter being unregistered
+ * Context: can sleep
+ *
+ * This unregisters an I2C adapter which was previously registered
+ * by @i2c_add_adapter or @i2c_add_numbered_adapter.
+ */
+void i2c_del_adapter(struct i2c_adapter *adap)
+{
+ struct i2c_adapter *found;
+
+ /* First make sure that this adapter was ever added */
+ mutex_lock(&core_lock);
+ found = idr_find(&i2c_adapter_idr, adap->nr);
+ mutex_unlock(&core_lock);
+ if (found != adap) {
+ pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name);
+ return;
+ }
+
+ i2c_acpi_remove_space_handler(adap);
+
+ i2c_deregister_clients(adap);
#ifdef CONFIG_I2C_COMPAT
class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 3/5] i2c: core: fix NULL-deref on adapter registration failure
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 2/5] i2c: core: fix hang " Sasha Levin
@ 2026-07-05 14:00 ` Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 4/5] i2c: core: fix adapter debugfs creation Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 5/5] i2c: core: fix adapter registration race Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-05 14:00 UTC (permalink / raw)
To: stable; +Cc: Johan Hovold, Joe Hattori, Wolfram Sang, Sasha Levin
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 2295d2bb101faa663fbc45fadbb3fec45f107441 ]
If adapter registration ever fails the release callback would trigger a
NULL-pointer dereference as the completion struct has not been
initialised.
Note that before the offending commit this would instead have resulted
in a minor memory leak of the adapter name.
Fixes: 3f8c4f5e9a57 ("i2c: core: fix reference leak in i2c_register_adapter()")
Cc: stable@vger.kernel.org
Cc: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 8bf8d395807f6f..899c7310c77423 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1555,7 +1555,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
res = device_register(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
- goto err_remove_irq_domain;
+ goto err_put_adap;
}
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
@@ -1600,10 +1600,12 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
out_reg:
i2c_deregister_clients(adap);
debugfs_remove_recursive(adap->debugfs);
+ device_del(&adap->dev);
+err_put_adap:
init_completion(&adap->dev_released);
- device_unregister(&adap->dev);
+ put_device(&adap->dev);
wait_for_completion(&adap->dev_released);
-err_remove_irq_domain:
+
i2c_host_notify_irq_teardown(adap);
out_list:
mutex_lock(&core_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 4/5] i2c: core: fix adapter debugfs creation
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 2/5] i2c: core: fix hang " Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 3/5] i2c: core: fix NULL-deref " Sasha Levin
@ 2026-07-05 14:00 ` Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 5/5] i2c: core: fix adapter registration race Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-05 14:00 UTC (permalink / raw)
To: stable; +Cc: Johan Hovold, Wolfram Sang, Sasha Levin
From: Johan Hovold <johan@kernel.org>
[ Upstream commit 07d5fb537928aad4369aaff0cbae73ba38a719af ]
Clients can be registered from bus notifier callbacks so the debugfs
directory needs to be created before registering the adapter as clients
use that directory as their debugfs parent.
Move debugfs creation before adapter registration to avoid having
clients create their debugfs directories in the debugfs root (which is
also more likely to fail due to name collisions).
Note that failure to allocate the adapter name must now be handled
explicitly as debugfs_create_dir() cannot handle a NULL name (unlike
device_add() which returns an error).
Fixes: 73febd775bdb ("i2c: create debugfs entry per adapter")
Cc: stable@vger.kernel.org # 6.8
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Stable-dep-of: ba14d7cf2fe7 ("i2c: core: fix adapter registration race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 899c7310c77423..37a75d57175b25 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1549,17 +1549,22 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
goto out_list;
}
- dev_set_name(&adap->dev, "i2c-%d", adap->nr);
+ res = dev_set_name(&adap->dev, "i2c-%d", adap->nr);
+ if (res)
+ goto err_remove_irq_domain;
+
adap->dev.bus = &i2c_bus_type;
adap->dev.type = &i2c_adapter_type;
- res = device_register(&adap->dev);
+ device_initialize(&adap->dev);
+
+ adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
+
+ res = device_add(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
- goto err_put_adap;
+ goto err_remove_debugfs;
}
- adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
-
res = i2c_setup_smbus_alert(adap);
if (res)
goto out_reg;
@@ -1599,13 +1604,13 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
out_reg:
i2c_deregister_clients(adap);
- debugfs_remove_recursive(adap->debugfs);
device_del(&adap->dev);
-err_put_adap:
+err_remove_debugfs:
+ debugfs_remove_recursive(adap->debugfs);
init_completion(&adap->dev_released);
put_device(&adap->dev);
wait_for_completion(&adap->dev_released);
-
+err_remove_irq_domain:
i2c_host_notify_irq_teardown(adap);
out_list:
mutex_lock(&core_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5.15.y 5/5] i2c: core: fix adapter registration race
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
` (2 preceding siblings ...)
2026-07-05 14:00 ` [PATCH 5.15.y 4/5] i2c: core: fix adapter debugfs creation Sasha Levin
@ 2026-07-05 14:00 ` Sasha Levin
3 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-07-05 14:00 UTC (permalink / raw)
To: stable; +Cc: Johan Hovold, Wolfram Sang, Sasha Levin
From: Johan Hovold <johan@kernel.org>
[ Upstream commit ba14d7cf2fe7284610a29854bdff22b2537d3ce6 ]
Adapters can be looked up based on their id using i2c_get_adapter()
which takes a reference to the embedded struct device.
Make sure that the adapter (including its struct device) has been
initialised before adding it to the IDR to avoid accessing uninitialised
data which could, for example, lead to NULL-pointer dereferences or
use-after-free.
Note that the i2c-dev chardev, which is registered from a bus notifier,
currently uses i2c_get_adapter() so the adapter needs to be added to the
IDR before registration.
Fixes: 6e13e6418418 ("i2c: Add i2c_add_numbered_adapter()")
Cc: stable@vger.kernel.org # 2.6.22
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/i2c/i2c-core-base.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 37a75d57175b25..98c281a35f5879 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1559,6 +1559,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
adap->debugfs = debugfs_create_dir(dev_name(&adap->dev), i2c_debugfs_root);
+ mutex_lock(&core_lock);
+ idr_replace(&i2c_adapter_idr, adap, adap->nr);
+ mutex_unlock(&core_lock);
+
res = device_add(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
@@ -1631,7 +1635,7 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
int id;
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
+ id = idr_alloc(&i2c_adapter_idr, NULL, adap->nr, adap->nr + 1, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
return id == -ENOSPC ? -EBUSY : id;
@@ -1667,7 +1671,7 @@ int i2c_add_adapter(struct i2c_adapter *adapter)
}
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adapter,
+ id = idr_alloc(&i2c_adapter_idr, NULL,
__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
--
2.53.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-05 14:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02 13:53 FAILED: patch "[PATCH] i2c: core: fix adapter registration race" failed to apply to 5.15-stable tree gregkh
2026-07-05 14:00 ` [PATCH 5.15.y 1/5] i2c: core: fix irq domain leak on adapter registration failure Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 2/5] i2c: core: fix hang " Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 3/5] i2c: core: fix NULL-deref " Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 4/5] i2c: core: fix adapter debugfs creation Sasha Levin
2026-07-05 14:00 ` [PATCH 5.15.y 5/5] i2c: core: fix adapter registration race Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox