commit 6058545df3aa5b31db050b5cad1f6090c811c38c Author: Vladimir Kondratyev Date: Sun Jun 2 12:37:43 2019 +0300 psm(4): Add extra sanity checks to Elantech trackpoint support diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c index 5da0c3f666d4..d93eb04c4e2d 100644 --- a/sys/dev/atkbdc/psm.c +++ b/sys/dev/atkbdc/psm.c @@ -4629,7 +4629,7 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, case ELANTECH_PKT_TRACKPOINT: /* 7 6 5 4 3 2 1 0 (LSB) * ------------------------------------------- - * ipacket[0]: 0 0 SX SY 0 M R L + * ipacket[0]: 0 0 SY SX 0 M R L * ipacket[1]: ~SX 0 0 0 0 0 0 0 * ipacket[2]: ~SY 0 0 0 0 0 0 0 * ipacket[3]: 0 0 ~SY ~SX 0 1 1 0 @@ -4640,22 +4640,34 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms, * over 9 bits with SX/SY the relative top bit and * X7..X0 and Y7..Y0 the lower bits. */ - *x = (pb->ipacket[0] & 0x20) ? - pb->ipacket[4] - 256 : pb->ipacket[4]; - *y = (pb->ipacket[0] & 0x10) ? - pb->ipacket[5] - 256 : pb->ipacket[5]; - trackpoint_button = - ((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) | - ((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0) | - ((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0); + /* Check zeros for presence and sign bits for equality */ + if (!(pb->ipacket[0] & 0xC8) && !(pb->ipacket[1] & 0x7F) && + !(pb->ipacket[2] & 0x7F) && !(pb->ipacket[3] & 0xC9) && + !(pb->ipacket[0] & 0x10) != !(pb->ipacket[1] & 0x80) && + !(pb->ipacket[0] & 0x10) != !(pb->ipacket[3] & 0x10) && + !(pb->ipacket[0] & 0x20) != !(pb->ipacket[2] & 0x80) && + !(pb->ipacket[0] & 0x20) != !(pb->ipacket[3] & 0x20)) { + + *x = (pb->ipacket[0] & MOUSE_PS2_XNEG) ? + pb->ipacket[4] - 256 : pb->ipacket[4]; + *y = (pb->ipacket[0] & MOUSE_PS2_YNEG) ? + pb->ipacket[5] - 256 : pb->ipacket[5]; + + trackpoint_button = + ((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) | + ((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0) | + ((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0); #ifdef EVDEV_SUPPORT - evdev_push_rel(sc->evdev_r, REL_X, *x); - evdev_push_rel(sc->evdev_r, REL_Y, -*y); - evdev_push_mouse_btn(sc->evdev_r, trackpoint_button); - evdev_sync(sc->evdev_r); + evdev_push_rel(sc->evdev_r, REL_X, *x); + evdev_push_rel(sc->evdev_r, REL_Y, -*y); + evdev_push_mouse_btn(sc->evdev_r, trackpoint_button); + evdev_sync(sc->evdev_r); #endif - ms->button = touchpad_button | trackpoint_button; + ms->button = touchpad_button | trackpoint_button; + } else + VLOG(3, (LOG_DEBUG, "elantech: " + "unexpected trackpoint packet skipped\n")); return (0); case ELANTECH_PKT_NOP: