Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 340bd9b6 authored by Harry Cutts's avatar Harry Cutts
Browse files

EventHub: abort if device disappears while opening

Connecting an input device for a brief period of time — long enough
for EventHub::openDeviceLocked to open its FD and give it a class, but
not long enough for it to cache all of its absolute axis information —
can cause InputReader to crash. This happens when a mapper looks up
information for an absolute axis that it should be able to depend on,
but finds it missing. For example, TouchpadInputMapper depends on the
device having ABS_MT_POSITION_X and _Y axes, since these are required
for the device to receive InputDeviceClass::TOUCHPAD, but if this
race condition occurs those axes may not be present.

Since we're already caching all of the absolute axis information during
opening, we can just stop opening the device if we detect that it's
gone, allowing mappers to safely assume that all of the absolute axes
required for a device to be given its class will have information
available through EventHub::getAbsoluteAxisInfo.

It's still possible that the device could be removed after
openDeviceLocked finishes but before the mappers initialize themselves
using the axis information. However, in that case the information will
already have been cached, so the worst that will happen is that we'll
initialize some mappers unnecessarily and then immediately destroy them.

Test: create test-fast-disconnect.json with the following contents:
      {
          "id": 1, "command": "register",
          "name": "BADLY CONNECTED TOUCHPAD",
          "vid": 0x18d1, "pid": 0xbaad, "bus": "usb",
          "configuration": [
              {"type": "UI_SET_EVBIT", "data":["EV_KEY", "EV_ABS"]},
              {"type": "UI_SET_KEYBIT",
	       "data": ["BTN_LEFT", "BTN_TOUCH", "BTN_TOOL_FINGER"]},
              {"type": "UI_SET_ABSBIT",
	       "data": ["ABS_X", "ABS_Y", "ABS_MT_SLOT",
	                "ABS_MT_POSITION_X", "ABS_MT_POSITION_Y",
		        "ABS_MT_TRACKING_ID"]},
              {"type": "UI_SET_PROPBIT",
	       "data": ["INPUT_PROP_POINTER", "INPUT_PROP_BUTTONPAD"]}
          ],
          "abs_info": [
              {"code": "ABS_X",
	       "info": {"value":0, "minimum":-255, "maximum":255,
	                "fuzz":0, "flat":0, "resolution":1}},
              {"code": "ABS_Y",
	       "info": {"value":0, "minimum":-255, "maximum":255,
	                "fuzz":0, "flat":0, "resolution":1}},
              {"code": "ABS_MT_SLOT",
	       "info": {"value":0, "minimum":0, "maximum":4, "fuzz":0,
	                "flat":0, "resolution":0}},
              {"code": "ABS_MT_POSITION_X",
	       "info": {"value":0, "minimum":0, "maximum":1, "fuzz":0,
	                "flat":0, "resolution":1}},
              {"code": "ABS_MT_POSITION_Y",
	       "info": {"value":0, "minimum":0, "maximum":1, "fuzz":0,
	                "flat":0, "resolution":1}},
              {"code": "ABS_MT_TRACKING_ID",
	       "info": {"value":0, "minimum":0, "maximum":65535,
	                "fuzz":0, "flat":0, "resolution":0}}
          ]
      }
      Then pipe it to uinput:
      $ adb shell uinput - < test-fast-disconnect.json
      and check that the device does not crash. Check that the "removed
      while opening" line is logged, to confirm that the fix is taking
      effect rather than the timing just being nice for this case. (You
      may have to repeat the uinput command a few times to see this.)
Bug: 424789999
Flag: com.android.input.flags.abort_device_opening_on_enodev
Change-Id: I8d7468eddd64854ff5b15986815999969388b375
parent d12ae836
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment