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>] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 21 Sep 2022 13:44:44 +0200
From:   Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To:     netdev@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Russell King <linux@...linux.org.uk>,
        Marcin Wojtas <mw@...ihalf.com>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>, stable <stable@...nel.org>
Subject: [PATCH net] net: mvpp2: debugfs: fix problem with previous memory leak fix

In commit fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using
debugfs_lookup()"), if the module is unloaded, the directory will still
be present if the module is loaded again and creating the directory will
fail, causing the creation of additional child debugfs entries for the
individual devices to fail.

As this module never cleaned up the root directory it created, even when
loaded, and unloading/loading a module is not a normal operation, none
of would normally happen.

To clean all of this up, use a tiny reference counted structure to hold
the root debugfs directory for the driver, and then clean it up when the
last user of it is removed from the system.  This should resolve the
previously reported problems, and the original memory leak that
fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using
debugfs_lookup()") was attempting to fix.

Reported-by: Russell King <linux@...linux.org.uk>
Cc: Marcin Wojtas <mw@...ihalf.com>
Cc: "David S. Miller" <davem@...emloft.net>
Cc: Eric Dumazet <edumazet@...gle.com>
Cc: Jakub Kicinski <kuba@...nel.org>
Cc: Paolo Abeni <pabeni@...hat.com>
Cc: netdev@...r.kernel.org
Cc: stable <stable@...nel.org>
Fixes: fe2c9c61f668 ("net: mvpp2: debugfs: fix memory leak when using debugfs_lookup()")
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
Note, test-built only, I do not have access to this hardware so please
review it for any foolish mistakes I might have again made.

 .../ethernet/marvell/mvpp2/mvpp2_debugfs.c    | 32 ++++++++++++++++---
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
index 0eec05d905eb..16c303048f25 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
@@ -691,23 +691,47 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent,
 	return 0;
 }
 
+static struct mvpp2_debug_dir {
+	struct dentry *dir;
+	struct kref kref;
+} *mvpp2_root;
+
+static void mvpp2_release(struct kref *kref)
+{
+	struct mvpp2_debug_dir *mvpp2_root = container_of(kref, struct mvpp2_debug_dir, kref);
+
+	debugfs_remove(mvpp2_root->dir);
+	kfree(mvpp2_root);
+}
+
 void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
 {
 	debugfs_remove_recursive(priv->dbgfs_dir);
 
 	kfree(priv->dbgfs_entries);
+
+	if (mvpp2_root)
+		kref_put(&mvpp2_root->kref, mvpp2_release);
 }
 
 void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
 {
-	static struct dentry *mvpp2_root;
 	struct dentry *mvpp2_dir;
 	int ret, i;
 
-	if (!mvpp2_root)
-		mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
+	if (!mvpp2_root) {
+		mvpp2_root = kzalloc(sizeof(mvpp2_root), GFP_KERNEL);
+		if (!mvpp2_root) {
+			mvpp2_root = NULL;
+			return;
+		}
+		mvpp2_root->dir = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
+		kref_init(&mvpp2_root->kref);
+	} else {
+		kref_get(&mvpp2_root->kref);
+	}
 
-	mvpp2_dir = debugfs_create_dir(name, mvpp2_root);
+	mvpp2_dir = debugfs_create_dir(name, mvpp2_root->dir);
 
 	priv->dbgfs_dir = mvpp2_dir;
 	priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL);
-- 
2.37.3

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ