From: Seungjin Bae eeodqql09@gmail.com
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, which could result in a system panic.
Fixes: 948bf18 ("Input: remove third argument of usb_maxpacket()") Signed-off-by: Seungjin Bae eeodqql09@gmail.com --- drivers/input/tablet/pegasus_notetaker.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index 8d6b71d59793..6c4199712a4e 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -311,6 +311,11 @@ static int pegasus_probe(struct usb_interface *intf, }
pegasus->data_len = usb_maxpacket(dev, pipe); + if (pegasus->data_len < 5) { + dev_err(&intf->dev, "Invalid number of wMaxPacketSize\n"); + error = -EINVAL; + goto err_free_mem; + }
pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, &pegasus->data_dma);
On Tue, Oct 07, 2025 at 05:41:32PM -0400, pip-izony wrote:
From: Seungjin Bae eeodqql09@gmail.com
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, which could result in a system panic.
Fixes: 948bf18 ("Input: remove third argument of usb_maxpacket()") Signed-off-by: Seungjin Bae eeodqql09@gmail.com
drivers/input/tablet/pegasus_notetaker.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index 8d6b71d59793..6c4199712a4e 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -311,6 +311,11 @@ static int pegasus_probe(struct usb_interface *intf, } pegasus->data_len = usb_maxpacket(dev, pipe);
- if (pegasus->data_len < 5) {
dev_err(&intf->dev, "Invalid number of wMaxPacketSize\n");
error = -EINVAL;
goto err_free_mem;
- }
pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, &pegasus->data_dma); -- 2.43.0
<formletter>
This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read: https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html for how to do this properly.
</formletter>
Hi,
Thanks for your patch.
FYI: kernel test robot notices the stable kernel rule is not satisfied.
The check is based on https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html#opti...
Rule: add the tag "Cc: stable@vger.kernel.org" in the sign-off area to have the patch automatically included in the stable tree. Subject: [PATCH] Input: pegasus-notetaker - fix out-of-bounds access vulnerability in pegasus_parse_packet() function of the pegasus driver Link: https://lore.kernel.org/stable/20251007214131.3737115-2-eeodqql09%40gmail.co...
Hi pip-izony,
kernel test robot noticed the following build warnings:
[auto build test WARNING on dtor-input/next] [also build test WARNING on dtor-input/for-linus linus/master v6.17 next-20251010] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/pip-izony/Input-pegasus-notet... base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next patch link: https://lore.kernel.org/r/20251007214131.3737115-2-eeodqql09%40gmail.com patch subject: [PATCH] Input: pegasus-notetaker - fix out-of-bounds access vulnerability in pegasus_parse_packet() function of the pegasus driver config: powerpc64-randconfig-r073-20251010 (https://download.01.org/0day-ci/archive/20251011/202510110303.ibbCe4PD-lkp@i...) compiler: powerpc64-linux-gcc (GCC) 8.5.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202510110303.ibbCe4PD-lkp@intel.com/
smatch warnings: drivers/input/tablet/pegasus_notetaker.c:314 pegasus_probe() warn: inconsistent indenting
vim +314 drivers/input/tablet/pegasus_notetaker.c
270 271 static int pegasus_probe(struct usb_interface *intf, 272 const struct usb_device_id *id) 273 { 274 struct usb_device *dev = interface_to_usbdev(intf); 275 struct usb_endpoint_descriptor *endpoint; 276 struct pegasus *pegasus; 277 struct input_dev *input_dev; 278 int error; 279 int pipe; 280 281 /* We control interface 0 */ 282 if (intf->cur_altsetting->desc.bInterfaceNumber >= 1) 283 return -ENODEV; 284 285 /* Sanity check that the device has an endpoint */ 286 if (intf->cur_altsetting->desc.bNumEndpoints < 1) { 287 dev_err(&intf->dev, "Invalid number of endpoints\n"); 288 return -EINVAL; 289 } 290 291 endpoint = &intf->cur_altsetting->endpoint[0].desc; 292 293 pegasus = kzalloc(sizeof(*pegasus), GFP_KERNEL); 294 input_dev = input_allocate_device(); 295 if (!pegasus || !input_dev) { 296 error = -ENOMEM; 297 goto err_free_mem; 298 } 299 300 mutex_init(&pegasus->pm_mutex); 301 302 pegasus->usbdev = dev; 303 pegasus->dev = input_dev; 304 pegasus->intf = intf; 305 306 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 307 /* Sanity check that pipe's type matches endpoint's type */ 308 if (usb_pipe_type_check(dev, pipe)) { 309 error = -EINVAL; 310 goto err_free_mem; 311 } 312 313 pegasus->data_len = usb_maxpacket(dev, pipe);
314 if (pegasus->data_len < 5) {
315 dev_err(&intf->dev, "Invalid number of wMaxPacketSize\n"); 316 error = -EINVAL; 317 goto err_free_mem; 318 } 319 320 pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL, 321 &pegasus->data_dma); 322 if (!pegasus->data) { 323 error = -ENOMEM; 324 goto err_free_mem; 325 } 326 327 pegasus->irq = usb_alloc_urb(0, GFP_KERNEL); 328 if (!pegasus->irq) { 329 error = -ENOMEM; 330 goto err_free_dma; 331 } 332 333 usb_fill_int_urb(pegasus->irq, dev, pipe, 334 pegasus->data, pegasus->data_len, 335 pegasus_irq, pegasus, endpoint->bInterval); 336 337 pegasus->irq->transfer_dma = pegasus->data_dma; 338 pegasus->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 339 340 if (dev->manufacturer) 341 strscpy(pegasus->name, dev->manufacturer, 342 sizeof(pegasus->name)); 343 344 if (dev->product) { 345 if (dev->manufacturer) 346 strlcat(pegasus->name, " ", sizeof(pegasus->name)); 347 strlcat(pegasus->name, dev->product, sizeof(pegasus->name)); 348 } 349 350 if (!strlen(pegasus->name)) 351 snprintf(pegasus->name, sizeof(pegasus->name), 352 "USB Pegasus Device %04x:%04x", 353 le16_to_cpu(dev->descriptor.idVendor), 354 le16_to_cpu(dev->descriptor.idProduct)); 355 356 usb_make_path(dev, pegasus->phys, sizeof(pegasus->phys)); 357 strlcat(pegasus->phys, "/input0", sizeof(pegasus->phys)); 358 359 INIT_WORK(&pegasus->init, pegasus_init); 360 361 usb_set_intfdata(intf, pegasus); 362 363 input_dev->name = pegasus->name; 364 input_dev->phys = pegasus->phys; 365 usb_to_input_id(dev, &input_dev->id); 366 input_dev->dev.parent = &intf->dev; 367 368 input_set_drvdata(input_dev, pegasus); 369 370 input_dev->open = pegasus_open; 371 input_dev->close = pegasus_close; 372 373 __set_bit(EV_ABS, input_dev->evbit); 374 __set_bit(EV_KEY, input_dev->evbit); 375 376 __set_bit(ABS_X, input_dev->absbit); 377 __set_bit(ABS_Y, input_dev->absbit); 378 379 __set_bit(BTN_TOUCH, input_dev->keybit); 380 __set_bit(BTN_RIGHT, input_dev->keybit); 381 __set_bit(BTN_TOOL_PEN, input_dev->keybit); 382 383 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); 384 __set_bit(INPUT_PROP_POINTER, input_dev->propbit); 385 386 input_set_abs_params(input_dev, ABS_X, -1500, 1500, 8, 0); 387 input_set_abs_params(input_dev, ABS_Y, 1600, 3000, 8, 0); 388 389 error = input_register_device(pegasus->dev); 390 if (error) 391 goto err_free_urb; 392 393 return 0; 394 395 err_free_urb: 396 usb_free_urb(pegasus->irq); 397 err_free_dma: 398 usb_free_coherent(dev, pegasus->data_len, 399 pegasus->data, pegasus->data_dma); 400 err_free_mem: 401 input_free_device(input_dev); 402 kfree(pegasus); 403 usb_set_intfdata(intf, NULL); 404 405 return error; 406 } 407
linux-stable-mirror@lists.linaro.org