CVE-2026-45939
Description
In the Linux kernel, the following vulnerability has been resolved:
gpib: Fix memory leak in ni_usb_init()
In ni_usb_init(), if ni_usb_setup_init() fails, the function returns -EFAULT without freeing the allocated writes buffer, leading to a memory leak.
Additionally, ni_usb_setup_init() returns 0 on failure, which causes ni_usb_init() to return -EFAULT, an inappropriate error code for this situation.
Fix the leak by freeing writes in the error path. Modify ni_usb_setup_init() to return -EINVAL on failure and propagate this error code in ni_usb_init().
Affected products
1Patches
69c97fcfb7a62gpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/staging/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
b89921eed8cfgpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/gpib/ni_usb/ni_usb_gpib.c b/drivers/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
c899d4b62c07gpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/gpib/ni_usb/ni_usb_gpib.c b/drivers/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
9c97fcfb7a62gpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/staging/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/staging/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/staging/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
b89921eed8cfgpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/gpib/ni_usb/ni_usb_gpib.c b/drivers/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
c899d4b62c07gpib: Fix memory leak in ni_usb_init()
1 file changed · +7 −6
drivers/gpib/ni_usb/ni_usb_gpib.c+7 −6 modifieddiff --git a/drivers/gpib/ni_usb/ni_usb_gpib.c b/drivers/gpib/ni_usb/ni_usb_gpib.c index fdcaa6c00bfeac..b6fddb437f5524 100644 --- a/drivers/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/gpib/ni_usb/ni_usb_gpib.c @@ -1780,7 +1780,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1799,10 +1799,12 @@ static int ni_usb_init(struct gpib_board *board) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing kfree(writes) in the error path of ni_usb_init() when ni_usb_setup_init() fails, and ni_usb_setup_init() incorrectly returning 0 (success) on a buffer-overrun failure instead of a negative error code."
Attack vector
This is a local memory-leak vulnerability in the National Instruments USB GPIB driver. An attacker with the ability to trigger device initialization (e.g., by plugging in a malicious or malfunctioning USB GPIB device that causes an internal buffer overrun condition in ni_usb_setup_init()) can cause the kernel to leak the dynamically allocated writes buffer. The leak occurs because ni_usb_init() returns immediately without calling kfree(writes) when ni_usb_setup_init() returns 0 (the old failure sentinel). Repeated init attempts exhaust kernel memory, leading to denial of service. No authentication or special privileges are required beyond the ability to interact with the GPIB device.
Affected code
The vulnerable functions are ni_usb_setup_init() and ni_usb_init() in drivers/staging/gpib/ni_usb/ni_usb_gpib.c (or drivers/gpib/ni_usb/ni_usb_gpib.c) [patch_id=2661167][patch_id=2661168][patch_id=2661169]. The error path in ni_usb_init() at the call to ni_usb_setup_init() lacked a kfree(writes) before returning, and ni_usb_setup_init() returned 0 on the buffer-overrun failure path instead of a negative errno.
What the fix does
The patch makes two changes in drivers/staging/gpib/ni_usb/ni_usb_gpib.c (or drivers/gpib/ni_usb/ni_usb_gpib.c) [patch_id=2661167][patch_id=2661168][patch_id=2661169]. First, ni_usb_setup_init() now returns -EINVAL instead of 0 when the buffer-overrun condition (i > NUM_INIT_WRITES) is hit, so callers can distinguish failure from success. Second, ni_usb_init() checks if writes_len < 0; if so, it calls kfree(writes) to free the allocated buffer before propagating the error code. This closes the memory leak and returns an appropriate error code (-EINVAL) instead of the misleading -EFAULT.
Preconditions
- configThe system must have the National Instruments USB GPIB driver (ni_usb) loaded or loadable.
- inputAn attacker must be able to trigger device initialization, e.g., by connecting a USB GPIB device that causes a buffer overrun in ni_usb_setup_init().
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.