diff mbox series

input: tablet: aiptek: fix possible buffer overflow caused by bad DMA value in aiptek_irq()

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

Commit Message

Jia-Ju Bai May 30, 2020, 7:39 a.m. UTC
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(-)

Comments

kernel test robot June 1, 2020, 2:03 a.m. UTC | #1
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
kernel test robot June 1, 2020, 3:55 a.m. UTC | #2
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 mbox series

Patch

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);