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