Message ID | 20200530073935.17874-1-baijiaju1990@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | input: tablet: aiptek: fix possible buffer overflow caused by bad DMA value in aiptek_irq() | expand |
Hi Jia-Ju, Thank you for the patch! Yet something to improve: [auto build test ERROR on input/next] [also build test ERROR on v5.7 next-20200529] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Jia-Ju-Bai/input-tablet-aiptek-fix-possible-buffer-overflow-caused-by-bad-DMA-value-in-aiptek_irq/20200601-015649 base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next config: s390-allyesconfig (attached as .config) compiler: s390-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=s390 If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot <lkp@intel.com> All errors (new ones prefixed by >>, old ones prefixed by <<): drivers/input/tablet/aiptek.c: In function 'aiptek_irq': >> drivers/input/tablet/aiptek.c:744:7: error: 'marco' undeclared (first use in this function); did you mean 'macro'? 744 | if (marco > 0 && macro < 25) { | ^~~~~ | macro drivers/input/tablet/aiptek.c:744:7: note: each undeclared identifier is reported only once for each function it appears in vim +744 drivers/input/tablet/aiptek.c 377 378 /*********************************************************************** 379 * aiptek_irq can receive one of six potential reports. 380 * The documentation for each is in the body of the function. 381 * 382 * The tablet reports on several attributes per invocation of 383 * aiptek_irq. Because the Linux Input Event system allows the 384 * transmission of ONE attribute per input_report_xxx() call, 385 * collation has to be done on the other end to reconstitute 386 * a complete tablet report. Further, the number of Input Event reports 387 * submitted varies, depending on what USB report type, and circumstance. 388 * To deal with this, EV_MSC is used to indicate an 'end-of-report' 389 * message. This has been an undocumented convention understood by the kernel 390 * tablet driver and clients such as gpm and XFree86's tablet drivers. 391 * 392 * Of the information received from the tablet, the one piece I 393 * cannot transmit is the proximity bit (without resorting to an EV_MSC 394 * convention above.) I therefore have taken over REL_MISC and ABS_MISC 395 * (for relative and absolute reports, respectively) for communicating 396 * Proximity. Why two events? I thought it interesting to know if the 397 * Proximity event occurred while the tablet was in absolute or relative 398 * mode. 399 * Update: REL_MISC proved not to be such a good idea. With REL_MISC you 400 * get an event transmitted each time. ABS_MISC works better, since it 401 * can be set and re-set. Thus, only using ABS_MISC from now on. 402 * 403 * Other tablets use the notion of a certain minimum stylus pressure 404 * to infer proximity. While that could have been done, that is yet 405 * another 'by convention' behavior, the documentation for which 406 * would be spread between two (or more) pieces of software. 407 * 408 * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and 409 * replaced with the input_sync() method (which emits EV_SYN.) 410 */ 411 412 static void aiptek_irq(struct urb *urb) 413 { 414 struct aiptek *aiptek = urb->context; 415 unsigned char *data = aiptek->data; 416 struct input_dev *inputdev = aiptek->inputdev; 417 struct usb_interface *intf = aiptek->intf; 418 int jitterable = 0; 419 int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck; 420 421 switch (urb->status) { 422 case 0: 423 /* Success */ 424 break; 425 426 case -ECONNRESET: 427 case -ENOENT: 428 case -ESHUTDOWN: 429 /* This urb is terminated, clean up */ 430 dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n", 431 __func__, urb->status); 432 return; 433 434 default: 435 dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n", 436 __func__, urb->status); 437 goto exit; 438 } 439 440 /* See if we are in a delay loop -- throw out report if true. 441 */ 442 if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) { 443 goto exit; 444 } 445 446 aiptek->inDelay = 0; 447 aiptek->eventCount++; 448 449 /* Report 1 delivers relative coordinates with either a stylus 450 * or the mouse. You do not know, however, which input 451 * tool generated the event. 452 */ 453 if (data[0] == 1) { 454 if (aiptek->curSetting.coordinateMode == 455 AIPTEK_COORDINATE_ABSOLUTE_MODE) { 456 aiptek->diagnostic = 457 AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; 458 } else { 459 x = (signed char) data[2]; 460 y = (signed char) data[3]; 461 462 /* jitterable keeps track of whether any button has been pressed. 463 * We're also using it to remap the physical mouse button mask 464 * to pseudo-settings. (We don't specifically care about it's 465 * value after moving/transposing mouse button bitmasks, except 466 * that a non-zero value indicates that one or more 467 * mouse button was pressed.) 468 */ 469 jitterable = data[1] & 0x07; 470 471 left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0; 472 right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0; 473 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0; 474 475 input_report_key(inputdev, BTN_LEFT, left); 476 input_report_key(inputdev, BTN_MIDDLE, middle); 477 input_report_key(inputdev, BTN_RIGHT, right); 478 479 input_report_abs(inputdev, ABS_MISC, 480 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 481 input_report_rel(inputdev, REL_X, x); 482 input_report_rel(inputdev, REL_Y, y); 483 484 /* Wheel support is in the form of a single-event 485 * firing. 486 */ 487 if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 488 input_report_rel(inputdev, REL_WHEEL, 489 aiptek->curSetting.wheel); 490 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 491 } 492 if (aiptek->lastMacro != -1) { 493 input_report_key(inputdev, 494 macroKeyEvents[aiptek->lastMacro], 0); 495 aiptek->lastMacro = -1; 496 } 497 input_sync(inputdev); 498 } 499 } 500 /* Report 2 is delivered only by the stylus, and delivers 501 * absolute coordinates. 502 */ 503 else if (data[0] == 2) { 504 if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 505 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 506 } else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE 507 (aiptek->curSetting.pointerMode)) { 508 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 509 } else { 510 x = get_unaligned_le16(data + 1); 511 y = get_unaligned_le16(data + 3); 512 z = get_unaligned_le16(data + 6); 513 514 dv = (data[5] & 0x01) != 0 ? 1 : 0; 515 p = (data[5] & 0x02) != 0 ? 1 : 0; 516 tip = (data[5] & 0x04) != 0 ? 1 : 0; 517 518 /* Use jitterable to re-arrange button masks 519 */ 520 jitterable = data[5] & 0x18; 521 522 bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 523 pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 524 525 /* dv indicates 'data valid' (e.g., the tablet is in sync 526 * and has delivered a "correct" report) We will ignore 527 * all 'bad' reports... 528 */ 529 if (dv != 0) { 530 /* If the selected tool changed, reset the old 531 * tool key, and set the new one. 532 */ 533 if (aiptek->previousToolMode != 534 aiptek->curSetting.toolMode) { 535 input_report_key(inputdev, 536 aiptek->previousToolMode, 0); 537 input_report_key(inputdev, 538 aiptek->curSetting.toolMode, 539 1); 540 aiptek->previousToolMode = 541 aiptek->curSetting.toolMode; 542 } 543 544 if (p != 0) { 545 input_report_abs(inputdev, ABS_X, x); 546 input_report_abs(inputdev, ABS_Y, y); 547 input_report_abs(inputdev, ABS_PRESSURE, z); 548 549 input_report_key(inputdev, BTN_TOUCH, tip); 550 input_report_key(inputdev, BTN_STYLUS, bs); 551 input_report_key(inputdev, BTN_STYLUS2, pck); 552 553 if (aiptek->curSetting.xTilt != 554 AIPTEK_TILT_DISABLE) { 555 input_report_abs(inputdev, 556 ABS_TILT_X, 557 aiptek->curSetting.xTilt); 558 } 559 if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) { 560 input_report_abs(inputdev, 561 ABS_TILT_Y, 562 aiptek->curSetting.yTilt); 563 } 564 565 /* Wheel support is in the form of a single-event 566 * firing. 567 */ 568 if (aiptek->curSetting.wheel != 569 AIPTEK_WHEEL_DISABLE) { 570 input_report_abs(inputdev, 571 ABS_WHEEL, 572 aiptek->curSetting.wheel); 573 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 574 } 575 } 576 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); 577 if (aiptek->lastMacro != -1) { 578 input_report_key(inputdev, 579 macroKeyEvents[aiptek->lastMacro], 0); 580 aiptek->lastMacro = -1; 581 } 582 input_sync(inputdev); 583 } 584 } 585 } 586 /* Report 3's come from the mouse in absolute mode. 587 */ 588 else if (data[0] == 3) { 589 if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 590 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 591 } else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE 592 (aiptek->curSetting.pointerMode)) { 593 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 594 } else { 595 x = get_unaligned_le16(data + 1); 596 y = get_unaligned_le16(data + 3); 597 598 jitterable = data[5] & 0x1c; 599 600 dv = (data[5] & 0x01) != 0 ? 1 : 0; 601 p = (data[5] & 0x02) != 0 ? 1 : 0; 602 left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 603 right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 604 middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 605 606 if (dv != 0) { 607 /* If the selected tool changed, reset the old 608 * tool key, and set the new one. 609 */ 610 if (aiptek->previousToolMode != 611 aiptek->curSetting.toolMode) { 612 input_report_key(inputdev, 613 aiptek->previousToolMode, 0); 614 input_report_key(inputdev, 615 aiptek->curSetting.toolMode, 616 1); 617 aiptek->previousToolMode = 618 aiptek->curSetting.toolMode; 619 } 620 621 if (p != 0) { 622 input_report_abs(inputdev, ABS_X, x); 623 input_report_abs(inputdev, ABS_Y, y); 624 625 input_report_key(inputdev, BTN_LEFT, left); 626 input_report_key(inputdev, BTN_MIDDLE, middle); 627 input_report_key(inputdev, BTN_RIGHT, right); 628 629 /* Wheel support is in the form of a single-event 630 * firing. 631 */ 632 if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 633 input_report_abs(inputdev, 634 ABS_WHEEL, 635 aiptek->curSetting.wheel); 636 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 637 } 638 } 639 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); 640 if (aiptek->lastMacro != -1) { 641 input_report_key(inputdev, 642 macroKeyEvents[aiptek->lastMacro], 0); 643 aiptek->lastMacro = -1; 644 } 645 input_sync(inputdev); 646 } 647 } 648 } 649 /* Report 4s come from the macro keys when pressed by stylus 650 */ 651 else if (data[0] == 4) { 652 jitterable = data[1] & 0x18; 653 654 dv = (data[1] & 0x01) != 0 ? 1 : 0; 655 p = (data[1] & 0x02) != 0 ? 1 : 0; 656 tip = (data[1] & 0x04) != 0 ? 1 : 0; 657 bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 658 pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 659 660 macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1; 661 z = get_unaligned_le16(data + 4); 662 663 if (dv) { 664 /* If the selected tool changed, reset the old 665 * tool key, and set the new one. 666 */ 667 if (aiptek->previousToolMode != 668 aiptek->curSetting.toolMode) { 669 input_report_key(inputdev, 670 aiptek->previousToolMode, 0); 671 input_report_key(inputdev, 672 aiptek->curSetting.toolMode, 673 1); 674 aiptek->previousToolMode = 675 aiptek->curSetting.toolMode; 676 } 677 } 678 679 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 680 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 681 aiptek->lastMacro = -1; 682 } 683 684 if (macro != -1 && macro != aiptek->lastMacro) { 685 input_report_key(inputdev, macroKeyEvents[macro], 1); 686 aiptek->lastMacro = macro; 687 } 688 input_report_abs(inputdev, ABS_MISC, 689 p | AIPTEK_REPORT_TOOL_STYLUS); 690 input_sync(inputdev); 691 } 692 /* Report 5s come from the macro keys when pressed by mouse 693 */ 694 else if (data[0] == 5) { 695 jitterable = data[1] & 0x1c; 696 697 dv = (data[1] & 0x01) != 0 ? 1 : 0; 698 p = (data[1] & 0x02) != 0 ? 1 : 0; 699 left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 700 right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 701 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 702 macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0; 703 704 if (dv) { 705 /* If the selected tool changed, reset the old 706 * tool key, and set the new one. 707 */ 708 if (aiptek->previousToolMode != 709 aiptek->curSetting.toolMode) { 710 input_report_key(inputdev, 711 aiptek->previousToolMode, 0); 712 input_report_key(inputdev, 713 aiptek->curSetting.toolMode, 1); 714 aiptek->previousToolMode = aiptek->curSetting.toolMode; 715 } 716 } 717 718 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 719 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 720 aiptek->lastMacro = -1; 721 } 722 723 if (macro != -1 && macro != aiptek->lastMacro) { 724 input_report_key(inputdev, macroKeyEvents[macro], 1); 725 aiptek->lastMacro = macro; 726 } 727 728 input_report_abs(inputdev, ABS_MISC, 729 p | AIPTEK_REPORT_TOOL_MOUSE); 730 input_sync(inputdev); 731 } 732 /* We have no idea which tool can generate a report 6. Theoretically, 733 * neither need to, having been given reports 4 & 5 for such use. 734 * However, report 6 is the 'official-looking' report for macroKeys; 735 * reports 4 & 5 supposively are used to support unnamed, unknown 736 * hat switches (which just so happen to be the macroKeys.) 737 */ 738 else if (data[0] == 6) { 739 macro = get_unaligned_le16(data + 1); 740 if (macro > 0 && macro < 34) { 741 input_report_key(inputdev, macroKeyEvents[macro - 1], 742 0); 743 } > 744 if (marco > 0 && macro < 25) { 745 input_report_key(inputdev, macroKeyEvents[macro + 1], 746 0); 747 } 748 749 /* If the selected tool changed, reset the old 750 tool key, and set the new one. 751 */ 752 if (aiptek->previousToolMode != 753 aiptek->curSetting.toolMode) { 754 input_report_key(inputdev, 755 aiptek->previousToolMode, 0); 756 input_report_key(inputdev, 757 aiptek->curSetting.toolMode, 758 1); 759 aiptek->previousToolMode = 760 aiptek->curSetting.toolMode; 761 } 762 763 if (macro > 0 && macro < 33) 764 input_report_key(inputdev, macroKeyEvents[macro], 1); 765 input_report_abs(inputdev, ABS_MISC, 766 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 767 input_sync(inputdev); 768 } else { 769 dev_dbg(&intf->dev, "Unknown report %d\n", data[0]); 770 } 771 772 /* Jitter may occur when the user presses a button on the stlyus 773 * or the mouse. What we do to prevent that is wait 'x' milliseconds 774 * following a 'jitterable' event, which should give the hand some time 775 * stabilize itself. 776 * 777 * We just introduced aiptek->previousJitterable to carry forth the 778 * notion that jitter occurs when the button state changes from on to off: 779 * a person drawing, holding a button down is not subject to jittering. 780 * With that in mind, changing from upper button depressed to lower button 781 * WILL transition through a jitter delay. 782 */ 783 784 if (aiptek->previousJitterable != jitterable && 785 aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) { 786 aiptek->endDelay = jiffies + 787 ((aiptek->curSetting.jitterDelay * HZ) / 1000); 788 aiptek->inDelay = 1; 789 } 790 aiptek->previousJitterable = jitterable; 791 792 exit: 793 retval = usb_submit_urb(urb, GFP_ATOMIC); 794 if (retval != 0) { 795 dev_err(&intf->dev, 796 "%s - usb_submit_urb failed with result %d\n", 797 __func__, retval); 798 } 799 } 800 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Jia-Ju, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on input/next] [also build test WARNING on v5.7 next-20200529] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Jia-Ju-Bai/input-tablet-aiptek-fix-possible-buffer-overflow-caused-by-bad-DMA-value-in-aiptek_irq/20200601-015649 base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next config: mips-randconfig-r032-20200531 (attached as .config) compiler: mipsel-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot <lkp@intel.com> All warnings (new ones prefixed by >>, old ones prefixed by <<): In file included from include/asm-generic/div64.h:25, from arch/mips/include/asm/div64.h:12, from include/linux/math64.h:6, from include/linux/jiffies.h:6, from drivers/input/tablet/aiptek.c:60: drivers/input/tablet/aiptek.c: In function 'aiptek_irq': drivers/input/tablet/aiptek.c:744:7: error: 'marco' undeclared (first use in this function); did you mean 'macro'? 744 | if (marco > 0 && macro < 25) { | ^~~~~ include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var' 58 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond)) | ^~~~ >> drivers/input/tablet/aiptek.c:744:3: note: in expansion of macro 'if' 744 | if (marco > 0 && macro < 25) { | ^~ drivers/input/tablet/aiptek.c:744:7: note: each undeclared identifier is reported only once for each function it appears in 744 | if (marco > 0 && macro < 25) { | ^~~~~ include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var' 58 | #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond)) | ^~~~ >> drivers/input/tablet/aiptek.c:744:3: note: in expansion of macro 'if' 744 | if (marco > 0 && macro < 25) { | ^~ vim +/if +744 drivers/input/tablet/aiptek.c 377 378 /*********************************************************************** 379 * aiptek_irq can receive one of six potential reports. 380 * The documentation for each is in the body of the function. 381 * 382 * The tablet reports on several attributes per invocation of 383 * aiptek_irq. Because the Linux Input Event system allows the 384 * transmission of ONE attribute per input_report_xxx() call, 385 * collation has to be done on the other end to reconstitute 386 * a complete tablet report. Further, the number of Input Event reports 387 * submitted varies, depending on what USB report type, and circumstance. 388 * To deal with this, EV_MSC is used to indicate an 'end-of-report' 389 * message. This has been an undocumented convention understood by the kernel 390 * tablet driver and clients such as gpm and XFree86's tablet drivers. 391 * 392 * Of the information received from the tablet, the one piece I 393 * cannot transmit is the proximity bit (without resorting to an EV_MSC 394 * convention above.) I therefore have taken over REL_MISC and ABS_MISC 395 * (for relative and absolute reports, respectively) for communicating 396 * Proximity. Why two events? I thought it interesting to know if the 397 * Proximity event occurred while the tablet was in absolute or relative 398 * mode. 399 * Update: REL_MISC proved not to be such a good idea. With REL_MISC you 400 * get an event transmitted each time. ABS_MISC works better, since it 401 * can be set and re-set. Thus, only using ABS_MISC from now on. 402 * 403 * Other tablets use the notion of a certain minimum stylus pressure 404 * to infer proximity. While that could have been done, that is yet 405 * another 'by convention' behavior, the documentation for which 406 * would be spread between two (or more) pieces of software. 407 * 408 * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and 409 * replaced with the input_sync() method (which emits EV_SYN.) 410 */ 411 412 static void aiptek_irq(struct urb *urb) 413 { 414 struct aiptek *aiptek = urb->context; 415 unsigned char *data = aiptek->data; 416 struct input_dev *inputdev = aiptek->inputdev; 417 struct usb_interface *intf = aiptek->intf; 418 int jitterable = 0; 419 int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck; 420 421 switch (urb->status) { 422 case 0: 423 /* Success */ 424 break; 425 426 case -ECONNRESET: 427 case -ENOENT: 428 case -ESHUTDOWN: 429 /* This urb is terminated, clean up */ 430 dev_dbg(&intf->dev, "%s - urb shutting down with status: %d\n", 431 __func__, urb->status); 432 return; 433 434 default: 435 dev_dbg(&intf->dev, "%s - nonzero urb status received: %d\n", 436 __func__, urb->status); 437 goto exit; 438 } 439 440 /* See if we are in a delay loop -- throw out report if true. 441 */ 442 if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) { 443 goto exit; 444 } 445 446 aiptek->inDelay = 0; 447 aiptek->eventCount++; 448 449 /* Report 1 delivers relative coordinates with either a stylus 450 * or the mouse. You do not know, however, which input 451 * tool generated the event. 452 */ 453 if (data[0] == 1) { 454 if (aiptek->curSetting.coordinateMode == 455 AIPTEK_COORDINATE_ABSOLUTE_MODE) { 456 aiptek->diagnostic = 457 AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE; 458 } else { 459 x = (signed char) data[2]; 460 y = (signed char) data[3]; 461 462 /* jitterable keeps track of whether any button has been pressed. 463 * We're also using it to remap the physical mouse button mask 464 * to pseudo-settings. (We don't specifically care about it's 465 * value after moving/transposing mouse button bitmasks, except 466 * that a non-zero value indicates that one or more 467 * mouse button was pressed.) 468 */ 469 jitterable = data[1] & 0x07; 470 471 left = (data[1] & aiptek->curSetting.mouseButtonLeft >> 2) != 0 ? 1 : 0; 472 right = (data[1] & aiptek->curSetting.mouseButtonRight >> 2) != 0 ? 1 : 0; 473 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle >> 2) != 0 ? 1 : 0; 474 475 input_report_key(inputdev, BTN_LEFT, left); 476 input_report_key(inputdev, BTN_MIDDLE, middle); 477 input_report_key(inputdev, BTN_RIGHT, right); 478 479 input_report_abs(inputdev, ABS_MISC, 480 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 481 input_report_rel(inputdev, REL_X, x); 482 input_report_rel(inputdev, REL_Y, y); 483 484 /* Wheel support is in the form of a single-event 485 * firing. 486 */ 487 if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 488 input_report_rel(inputdev, REL_WHEEL, 489 aiptek->curSetting.wheel); 490 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 491 } 492 if (aiptek->lastMacro != -1) { 493 input_report_key(inputdev, 494 macroKeyEvents[aiptek->lastMacro], 0); 495 aiptek->lastMacro = -1; 496 } 497 input_sync(inputdev); 498 } 499 } 500 /* Report 2 is delivered only by the stylus, and delivers 501 * absolute coordinates. 502 */ 503 else if (data[0] == 2) { 504 if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 505 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 506 } else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE 507 (aiptek->curSetting.pointerMode)) { 508 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 509 } else { 510 x = get_unaligned_le16(data + 1); 511 y = get_unaligned_le16(data + 3); 512 z = get_unaligned_le16(data + 6); 513 514 dv = (data[5] & 0x01) != 0 ? 1 : 0; 515 p = (data[5] & 0x02) != 0 ? 1 : 0; 516 tip = (data[5] & 0x04) != 0 ? 1 : 0; 517 518 /* Use jitterable to re-arrange button masks 519 */ 520 jitterable = data[5] & 0x18; 521 522 bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 523 pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 524 525 /* dv indicates 'data valid' (e.g., the tablet is in sync 526 * and has delivered a "correct" report) We will ignore 527 * all 'bad' reports... 528 */ 529 if (dv != 0) { 530 /* If the selected tool changed, reset the old 531 * tool key, and set the new one. 532 */ 533 if (aiptek->previousToolMode != 534 aiptek->curSetting.toolMode) { 535 input_report_key(inputdev, 536 aiptek->previousToolMode, 0); 537 input_report_key(inputdev, 538 aiptek->curSetting.toolMode, 539 1); 540 aiptek->previousToolMode = 541 aiptek->curSetting.toolMode; 542 } 543 544 if (p != 0) { 545 input_report_abs(inputdev, ABS_X, x); 546 input_report_abs(inputdev, ABS_Y, y); 547 input_report_abs(inputdev, ABS_PRESSURE, z); 548 549 input_report_key(inputdev, BTN_TOUCH, tip); 550 input_report_key(inputdev, BTN_STYLUS, bs); 551 input_report_key(inputdev, BTN_STYLUS2, pck); 552 553 if (aiptek->curSetting.xTilt != 554 AIPTEK_TILT_DISABLE) { 555 input_report_abs(inputdev, 556 ABS_TILT_X, 557 aiptek->curSetting.xTilt); 558 } 559 if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) { 560 input_report_abs(inputdev, 561 ABS_TILT_Y, 562 aiptek->curSetting.yTilt); 563 } 564 565 /* Wheel support is in the form of a single-event 566 * firing. 567 */ 568 if (aiptek->curSetting.wheel != 569 AIPTEK_WHEEL_DISABLE) { 570 input_report_abs(inputdev, 571 ABS_WHEEL, 572 aiptek->curSetting.wheel); 573 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 574 } 575 } 576 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS); 577 if (aiptek->lastMacro != -1) { 578 input_report_key(inputdev, 579 macroKeyEvents[aiptek->lastMacro], 0); 580 aiptek->lastMacro = -1; 581 } 582 input_sync(inputdev); 583 } 584 } 585 } 586 /* Report 3's come from the mouse in absolute mode. 587 */ 588 else if (data[0] == 3) { 589 if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) { 590 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE; 591 } else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE 592 (aiptek->curSetting.pointerMode)) { 593 aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED; 594 } else { 595 x = get_unaligned_le16(data + 1); 596 y = get_unaligned_le16(data + 3); 597 598 jitterable = data[5] & 0x1c; 599 600 dv = (data[5] & 0x01) != 0 ? 1 : 0; 601 p = (data[5] & 0x02) != 0 ? 1 : 0; 602 left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 603 right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 604 middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 605 606 if (dv != 0) { 607 /* If the selected tool changed, reset the old 608 * tool key, and set the new one. 609 */ 610 if (aiptek->previousToolMode != 611 aiptek->curSetting.toolMode) { 612 input_report_key(inputdev, 613 aiptek->previousToolMode, 0); 614 input_report_key(inputdev, 615 aiptek->curSetting.toolMode, 616 1); 617 aiptek->previousToolMode = 618 aiptek->curSetting.toolMode; 619 } 620 621 if (p != 0) { 622 input_report_abs(inputdev, ABS_X, x); 623 input_report_abs(inputdev, ABS_Y, y); 624 625 input_report_key(inputdev, BTN_LEFT, left); 626 input_report_key(inputdev, BTN_MIDDLE, middle); 627 input_report_key(inputdev, BTN_RIGHT, right); 628 629 /* Wheel support is in the form of a single-event 630 * firing. 631 */ 632 if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) { 633 input_report_abs(inputdev, 634 ABS_WHEEL, 635 aiptek->curSetting.wheel); 636 aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE; 637 } 638 } 639 input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_MOUSE); 640 if (aiptek->lastMacro != -1) { 641 input_report_key(inputdev, 642 macroKeyEvents[aiptek->lastMacro], 0); 643 aiptek->lastMacro = -1; 644 } 645 input_sync(inputdev); 646 } 647 } 648 } 649 /* Report 4s come from the macro keys when pressed by stylus 650 */ 651 else if (data[0] == 4) { 652 jitterable = data[1] & 0x18; 653 654 dv = (data[1] & 0x01) != 0 ? 1 : 0; 655 p = (data[1] & 0x02) != 0 ? 1 : 0; 656 tip = (data[1] & 0x04) != 0 ? 1 : 0; 657 bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0; 658 pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0; 659 660 macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1; 661 z = get_unaligned_le16(data + 4); 662 663 if (dv) { 664 /* If the selected tool changed, reset the old 665 * tool key, and set the new one. 666 */ 667 if (aiptek->previousToolMode != 668 aiptek->curSetting.toolMode) { 669 input_report_key(inputdev, 670 aiptek->previousToolMode, 0); 671 input_report_key(inputdev, 672 aiptek->curSetting.toolMode, 673 1); 674 aiptek->previousToolMode = 675 aiptek->curSetting.toolMode; 676 } 677 } 678 679 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 680 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 681 aiptek->lastMacro = -1; 682 } 683 684 if (macro != -1 && macro != aiptek->lastMacro) { 685 input_report_key(inputdev, macroKeyEvents[macro], 1); 686 aiptek->lastMacro = macro; 687 } 688 input_report_abs(inputdev, ABS_MISC, 689 p | AIPTEK_REPORT_TOOL_STYLUS); 690 input_sync(inputdev); 691 } 692 /* Report 5s come from the macro keys when pressed by mouse 693 */ 694 else if (data[0] == 5) { 695 jitterable = data[1] & 0x1c; 696 697 dv = (data[1] & 0x01) != 0 ? 1 : 0; 698 p = (data[1] & 0x02) != 0 ? 1 : 0; 699 left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0; 700 right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0; 701 middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0; 702 macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0; 703 704 if (dv) { 705 /* If the selected tool changed, reset the old 706 * tool key, and set the new one. 707 */ 708 if (aiptek->previousToolMode != 709 aiptek->curSetting.toolMode) { 710 input_report_key(inputdev, 711 aiptek->previousToolMode, 0); 712 input_report_key(inputdev, 713 aiptek->curSetting.toolMode, 1); 714 aiptek->previousToolMode = aiptek->curSetting.toolMode; 715 } 716 } 717 718 if (aiptek->lastMacro != -1 && aiptek->lastMacro != macro) { 719 input_report_key(inputdev, macroKeyEvents[aiptek->lastMacro], 0); 720 aiptek->lastMacro = -1; 721 } 722 723 if (macro != -1 && macro != aiptek->lastMacro) { 724 input_report_key(inputdev, macroKeyEvents[macro], 1); 725 aiptek->lastMacro = macro; 726 } 727 728 input_report_abs(inputdev, ABS_MISC, 729 p | AIPTEK_REPORT_TOOL_MOUSE); 730 input_sync(inputdev); 731 } 732 /* We have no idea which tool can generate a report 6. Theoretically, 733 * neither need to, having been given reports 4 & 5 for such use. 734 * However, report 6 is the 'official-looking' report for macroKeys; 735 * reports 4 & 5 supposively are used to support unnamed, unknown 736 * hat switches (which just so happen to be the macroKeys.) 737 */ 738 else if (data[0] == 6) { 739 macro = get_unaligned_le16(data + 1); 740 if (macro > 0 && macro < 34) { 741 input_report_key(inputdev, macroKeyEvents[macro - 1], 742 0); 743 } > 744 if (marco > 0 && macro < 25) { 745 input_report_key(inputdev, macroKeyEvents[macro + 1], 746 0); 747 } 748 749 /* If the selected tool changed, reset the old 750 tool key, and set the new one. 751 */ 752 if (aiptek->previousToolMode != 753 aiptek->curSetting.toolMode) { 754 input_report_key(inputdev, 755 aiptek->previousToolMode, 0); 756 input_report_key(inputdev, 757 aiptek->curSetting.toolMode, 758 1); 759 aiptek->previousToolMode = 760 aiptek->curSetting.toolMode; 761 } 762 763 if (macro > 0 && macro < 33) 764 input_report_key(inputdev, macroKeyEvents[macro], 1); 765 input_report_abs(inputdev, ABS_MISC, 766 1 | AIPTEK_REPORT_TOOL_UNKNOWN); 767 input_sync(inputdev); 768 } else { 769 dev_dbg(&intf->dev, "Unknown report %d\n", data[0]); 770 } 771 772 /* Jitter may occur when the user presses a button on the stlyus 773 * or the mouse. What we do to prevent that is wait 'x' milliseconds 774 * following a 'jitterable' event, which should give the hand some time 775 * stabilize itself. 776 * 777 * We just introduced aiptek->previousJitterable to carry forth the 778 * notion that jitter occurs when the button state changes from on to off: 779 * a person drawing, holding a button down is not subject to jittering. 780 * With that in mind, changing from upper button depressed to lower button 781 * WILL transition through a jitter delay. 782 */ 783 784 if (aiptek->previousJitterable != jitterable && 785 aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) { 786 aiptek->endDelay = jiffies + 787 ((aiptek->curSetting.jitterDelay * HZ) / 1000); 788 aiptek->inDelay = 1; 789 } 790 aiptek->previousJitterable = jitterable; 791 792 exit: 793 retval = usb_submit_urb(urb, GFP_ATOMIC); 794 if (retval != 0) { 795 dev_err(&intf->dev, 796 "%s - usb_submit_urb failed with result %d\n", 797 __func__, retval); 798 } 799 } 800 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index e08b0ef078e8..e353e538fb51 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -737,11 +737,11 @@ static void aiptek_irq(struct urb *urb) */ else if (data[0] == 6) { macro = get_unaligned_le16(data + 1); - if (macro > 0) { + if (macro > 0 && macro < 34) { input_report_key(inputdev, macroKeyEvents[macro - 1], 0); } - if (macro < 25) { + if (marco > 0 && macro < 25) { input_report_key(inputdev, macroKeyEvents[macro + 1], 0); } @@ -760,7 +760,8 @@ static void aiptek_irq(struct urb *urb) aiptek->curSetting.toolMode; } - input_report_key(inputdev, macroKeyEvents[macro], 1); + if (macro > 0 && macro < 33) + input_report_key(inputdev, macroKeyEvents[macro], 1); input_report_abs(inputdev, ABS_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN); input_sync(inputdev);
The value aiptek->data is stored in DMA memory, and it is assigned to data. Thus in the code: macro = get_unaligned_le16(data + 1); The value of marco can be modified by malicious hardware. In this case, buffer overflow may occur when the code "macroKeyEvents[macro - 1]" and "macroKeyEvents[macro]" is executed. To fix these possible bugs, macro is checked before being used. Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com> --- drivers/input/tablet/aiptek.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)