VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45939

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

1

Patches

6
9c97fcfb7a62

gpib: Fix memory leak in ni_usb_init()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 30, 2025Fixed in 6.18.14via kernel-cna
1 file changed · +7 6
  • drivers/staging/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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
    
    
    
b89921eed8cf

gpib: Fix memory leak in ni_usb_init()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 30, 2025Fixed in 7.0via kernel-cna
1 file changed · +7 6
  • drivers/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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
    
    
    
c899d4b62c07

gpib: Fix memory leak in ni_usb_init()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 30, 2025Fixed in 6.19.4via kernel-cna
1 file changed · +7 6
  • drivers/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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
    
    
    
9c97fcfb7a62

gpib: Fix memory leak in ni_usb_init()

1 file changed · +7 6
  • drivers/staging/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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
    
    
    
b89921eed8cf

gpib: Fix memory leak in ni_usb_init()

1 file changed · +7 6
  • drivers/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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
    
    
    
c899d4b62c07

gpib: Fix memory leak in ni_usb_init()

1 file changed · +7 6
  • drivers/gpib/ni_usb/ni_usb_gpib.c+7 6 modified
    diff --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

3

News mentions

0

No linked articles in our index yet.