1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 #include "vmlinux.h" 3 #include "vmlinux.h" 4 #include <bpf/bpf_helpers.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_tracing.h> 5 #include <bpf/bpf_tracing.h> 6 #include "hid_bpf_helpers.h" 6 #include "hid_bpf_helpers.h" 7 7 8 static int hid_y_event(struct hid_bpf_ctx *hct !! 8 SEC("fmod_ret/hid_bpf_device_event") >> 9 int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx) 9 { 10 { 10 s16 y; 11 s16 y; 11 __u8 *data = hid_bpf_get_data(hctx, 0 12 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 12 13 13 if (!data) 14 if (!data) 14 return 0; /* EPERM check */ 15 return 0; /* EPERM check */ 15 16 16 bpf_printk("event: size: %d", hctx->si 17 bpf_printk("event: size: %d", hctx->size); 17 bpf_printk("incoming event: %02x %02x 18 bpf_printk("incoming event: %02x %02x %02x", 18 data[0], 19 data[0], 19 data[1], 20 data[1], 20 data[2]); 21 data[2]); 21 bpf_printk(" %02x %02x 22 bpf_printk(" %02x %02x %02x", 22 data[3], 23 data[3], 23 data[4], 24 data[4], 24 data[5]); 25 data[5]); 25 bpf_printk(" %02x %02x 26 bpf_printk(" %02x %02x %02x", 26 data[6], 27 data[6], 27 data[7], 28 data[7], 28 data[8]); 29 data[8]); 29 30 30 y = data[3] | (data[4] << 8); 31 y = data[3] | (data[4] << 8); 31 32 32 y = -y; 33 y = -y; 33 34 34 data[3] = y & 0xFF; 35 data[3] = y & 0xFF; 35 data[4] = (y >> 8) & 0xFF; 36 data[4] = (y >> 8) & 0xFF; 36 37 37 bpf_printk("modified event: %02x %02x 38 bpf_printk("modified event: %02x %02x %02x", 38 data[0], 39 data[0], 39 data[1], 40 data[1], 40 data[2]); 41 data[2]); 41 bpf_printk(" %02x %02x 42 bpf_printk(" %02x %02x %02x", 42 data[3], 43 data[3], 43 data[4], 44 data[4], 44 data[5]); 45 data[5]); 45 bpf_printk(" %02x %02x 46 bpf_printk(" %02x %02x %02x", 46 data[6], 47 data[6], 47 data[7], 48 data[7], 48 data[8]); 49 data[8]); 49 50 50 return 0; 51 return 0; 51 } 52 } 52 53 53 static int hid_x_event(struct hid_bpf_ctx *hct !! 54 SEC("fmod_ret/hid_bpf_device_event") >> 55 int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx) 54 { 56 { 55 s16 x; 57 s16 x; 56 __u8 *data = hid_bpf_get_data(hctx, 0 58 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */); 57 59 58 if (!data) 60 if (!data) 59 return 0; /* EPERM check */ 61 return 0; /* EPERM check */ 60 62 61 x = data[1] | (data[2] << 8); 63 x = data[1] | (data[2] << 8); 62 64 63 x = -x; 65 x = -x; 64 66 65 data[1] = x & 0xFF; 67 data[1] = x & 0xFF; 66 data[2] = (x >> 8) & 0xFF; 68 data[2] = (x >> 8) & 0xFF; 67 return 0; 69 return 0; 68 } 70 } 69 71 70 SEC("struct_ops/hid_device_event") !! 72 SEC("fmod_ret/hid_bpf_rdesc_fixup") 71 int BPF_PROG(hid_event, struct hid_bpf_ctx *hc << 72 { << 73 int ret = hid_y_event(hctx); << 74 << 75 if (ret) << 76 return ret; << 77 << 78 return hid_x_event(hctx); << 79 } << 80 << 81 << 82 SEC("struct_ops/hid_rdesc_fixup") << 83 int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_c 73 int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) 84 { 74 { 85 __u8 *data = hid_bpf_get_data(hctx, 0 75 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */); 86 76 87 if (!data) 77 if (!data) 88 return 0; /* EPERM check */ 78 return 0; /* EPERM check */ 89 79 90 bpf_printk("rdesc: %02x %02x %02x", 80 bpf_printk("rdesc: %02x %02x %02x", 91 data[0], 81 data[0], 92 data[1], 82 data[1], 93 data[2]); 83 data[2]); 94 bpf_printk(" %02x %02x %02x", 84 bpf_printk(" %02x %02x %02x", 95 data[3], 85 data[3], 96 data[4], 86 data[4], 97 data[5]); 87 data[5]); 98 bpf_printk(" %02x %02x %02x ..." 88 bpf_printk(" %02x %02x %02x ...", 99 data[6], 89 data[6], 100 data[7], 90 data[7], 101 data[8]); 91 data[8]); 102 92 103 /* 93 /* 104 * The original report descriptor cont 94 * The original report descriptor contains: 105 * 95 * 106 * 0x05, 0x01, // 96 * 0x05, 0x01, // Usage Page (Generic Desktop) 30 107 * 0x16, 0x01, 0x80, // 97 * 0x16, 0x01, 0x80, // Logical Minimum (-32767) 32 108 * 0x26, 0xff, 0x7f, // 98 * 0x26, 0xff, 0x7f, // Logical Maximum (32767) 35 109 * 0x09, 0x30, // 99 * 0x09, 0x30, // Usage (X) 38 110 * 0x09, 0x31, // 100 * 0x09, 0x31, // Usage (Y) 40 111 * 101 * 112 * So byte 39 contains Usage X and byt 102 * So byte 39 contains Usage X and byte 41 Usage Y. 113 * 103 * 114 * We simply swap the axes here. 104 * We simply swap the axes here. 115 */ 105 */ 116 data[39] = 0x31; 106 data[39] = 0x31; 117 data[41] = 0x30; 107 data[41] = 0x30; 118 108 119 return 0; 109 return 0; 120 } 110 } 121 << 122 SEC(".struct_ops.link") << 123 struct hid_bpf_ops mouse_invert = { << 124 .hid_rdesc_fixup = (void *)hid_rdesc_f << 125 .hid_device_event = (void *)hid_event, << 126 }; << 127 111 128 char _license[] SEC("license") = "GPL"; 112 char _license[] SEC("license") = "GPL"; 129 113
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.