summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungjin Bae <eeodqql09@gmail.com>2025-11-24 14:20:46 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-12-03 12:45:22 +0100
commitc4e746651bd74c38f581e1cf31651119a94de8cd (patch)
treec40595af72eb98f7c66cb9a213a4e5f95c489cba
parenta643fecbcac0a343fc83393ebf31eb09cd556e5b (diff)
Input: pegasus-notetaker - fix potential out-of-bounds access
[ Upstream commit 69aeb507312306f73495598a055293fa749d454e ] In the pegasus_notetaker driver, the pegasus_probe() function allocates the URB transfer buffer using the wMaxPacketSize value from the endpoint descriptor. An attacker can use a malicious USB descriptor to force the allocation of a very small buffer. Subsequently, if the device sends an interrupt packet with a specific pattern (e.g., where the first byte is 0x80 or 0x42), the pegasus_parse_packet() function parses the packet without checking the allocated buffer size. This leads to an out-of-bounds memory access. Fixes: 1afca2b66aac ("Input: add Pegasus Notetaker tablet driver") Signed-off-by: Seungjin Bae <eeodqql09@gmail.com> Link: https://lore.kernel.org/r/20251007214131.3737115-2-eeodqql09@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/input/tablet/pegasus_notetaker.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c
index 4e412a73a5aa..64a5ce546229 100644
--- a/drivers/input/tablet/pegasus_notetaker.c
+++ b/drivers/input/tablet/pegasus_notetaker.c
@@ -63,6 +63,9 @@
#define BUTTON_PRESSED 0xb5
#define COMMAND_VERSION 0xa9
+/* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */
+#define NOTETAKER_PACKET_SIZE 6
+
/* in xy data packet */
#define BATTERY_NO_REPORT 0x40
#define BATTERY_LOW 0x41
@@ -297,6 +300,12 @@ static int pegasus_probe(struct usb_interface *intf,
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
pegasus->data_len = usb_maxpacket(dev, pipe);
+ if (pegasus->data_len < NOTETAKER_PACKET_SIZE) {
+ dev_err(&intf->dev, "packet size is too small (%d)\n",
+ pegasus->data_len);
+ error = -EINVAL;
+ goto err_free_mem;
+ }
pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL,
&pegasus->data_dma);