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
1Patches
107a400c6fe361usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
6e29c32a2721usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
6d8142141c94usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
8247f52d8221usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
522d17e93a85usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
6e29c32a2721usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
522d17e93a85usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
6d8142141c94usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
7a400c6fe361usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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
8247f52d8221usb: usblp: fix heap leak in IEEE 1284 device ID via short response
1 file changed · +1 −1
drivers/usb/class/usblp.c+1 −1 modifieddiff --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- git.kernel.org/stable/c/522d17e93a85575256894212d10e5a1fa6f36529nvd
- git.kernel.org/stable/c/6d8142141c942c0d8e79343cffda9c44bb1f3f4fnvd
- git.kernel.org/stable/c/6e29c32a27218f2dcd4a4e9b0b3c5e7728640698nvd
- git.kernel.org/stable/c/7a400c6fe3617e31e690e3f7ca37bb335e0498f3nvd
- git.kernel.org/stable/c/8247f52d822180e94ccbfdab91613af386a4e34dnvd
News mentions
0No linked articles in our index yet.