lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20250810165158.1888206-11-sashal@kernel.org>
Date: Sun, 10 Aug 2025 12:51:53 -0400
From: Sasha Levin <sashal@...nel.org>
To: patches@...ts.linux.dev,
	stable@...r.kernel.org
Cc: Mark Brown <broonie@...nel.org>,
	Russell King <rmk+kernel@...linux.org.uk>,
	Sasha Levin <sashal@...nel.org>,
	linux-kernel@...r.kernel.org
Subject: [PATCH AUTOSEL 6.16] regmap: irq: Free the regmap-irq mutex

From: Mark Brown <broonie@...nel.org>

[ Upstream commit 1da33858af6250184d2ef907494d698af03283de ]

We do not currently free the mutex allocated by regmap-irq, do so.

Tested-by: Russell King (Oracle) <rmk+kernel@...linux.org.uk>
Reviewed-by: Russell King (Oracle) <rmk+kernel@...linux.org.uk>
Signed-off-by: Mark Brown <broonie@...nel.org>
Link: https://patch.msgid.link/20250731-regmap-irq-nesting-v1-1-98b4d1bf20f0@kernel.org
Signed-off-by: Mark Brown <broonie@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---

LLM Generated explanations, may be completely bogus:

**Backport Status: YES**

This commit fixes a resource leak bug where a mutex allocated with
`mutex_init()` in `regmap_add_irq_chip_fwnode()` was never properly
freed with `mutex_destroy()`. This is a clear memory/resource leak that
has existed since the mutex was first introduced in 2011 (commit
f8beab2bb611).

**Key reasons for backporting:**

1. **Clear bug fix**: The commit fixes a resource leak where
   `mutex_init(&d->lock)` at line 804 allocates mutex resources but they
   were never freed. The fix adds corresponding
   `mutex_destroy(&d->lock)` calls in both error paths and the cleanup
   function.

2. **Long-standing issue**: This bug has existed since 2011 when the
   mutex was first introduced, affecting all stable kernels that include
   the regmap-irq subsystem.

3. **Small and contained change**: The patch only adds two
   `mutex_destroy()` calls:
   - One in the error path (`err_mutex:` label) at line 935
   - One in `regmap_del_irq_chip()` at line 1031

4. **No behavioral changes**: The fix only ensures proper cleanup; it
   doesn't change any functional behavior or introduce new features.

5. **Low regression risk**: Adding `mutex_destroy()` calls is a standard
   cleanup operation that carries minimal risk. The patch also properly
   adjusts error handling labels (changing `goto err_alloc` to `goto
   err_mutex` after mutex initialization).

6. **Affects widely-used subsystem**: The regmap-irq framework is used
   by many drivers across the kernel for interrupt handling, making this
   fix broadly beneficial.

The commit follows stable kernel rules perfectly - it's a small, obvious
fix for a real bug with minimal risk of regression. While not a critical
security issue or crash fix, resource leaks are valid stable candidates,
especially in widely-used infrastructure code like regmap.

 drivers/base/regmap/regmap-irq.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index d1585f073776..4aac12d38215 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -816,7 +816,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 						     d->mask_buf[i],
 						     chip->irq_drv_data);
 			if (ret)
-				goto err_alloc;
+				goto err_mutex;
 		}
 
 		if (chip->mask_base && !chip->handle_mask_sync) {
@@ -827,7 +827,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			if (ret) {
 				dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
 					reg, ret);
-				goto err_alloc;
+				goto err_mutex;
 			}
 		}
 
@@ -838,7 +838,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			if (ret) {
 				dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
 					reg, ret);
-				goto err_alloc;
+				goto err_mutex;
 			}
 		}
 
@@ -855,7 +855,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			if (ret != 0) {
 				dev_err(map->dev, "Failed to read IRQ status: %d\n",
 					ret);
-				goto err_alloc;
+				goto err_mutex;
 			}
 		}
 
@@ -879,7 +879,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			if (ret != 0) {
 				dev_err(map->dev, "Failed to ack 0x%x: %d\n",
 					reg, ret);
-				goto err_alloc;
+				goto err_mutex;
 			}
 		}
 	}
@@ -901,7 +901,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 			if (ret != 0) {
 				dev_err(map->dev, "Failed to set masks in 0x%x: %d\n",
 					reg, ret);
-				goto err_alloc;
+				goto err_mutex;
 			}
 		}
 	}
@@ -910,7 +910,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 	if (chip->status_is_level) {
 		ret = read_irq_data(d);
 		if (ret < 0)
-			goto err_alloc;
+			goto err_mutex;
 
 		memcpy(d->prev_status_buf, d->status_buf,
 		       array_size(d->chip->num_regs, sizeof(d->prev_status_buf[0])));
@@ -918,7 +918,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 
 	ret = regmap_irq_create_domain(fwnode, irq_base, chip, d);
 	if (ret)
-		goto err_alloc;
+		goto err_mutex;
 
 	ret = request_threaded_irq(irq, NULL, regmap_irq_thread,
 				   irq_flags | IRQF_ONESHOT,
@@ -935,6 +935,8 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
 
 err_domain:
 	/* Should really dispose of the domain but... */
+err_mutex:
+	mutex_destroy(&d->lock);
 err_alloc:
 	kfree(d->type_buf);
 	kfree(d->type_buf_def);
@@ -1027,6 +1029,7 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
 			kfree(d->config_buf[i]);
 		kfree(d->config_buf);
 	}
+	mutex_destroy(&d->lock);
 	kfree(d);
 }
 EXPORT_SYMBOL_GPL(regmap_del_irq_chip);
-- 
2.39.5


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ