VYPR
Unrated severityNVD Advisory· Published May 28, 2026

CVE-2026-46151

CVE-2026-46151

Description

In the Linux kernel, the following vulnerability has been resolved:

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

usblp_ctrl_msg() collapses the usb_control_msg() return value to 0/-errno, discarding the actual number of bytes transferred. A broken printer can complete the GET_DEVICE_ID control transfer short and the driver has no way to know.

usblp_cache_device_id_string() reads the 2-byte big-endian length prefix from the response and trusts it (clamped only to the buffer bounds). The buffer is kmalloc(1024) at probe time. A device that sends exactly two bytes (e.g. 0x03 0xFF, claiming a 1023-byte ID) leaves device_id_string[2..1022] holding stale kmalloc heap.

That stale data is then exposed: - via the ieee1284_id sysfs attribute (sprintf("%s", buf+2), truncated at the first NUL in the stale heap), and - via the IOCNR_GET_DEVICE_ID ioctl, which copy_to_user()s the full claimed length regardless of NULs, up to 1021 bytes of uninitialized heap, with the leak size chosen by the device.

Fix this up by just zapping the buffer with zeros before each request sent to the device.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A heap memory leak in the Linux kernel's usblp driver allows a malicious USB printer to leak uninitialized kernel heap data via the IEEE 1284 device ID.

Vulnerability

The Linux kernel's usblp driver (userspace printer driver) contains a heap memory leak vulnerability in the IEEE 1284 device ID handling. The issue is in usblp_cache_device_id_string(), which reads a 2-byte big-endian length prefix from the device's response and trusts it (clamped only to the buffer bounds, up to 1023 bytes). The response buffer is kmalloc(1024) at probe time. A broken or malicious printer can send a short response (e.g. exactly two bytes claiming a 1023-byte ID), leaving the rest of the buffer (bytes 2..1022) holding stale heap content. The driver's usblp_ctrl_msg() collapses the usb_control_msg() return value to 0/-errno, discarding the actual number of bytes transferred, so the driver cannot detect the short response. Affected are Linux kernel versions before the fix commit 522d17e93a85 (applied to stable trees). [1]

Exploitation

An attacker needs either physical access to a USB port or the ability to emulate a USB printer device (e.g., via a compromised USB device or a malicious peripheral). The attacker sends a control transfer response to the GET_DEVICE_ID request that contains only two bytes: a fabricated big-endian length prefix (e.g., 0x03 0xFF for 1023 bytes). No further authentication is required. The driver then treats the remaining buffer content as part of the device ID, which contains uninitialized heap memory. The stale data is later read by user-space via the ieee1284_id sysfs attribute or the IOCNR_GET_DEVICE_ID ioctl. [1]

Impact

A malicious USB device can cause the kernel to expose up to 1021 bytes of uninitialized heap memory to a local user or process. This is an information disclosure vulnerability: the leaked data may contain sensitive kernel pointers, slab metadata, or remnants of other kernel operations. The exposure occurs through two paths: the sysfs attribute (string truncated at the first NUL) and the ioctl (which copies the full claimed length to user-space). The attacker controls the amount of leaked data by setting the length prefix. [1]

Mitigation

The fix has been applied in the Linux kernel commit 522d17e93a85 [1]. The fix zeros the response buffer before each request, preventing stale heap data from being exposed. Users should apply the updated kernel version (distributions will backport the commit). No workaround is available for unpatched kernels. This CVE is not on the KEV list as of publication. [1]

AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

10
7a400c6fe361

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 7.1-rc3via kernel-cna
1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index 669b9e6879bfa5..e9b848622a3aa5 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
6e29c32a2721

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.6.140via kernel-cna
1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index ff1a941fd2ede4..a04acadc4faf01 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1365,6 +1365,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
6d8142141c94

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.12.88via kernel-cna
1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index ff1a941fd2ede4..a04acadc4faf01 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1365,6 +1365,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
8247f52d8221

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 6.18.30via kernel-cna
1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index a7a1d38b6bef75..2c47acdc35be4c 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
522d17e93a85

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitGreg Kroah-HartmanApr 20, 2026Fixed in 7.0.7via kernel-cna
1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index 669b9e6879bfa5..e9b848622a3aa5 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
6e29c32a2721

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index ff1a941fd2ede4..a04acadc4faf01 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1365,6 +1365,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
522d17e93a85

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index 669b9e6879bfa5..e9b848622a3aa5 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
6d8142141c94

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index ff1a941fd2ede4..a04acadc4faf01 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1365,6 +1365,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
7a400c6fe361

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index 669b9e6879bfa5..e9b848622a3aa5 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    
8247f52d8221

usb: usblp: fix heap leak in IEEE 1284 device ID via short response

1 file changed · +1 1
  • drivers/usb/class/usblp.c+1 1 modified
    diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
    index a7a1d38b6bef75..2c47acdc35be4c 100644
    --- a/drivers/usb/class/usblp.c
    +++ b/drivers/usb/class/usblp.c
    @@ -1377,6 +1377,7 @@ static int usblp_cache_device_id_string(struct usblp *usblp)
     {
     	int err, length;
     
    +	memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE);
     	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
     	if (err < 0) {
     		dev_dbg(&usblp->intf->dev,
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing buffer zeroing before USB control transfer allows a short response with a forged length prefix to expose stale kmalloc heap data."

Attack vector

A malicious or compromised USB printer can respond to the GET_DEVICE_ID control transfer with only two bytes (e.g. 0x03 0xFF), claiming a 1023-byte device ID. The function usblp_ctrl_msg() discards the actual byte count, so the driver cannot detect the short transfer. The function usblp_cache_device_id_string() then reads the 2-byte big-endian length prefix and trusts it, leaving bytes 2 through 1022 of the kmalloc(1024) buffer filled with stale heap data. That uninitialized data is exposed to user space via the ieee1284_id sysfs attribute (sprintf, truncated at first NUL) and via the IOCNR_GET_DEVICE_ID ioctl (copy_to_user of the full claimed length, up to 1021 bytes).

Affected code

The vulnerable code is in drivers/usb/class/usblp.c, in the function usblp_cache_device_id_string(). The buffer device_id_string is kmalloc(USBLP_DEVICE_ID_SIZE) (1024 bytes) at probe time and is reused across calls without being zeroed. The function usblp_ctrl_msg() collapses the usb_control_msg() return value to 0/-errno, discarding the actual byte count, so a short transfer is invisible to the caller.

What the fix does

The patch adds a single memset(usblp->device_id_string, 0, USBLP_DEVICE_ID_SIZE) call at the top of usblp_cache_device_id_string(), before the GET_DEVICE_ID request is issued [patch_id=2898253]. This zeros the entire 1024-byte buffer so that any bytes not overwritten by a short device response will contain NULs rather than stale heap content. The fix is minimal and targeted: it does not change the control-transfer return-value handling, but ensures that uninitialized heap can never be exposed through the device ID string.

Preconditions

  • physicalAttacker must have physical access to connect a malicious USB device to the host, or the host must be connected to a compromised printer that can respond with a crafted short GET_DEVICE_ID reply.
  • configThe usblp driver must be loaded and bound to the device.

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.