Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.12-rc4 237 lines 5.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2022-2024 Red Hat */ 3 4#include "hid_common.h" 5 6/* for older kernels */ 7#ifndef HIDIOCREVOKE 8#define HIDIOCREVOKE _IOW('H', 0x0D, int) /* Revoke device access */ 9#endif /* HIDIOCREVOKE */ 10 11FIXTURE(hidraw) { 12 int dev_id; 13 int uhid_fd; 14 int hidraw_fd; 15 int hid_id; 16 pthread_t tid; 17}; 18static void close_hidraw(FIXTURE_DATA(hidraw) * self) 19{ 20 if (self->hidraw_fd) 21 close(self->hidraw_fd); 22 self->hidraw_fd = 0; 23} 24 25FIXTURE_TEARDOWN(hidraw) { 26 void *uhid_err; 27 28 uhid_destroy(_metadata, self->uhid_fd); 29 30 close_hidraw(self); 31 pthread_join(self->tid, &uhid_err); 32} 33#define TEARDOWN_LOG(fmt, ...) do { \ 34 TH_LOG(fmt, ##__VA_ARGS__); \ 35 hidraw_teardown(_metadata, self, variant); \ 36} while (0) 37 38FIXTURE_SETUP(hidraw) 39{ 40 time_t t; 41 int err; 42 43 /* initialize random number generator */ 44 srand((unsigned int)time(&t)); 45 46 self->dev_id = rand() % 1024; 47 48 self->uhid_fd = setup_uhid(_metadata, self->dev_id); 49 50 /* locate the uev, self, variant);ent file of the created device */ 51 self->hid_id = get_hid_id(self->dev_id); 52 ASSERT_GT(self->hid_id, 0) 53 TEARDOWN_LOG("Could not locate uhid device id: %d", self->hid_id); 54 55 err = uhid_start_listener(_metadata, &self->tid, self->uhid_fd); 56 ASSERT_EQ(0, err) TEARDOWN_LOG("could not start udev listener: %d", err); 57 58 self->hidraw_fd = open_hidraw(self->dev_id); 59 ASSERT_GE(self->hidraw_fd, 0) TH_LOG("open_hidraw"); 60} 61 62/* 63 * A simple test to see if the fixture is working fine. 64 * If this fails, none of the other tests will pass. 65 */ 66TEST_F(hidraw, test_create_uhid) 67{ 68} 69 70/* 71 * Inject one event in the uhid device, 72 * check that we get the same data through hidraw 73 */ 74TEST_F(hidraw, raw_event) 75{ 76 __u8 buf[10] = {0}; 77 int err; 78 79 /* inject one event */ 80 buf[0] = 1; 81 buf[1] = 42; 82 uhid_send_event(_metadata, self->uhid_fd, buf, 6); 83 84 /* read the data from hidraw */ 85 memset(buf, 0, sizeof(buf)); 86 err = read(self->hidraw_fd, buf, sizeof(buf)); 87 ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); 88 ASSERT_EQ(buf[0], 1); 89 ASSERT_EQ(buf[1], 42); 90} 91 92/* 93 * After initial opening/checks of hidraw, revoke the hidraw 94 * node and check that we can not read any more data. 95 */ 96TEST_F(hidraw, raw_event_revoked) 97{ 98 __u8 buf[10] = {0}; 99 int err; 100 101 /* inject one event */ 102 buf[0] = 1; 103 buf[1] = 42; 104 uhid_send_event(_metadata, self->uhid_fd, buf, 6); 105 106 /* read the data from hidraw */ 107 memset(buf, 0, sizeof(buf)); 108 err = read(self->hidraw_fd, buf, sizeof(buf)); 109 ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); 110 ASSERT_EQ(buf[0], 1); 111 ASSERT_EQ(buf[1], 42); 112 113 /* call the revoke ioctl */ 114 err = ioctl(self->hidraw_fd, HIDIOCREVOKE, NULL); 115 ASSERT_OK(err) TH_LOG("couldn't revoke the hidraw fd"); 116 117 /* inject one other event */ 118 buf[0] = 1; 119 buf[1] = 43; 120 uhid_send_event(_metadata, self->uhid_fd, buf, 6); 121 122 /* read the data from hidraw */ 123 memset(buf, 0, sizeof(buf)); 124 err = read(self->hidraw_fd, buf, sizeof(buf)); 125 ASSERT_EQ(err, -1) TH_LOG("read_hidraw"); 126 ASSERT_EQ(errno, ENODEV) TH_LOG("unexpected error code while reading the hidraw node: %d", 127 errno); 128} 129 130/* 131 * Revoke the hidraw node and check that we can not do any ioctl. 132 */ 133TEST_F(hidraw, ioctl_revoked) 134{ 135 int err, desc_size = 0; 136 137 /* call the revoke ioctl */ 138 err = ioctl(self->hidraw_fd, HIDIOCREVOKE, NULL); 139 ASSERT_OK(err) TH_LOG("couldn't revoke the hidraw fd"); 140 141 /* do an ioctl */ 142 err = ioctl(self->hidraw_fd, HIDIOCGRDESCSIZE, &desc_size); 143 ASSERT_EQ(err, -1) TH_LOG("ioctl_hidraw"); 144 ASSERT_EQ(errno, ENODEV) TH_LOG("unexpected error code while doing an ioctl: %d", 145 errno); 146} 147 148/* 149 * Setup polling of the fd, and check that revoke works properly. 150 */ 151TEST_F(hidraw, poll_revoked) 152{ 153 struct pollfd pfds[1]; 154 __u8 buf[10] = {0}; 155 int err, ready; 156 157 /* setup polling */ 158 pfds[0].fd = self->hidraw_fd; 159 pfds[0].events = POLLIN; 160 161 /* inject one event */ 162 buf[0] = 1; 163 buf[1] = 42; 164 uhid_send_event(_metadata, self->uhid_fd, buf, 6); 165 166 while (true) { 167 ready = poll(pfds, 1, 5000); 168 ASSERT_EQ(ready, 1) TH_LOG("poll return value"); 169 170 if (pfds[0].revents & POLLIN) { 171 memset(buf, 0, sizeof(buf)); 172 err = read(self->hidraw_fd, buf, sizeof(buf)); 173 ASSERT_EQ(err, 6) TH_LOG("read_hidraw"); 174 ASSERT_EQ(buf[0], 1); 175 ASSERT_EQ(buf[1], 42); 176 177 /* call the revoke ioctl */ 178 err = ioctl(self->hidraw_fd, HIDIOCREVOKE, NULL); 179 ASSERT_OK(err) TH_LOG("couldn't revoke the hidraw fd"); 180 } else { 181 break; 182 } 183 } 184 185 ASSERT_TRUE(pfds[0].revents & POLLHUP); 186} 187 188/* 189 * After initial opening/checks of hidraw, revoke the hidraw 190 * node and check that we can not read any more data. 191 */ 192TEST_F(hidraw, write_event_revoked) 193{ 194 struct timespec time_to_wait; 195 __u8 buf[10] = {0}; 196 int err; 197 198 /* inject one event from hidraw */ 199 buf[0] = 1; /* report ID */ 200 buf[1] = 2; 201 buf[2] = 42; 202 203 pthread_mutex_lock(&uhid_output_mtx); 204 205 memset(output_report, 0, sizeof(output_report)); 206 clock_gettime(CLOCK_REALTIME, &time_to_wait); 207 time_to_wait.tv_sec += 2; 208 209 err = write(self->hidraw_fd, buf, 3); 210 ASSERT_EQ(err, 3) TH_LOG("unexpected error while writing to hidraw node: %d", err); 211 212 err = pthread_cond_timedwait(&uhid_output_cond, &uhid_output_mtx, &time_to_wait); 213 ASSERT_OK(err) TH_LOG("error while calling waiting for the condition"); 214 215 ASSERT_EQ(output_report[0], 1); 216 ASSERT_EQ(output_report[1], 2); 217 ASSERT_EQ(output_report[2], 42); 218 219 /* call the revoke ioctl */ 220 err = ioctl(self->hidraw_fd, HIDIOCREVOKE, NULL); 221 ASSERT_OK(err) TH_LOG("couldn't revoke the hidraw fd"); 222 223 /* inject one other event */ 224 buf[0] = 1; 225 buf[1] = 43; 226 err = write(self->hidraw_fd, buf, 3); 227 ASSERT_LT(err, 0) TH_LOG("unexpected success while writing to hidraw node: %d", err); 228 ASSERT_EQ(errno, ENODEV) TH_LOG("unexpected error code while writing to hidraw node: %d", 229 errno); 230 231 pthread_mutex_unlock(&uhid_output_mtx); 232} 233 234int main(int argc, char **argv) 235{ 236 return test_harness_run(argc, argv); 237}