Skip to content

Commit bf81de7

Browse files
committed
selftests: hid: import hid-tools usb-crash tests
These tests have been developed in the hid-tools[0] tree for a while. Now that we have a proper selftests/hid kernel entry and that the tests are more reliable, it is time to directly include those in the kernel tree. This one gets skipped when run by vmtest.sh as we currently need to test against actual kernel modules (.ko), not built-in to fetch the list of supported devices. [0] https://gitlab.freedesktop.org/libevdev/hid-tools Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent a4ee40b commit bf81de7

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

tools/testing/selftests/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ TEST_PROGS += hid-mouse.sh
1414
TEST_PROGS += hid-multitouch.sh
1515
TEST_PROGS += hid-sony.sh
1616
TEST_PROGS += hid-tablet.sh
17+
TEST_PROGS += hid-usb_crash.sh
1718
TEST_PROGS += hid-wacom.sh
1819

1920
CXX ?= $(CROSS_COMPILE)g++
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
# SPDX-License-Identifier: GPL-2.0
3+
# Runs tests for the HID subsystem
4+
5+
export TARGET=test_usb_crash.py
6+
7+
bash ./run-hid-tools-tests.sh
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/env python3
2+
# SPDX-License-Identifier: GPL-2.0
3+
# -*- coding: utf-8 -*-
4+
#
5+
# Copyright (c) 2021 Benjamin Tissoires <[email protected]>
6+
# Copyright (c) 2021 Red Hat, Inc.
7+
#
8+
9+
# This is to ensure we don't crash when emulating USB devices
10+
11+
from . import base
12+
import pytest
13+
import logging
14+
15+
logger = logging.getLogger("hidtools.test.usb")
16+
17+
18+
class USBDev(base.UHIDTestDevice):
19+
# fmt: off
20+
report_descriptor = [
21+
0x05, 0x01, # .Usage Page (Generic Desktop) 0
22+
0x09, 0x02, # .Usage (Mouse) 2
23+
0xa1, 0x01, # .Collection (Application) 4
24+
0x09, 0x02, # ..Usage (Mouse) 6
25+
0xa1, 0x02, # ..Collection (Logical) 8
26+
0x09, 0x01, # ...Usage (Pointer) 10
27+
0xa1, 0x00, # ...Collection (Physical) 12
28+
0x05, 0x09, # ....Usage Page (Button) 14
29+
0x19, 0x01, # ....Usage Minimum (1) 16
30+
0x29, 0x03, # ....Usage Maximum (3) 18
31+
0x15, 0x00, # ....Logical Minimum (0) 20
32+
0x25, 0x01, # ....Logical Maximum (1) 22
33+
0x75, 0x01, # ....Report Size (1) 24
34+
0x95, 0x03, # ....Report Count (3) 26
35+
0x81, 0x02, # ....Input (Data,Var,Abs) 28
36+
0x75, 0x05, # ....Report Size (5) 30
37+
0x95, 0x01, # ....Report Count (1) 32
38+
0x81, 0x03, # ....Input (Cnst,Var,Abs) 34
39+
0x05, 0x01, # ....Usage Page (Generic Desktop) 36
40+
0x09, 0x30, # ....Usage (X) 38
41+
0x09, 0x31, # ....Usage (Y) 40
42+
0x15, 0x81, # ....Logical Minimum (-127) 42
43+
0x25, 0x7f, # ....Logical Maximum (127) 44
44+
0x75, 0x08, # ....Report Size (8) 46
45+
0x95, 0x02, # ....Report Count (2) 48
46+
0x81, 0x06, # ....Input (Data,Var,Rel) 50
47+
0xc0, # ...End Collection 52
48+
0xc0, # ..End Collection 53
49+
0xc0, # .End Collection 54
50+
]
51+
# fmt: on
52+
53+
def __init__(self, name=None, input_info=None):
54+
super().__init__(
55+
name, "Mouse", input_info=input_info, rdesc=USBDev.report_descriptor
56+
)
57+
58+
# skip witing for udev events, it's likely that the report
59+
# descriptor is wrong
60+
def is_ready(self):
61+
return True
62+
63+
# we don't have an evdev node here, so paper over
64+
# the checks
65+
def get_evdev(self, application=None):
66+
return "OK"
67+
68+
69+
class TestUSBDevice(base.BaseTestCase.TestUhid):
70+
"""
71+
Test class to test if an emulated USB device crashes
72+
the kernel.
73+
"""
74+
75+
# conftest.py is generating the following fixture:
76+
#
77+
# @pytest.fixture(params=[('modulename', 1, 2)])
78+
# def usbVidPid(self, request):
79+
# return request.param
80+
81+
@pytest.fixture()
82+
def new_uhdev(self, usbVidPid, request):
83+
self.module, self.vid, self.pid = usbVidPid
84+
self._load_kernel_module(None, self.module)
85+
return USBDev(input_info=(3, self.vid, self.pid))
86+
87+
def test_creation(self):
88+
"""
89+
inject the USB dev through uhid and immediately see if there is a crash:
90+
91+
uhid can create a USB device with the BUS_USB bus, and some
92+
drivers assume that they can then access USB related structures
93+
when they are actually provided a uhid device. This leads to
94+
a crash because those access result in a segmentation fault.
95+
96+
The kernel should not crash on any (random) user space correct
97+
use of its API. So run through all available modules and declared
98+
devices to see if we can generate a uhid device without a crash.
99+
100+
The test is empty as the fixture `check_taint` is doing the job (and
101+
honestly, when the kernel crashes, the whole machine freezes).
102+
"""
103+
assert True

0 commit comments

Comments
 (0)