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-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251231065109.43378-8-slark_xiao@163.com>
Date: Wed, 31 Dec 2025 14:51:08 +0800
From: Slark Xiao <slark_xiao@....com>
To: loic.poulain@....qualcomm.com,
	ryazanov.s.a@...il.com,
	johannes@...solutions.net,
	andrew+netdev@...n.ch,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	mani@...nel.org
Cc: netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Daniele Palmas <dnlplm@...il.com>
Subject: [net-next v3 7/8] net: wwan: prevent premature device unregister when NMEA port is present

From: Loic Poulain <loic.poulain@....qualcomm.com>

The WWAN core unregisters the device when it has no remaining WWAN ops
or child devices. For NMEA port types, the child is registered under
the GNSS class instead of WWAN, so the core incorrectly assumes there
are no children and unregisters the WWAN device too early. This leads
to a second unregister attempt after the NMEA device is removed.

To fix this issue, we register a virtual WWAN port device along the
GNSS device, this ensures the WWAN device remains registered until
all associated ports, including NMEA, are properly removed.

Reported-by: Daniele Palmas <dnlplm@...il.com>
Closes: https://lore.kernel.org/netdev/CAGRyCJE28yf-rrfkFbzu44ygLEvoUM7fecK1vnrghjG_e9UaRA@mail.gmail.com/
Signed-off-by: Loic Poulain <loic.poulain@....qualcomm.com>
---
 drivers/net/wwan/wwan_core.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c
index 93998b498454..40a57fb0aa0b 100644
--- a/drivers/net/wwan/wwan_core.c
+++ b/drivers/net/wwan/wwan_core.c
@@ -455,7 +455,7 @@ static int __wwan_port_dev_assign_name(struct wwan_port *port, const char *fmt)
 }
 
 /* Register a regular WWAN port device (e.g. AT, MBIM, etc.) */
-static int wwan_port_register_wwan(struct wwan_port *port)
+static int wwan_port_register_wwan(struct wwan_port *port, bool cdev)
 {
 	struct wwan_device *wwandev = to_wwan_dev(port->dev.parent);
 	char namefmt[0x20];
@@ -467,7 +467,8 @@ static int wwan_port_register_wwan(struct wwan_port *port)
 		return minor;
 
 	port->dev.class = &wwan_class;
-	port->dev.devt = MKDEV(wwan_major, minor);
+	if (cdev)
+		port->dev.devt = MKDEV(wwan_major, minor);
 
 	/* allocate unique name based on wwan device id, port type and number */
 	snprintf(namefmt, sizeof(namefmt), "wwan%u%s%%d", wwandev->id,
@@ -625,6 +626,7 @@ struct wwan_port *wwan_create_port(struct device *parent,
 				   struct wwan_port_caps *caps,
 				   void *drvdata)
 {
+	bool cdev = (type == WWAN_PORT_NMEA) ? false : true;
 	struct wwan_device *wwandev;
 	struct wwan_port *port;
 	int err;
@@ -659,16 +661,20 @@ struct wwan_port *wwan_create_port(struct device *parent,
 	dev_set_drvdata(&port->dev, drvdata);
 	device_initialize(&port->dev);
 
-	if (port->type == WWAN_PORT_NMEA)
-		err = wwan_port_register_gnss(port);
-	else
-		err = wwan_port_register_wwan(port);
-
+	err = wwan_port_register_wwan(port, cdev);
 	if (err)
 		goto error_put_device;
 
+	if (type == WWAN_PORT_NMEA) {
+		err = wwan_port_register_gnss(port);
+		if (err)
+			goto error_port_unregister;
+	}
+
 	return port;
 
+error_port_unregister:
+	wwan_port_unregister_wwan(port);
 error_put_device:
 	put_device(&port->dev);
 error_wwandev_remove:
@@ -695,8 +701,8 @@ void wwan_remove_port(struct wwan_port *port)
 
 	if (port->type == WWAN_PORT_NMEA)
 		wwan_port_unregister_gnss(port);
-	else
-		wwan_port_unregister_wwan(port);
+
+	wwan_port_unregister_wwan(port);
 
 	put_device(&port->dev);
 
-- 
2.25.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ