hso_probe() allocates the shared interrupt state with hso_create_shared_int() for a multiplexed interface and then creates one muxed serial device per port advertised by the device. A muxed serial device takes ownership of the shared interrupt state by incrementing its ref_count, and hso_free_serial_device() releases the state together with the last reference. There are two paths where the state is allocated but no serial device ever takes a reference to it: the port mask read from the device contains no port that can be muxed (including a port mask of zero), and the creation of the first muxed serial device fails. In both cases hso_probe() leaves through a path that only frees the registered serial and network devices, so the URB, the buffer, the mutex and the state itself are leaked. Release the state in both places when no serial device took it over. hso_free_shared_int() still has to be called with the state's mutex held, so add a small helper which takes the lock first. Fixes: 72dc1c096c70 ("HSO: add option hso driver") Cc: stable@vger.kernel.org Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex Signed-off-by: Wentao Liang --- drivers/net/usb/hso.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 71caa3764b23..818444830072 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2736,6 +2736,13 @@ static void hso_free_shared_int(struct hso_shared_int *mux) kfree(mux); } +/* Release a shared interrupt state which no muxed serial device took over */ +static void hso_free_unused_shared_int(struct hso_shared_int *shared_int) +{ + mutex_lock(&shared_int->shared_int_lock); + hso_free_shared_int(shared_int); +} + static struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) { @@ -2853,8 +2860,9 @@ static int hso_probe(struct usb_interface *interface, int mux, i, if_num, port_spec; unsigned char port_mask; struct hso_device *hso_dev = NULL; - struct hso_shared_int *shared_int; + struct hso_shared_int *shared_int = NULL; struct hso_device *tmp_dev = NULL; + int mux_count = 0; if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) { dev_err(&interface->dev, "Not our interface\n"); @@ -2912,11 +2920,16 @@ static int hso_probe(struct usb_interface *interface, interface, i, shared_int); if (!hso_dev) goto exit; + mux_count++; } } if (tmp_dev) hso_dev = tmp_dev; + + /* No muxed port took over the shared interrupt state */ + if (!mux_count) + hso_free_unused_shared_int(shared_int); break; case HSO_INTF_BULK: @@ -2943,6 +2956,11 @@ static int hso_probe(struct usb_interface *interface, return 0; exit: hso_free_interface(interface); + + /* No muxed port took over the shared interrupt state */ + if (shared_int && !mux_count) + hso_free_unused_shared_int(shared_int); + return -ENODEV; } -- 2.34.1