1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* 4 * HID-BPF support for Linux 5 * 6 * Copyright (c) 2022-2024 Benjamin Tissoires 7 */ 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 #include <linux/bitops.h> 11 #include <linux/btf.h> 12 #include <linux/btf_ids.h> 13 #include <linux/filter.h> 14 #include <linux/hid.h> 15 #include <linux/hid_bpf.h> 16 #include <linux/init.h> 17 #include <linux/kfifo.h> 18 #include <linux/minmax.h> 19 #include <linux/module.h> 20 #include "hid_bpf_dispatch.h" 21 22 const struct hid_ops *hid_ops; 23 EXPORT_SYMBOL(hid_ops); 24 25 u8 * 26 dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data, 27 u32 *size, int interrupt, u64 source, bool from_bpf) 28 { 29 struct hid_bpf_ctx_kern ctx_kern = { 30 .ctx = { 31 .hid = hdev, 32 .allocated_size = hdev->bpf.allocated_data, 33 .size = *size, 34 }, 35 .data = hdev->bpf.device_data, 36 .from_bpf = from_bpf, 37 }; 38 struct hid_bpf_ops *e; 39 int ret; 40 41 if (type >= HID_REPORT_TYPES) 42 return ERR_PTR(-EINVAL); 43 44 /* no program has been attached yet */ 45 if (!hdev->bpf.device_data) 46 return data; 47 48 memset(ctx_kern.data, 0, hdev->bpf.allocated_data); 49 memcpy(ctx_kern.data, data, *size); 50 51 rcu_read_lock(); 52 list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) { 53 if (e->hid_device_event) { 54 ret = e->hid_device_event(&ctx_kern.ctx, type, source); 55 if (ret < 0) { 56 rcu_read_unlock(); 57 return ERR_PTR(ret); 58 } 59 60 if (ret) 61 ctx_kern.ctx.size = ret; 62 } 63 } 64 rcu_read_unlock(); 65 66 ret = ctx_kern.ctx.size; 67 if (ret) { 68 if (ret > ctx_kern.ctx.allocated_size) 69 return ERR_PTR(-EINVAL); 70 71 *size = ret; 72 } 73 74 return ctx_kern.data; 75 } 76 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); 77 78 int dispatch_hid_bpf_raw_requests(struct hid_device *hdev, 79 unsigned char reportnum, u8 *buf, 80 u32 size, enum hid_report_type rtype, 81 enum hid_class_request reqtype, 82 u64 source, bool from_bpf) 83 { 84 struct hid_bpf_ctx_kern ctx_kern = { 85 .ctx = { 86 .hid = hdev, 87 .allocated_size = size, 88 .size = size, 89 }, 90 .data = buf, 91 .from_bpf = from_bpf, 92 }; 93 struct hid_bpf_ops *e; 94 int ret, idx; 95 96 if (rtype >= HID_REPORT_TYPES) 97 return -EINVAL; 98 99 idx = srcu_read_lock(&hdev->bpf.srcu); 100 list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list, 101 srcu_read_lock_held(&hdev->bpf.srcu)) { 102 if (!e->hid_hw_request) 103 continue; 104 105 ret = e->hid_hw_request(&ctx_kern.ctx, reportnum, rtype, reqtype, source); 106 if (ret) 107 goto out; 108 } 109 ret = 0; 110 111 out: 112 srcu_read_unlock(&hdev->bpf.srcu, idx); 113 return ret; 114 } 115 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_raw_requests); 116 117 int dispatch_hid_bpf_output_report(struct hid_device *hdev, 118 __u8 *buf, u32 size, u64 source, 119 bool from_bpf) 120 { 121 struct hid_bpf_ctx_kern ctx_kern = { 122 .ctx = { 123 .hid = hdev, 124 .allocated_size = size, 125 .size = size, 126 }, 127 .data = buf, 128 .from_bpf = from_bpf, 129 }; 130 struct hid_bpf_ops *e; 131 int ret, idx; 132 133 idx = srcu_read_lock(&hdev->bpf.srcu); 134 list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list, 135 srcu_read_lock_held(&hdev->bpf.srcu)) { 136 if (!e->hid_hw_output_report) 137 continue; 138 139 ret = e->hid_hw_output_report(&ctx_kern.ctx, source); 140 if (ret) 141 goto out; 142 } 143 ret = 0; 144 145 out: 146 srcu_read_unlock(&hdev->bpf.srcu, idx); 147 return ret; 148 } 149 EXPORT_SYMBOL_GPL(dispatch_hid_bpf_output_report); 150 151 const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdesc, unsigned int *size) 152 { 153 int ret; 154 struct hid_bpf_ctx_kern ctx_kern = { 155 .ctx = { 156 .hid = hdev, 157 .size = *size, 158 .allocated_size = HID_MAX_DESCRIPTOR_SIZE, 159 }, 160 }; 161 162 if (!hdev->bpf.rdesc_ops) 163 goto ignore_bpf; 164 165 ctx_kern.data = kzalloc(ctx_kern.ctx.allocated_size, GFP_KERNEL); 166 if (!ctx_kern.data) 167 goto ignore_bpf; 168 169 memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTOR_SIZE)); 170 171 ret = hdev->bpf.rdesc_ops->hid_rdesc_fixup(&ctx_kern.ctx); 172 if (ret < 0) 173 goto ignore_bpf; 174 175 if (ret) { 176 if (ret > ctx_kern.ctx.allocated_size) 177 goto ignore_bpf; 178 179 *size = ret; 180 } 181 182 return krealloc(ctx_kern.data, *size, GFP_KERNEL); 183 184 ignore_bpf: 185 kfree(ctx_kern.data); 186 return rdesc; 187 } 188 EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup); 189 190 static int device_match_id(struct device *dev, const void *id) 191 { 192 struct hid_device *hdev = to_hid_device(dev); 193 194 return hdev->id == *(int *)id; 195 } 196 197 struct hid_device *hid_get_device(unsigned int hid_id) 198 { 199 struct device *dev; 200 201 if (!hid_ops) 202 return ERR_PTR(-EINVAL); 203 204 dev = bus_find_device(hid_ops->bus_type, NULL, &hid_id, device_match_id); 205 if (!dev) 206 return ERR_PTR(-EINVAL); 207 208 return to_hid_device(dev); 209 } 210 211 void hid_put_device(struct hid_device *hid) 212 { 213 put_device(&hid->dev); 214 } 215 216 static int __hid_bpf_allocate_data(struct hid_device *hdev, u8 **data, u32 *size) 217 { 218 u8 *alloc_data; 219 unsigned int i, j, max_report_len = 0; 220 size_t alloc_size = 0; 221 222 /* compute the maximum report length for this device */ 223 for (i = 0; i < HID_REPORT_TYPES; i++) { 224 struct hid_report_enum *report_enum = hdev->report_enum + i; 225 226 for (j = 0; j < HID_MAX_IDS; j++) { 227 struct hid_report *report = report_enum->report_id_hash[j]; 228 229 if (report) 230 max_report_len = max(max_report_len, hid_report_len(report)); 231 } 232 } 233 234 /* 235 * Give us a little bit of extra space and some predictability in the 236 * buffer length we create. This way, we can tell users that they can 237 * work on chunks of 64 bytes of memory without having the bpf verifier 238 * scream at them. 239 */ 240 alloc_size = DIV_ROUND_UP(max_report_len, 64) * 64; 241 242 alloc_data = kzalloc(alloc_size, GFP_KERNEL); 243 if (!alloc_data) 244 return -ENOMEM; 245 246 *data = alloc_data; 247 *size = alloc_size; 248 249 return 0; 250 } 251 252 int hid_bpf_allocate_event_data(struct hid_device *hdev) 253 { 254 /* hdev->bpf.device_data is already allocated, abort */ 255 if (hdev->bpf.device_data) 256 return 0; 257 258 return __hid_bpf_allocate_data(hdev, &hdev->bpf.device_data, &hdev->bpf.allocated_data); 259 } 260 261 int hid_bpf_reconnect(struct hid_device *hdev) 262 { 263 if (!test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status)) { 264 /* trigger call to call_hid_bpf_rdesc_fixup() during the next probe */ 265 hdev->bpf_rsize = 0; 266 return device_reprobe(&hdev->dev); 267 } 268 269 return 0; 270 } 271 272 /* Disables missing prototype warnings */ 273 __bpf_kfunc_start_defs(); 274 275 /** 276 * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx 277 * 278 * @ctx: The HID-BPF context 279 * @offset: The offset within the memory 280 * @rdwr_buf_size: the const size of the buffer 281 * 282 * @returns %NULL on error, an %__u8 memory pointer on success 283 */ 284 __bpf_kfunc __u8 * 285 hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size) 286 { 287 struct hid_bpf_ctx_kern *ctx_kern; 288 289 if (!ctx) 290 return NULL; 291 292 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 293 294 if (rdwr_buf_size + offset > ctx->allocated_size) 295 return NULL; 296 297 return ctx_kern->data + offset; 298 } 299 300 /** 301 * hid_bpf_allocate_context - Allocate a context to the given HID device 302 * 303 * @hid_id: the system unique identifier of the HID device 304 * 305 * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error. 306 */ 307 __bpf_kfunc struct hid_bpf_ctx * 308 hid_bpf_allocate_context(unsigned int hid_id) 309 { 310 struct hid_device *hdev; 311 struct hid_bpf_ctx_kern *ctx_kern = NULL; 312 313 hdev = hid_get_device(hid_id); 314 if (IS_ERR(hdev)) 315 return NULL; 316 317 ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL); 318 if (!ctx_kern) { 319 hid_put_device(hdev); 320 return NULL; 321 } 322 323 ctx_kern->ctx.hid = hdev; 324 325 return &ctx_kern->ctx; 326 } 327 328 /** 329 * hid_bpf_release_context - Release the previously allocated context @ctx 330 * 331 * @ctx: the HID-BPF context to release 332 * 333 */ 334 __bpf_kfunc void 335 hid_bpf_release_context(struct hid_bpf_ctx *ctx) 336 { 337 struct hid_bpf_ctx_kern *ctx_kern; 338 struct hid_device *hid; 339 340 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 341 hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */ 342 343 kfree(ctx_kern); 344 345 /* get_device() is called by bus_find_device() */ 346 hid_put_device(hid); 347 } 348 349 static int 350 __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz, 351 enum hid_report_type rtype) 352 { 353 struct hid_report_enum *report_enum; 354 struct hid_report *report; 355 u32 report_len; 356 357 /* check arguments */ 358 if (!ctx || !hid_ops || !buf) 359 return -EINVAL; 360 361 switch (rtype) { 362 case HID_INPUT_REPORT: 363 case HID_OUTPUT_REPORT: 364 case HID_FEATURE_REPORT: 365 break; 366 default: 367 return -EINVAL; 368 } 369 370 if (*buf__sz < 1) 371 return -EINVAL; 372 373 report_enum = ctx->hid->report_enum + rtype; 374 report = hid_ops->hid_get_report(report_enum, buf); 375 if (!report) 376 return -EINVAL; 377 378 report_len = hid_report_len(report); 379 380 if (*buf__sz > report_len) 381 *buf__sz = report_len; 382 383 return 0; 384 } 385 386 /** 387 * hid_bpf_hw_request - Communicate with a HID device 388 * 389 * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context() 390 * @buf: a %PTR_TO_MEM buffer 391 * @buf__sz: the size of the data to transfer 392 * @rtype: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT) 393 * @reqtype: the type of the request (%HID_REQ_GET_REPORT, %HID_REQ_SET_REPORT, ...) 394 * 395 * @returns %0 on success, a negative error code otherwise. 396 */ 397 __bpf_kfunc int 398 hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz, 399 enum hid_report_type rtype, enum hid_class_request reqtype) 400 { 401 struct hid_bpf_ctx_kern *ctx_kern; 402 size_t size = buf__sz; 403 u8 *dma_data; 404 int ret; 405 406 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 407 408 if (ctx_kern->from_bpf) 409 return -EDEADLOCK; 410 411 /* check arguments */ 412 ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype); 413 if (ret) 414 return ret; 415 416 switch (reqtype) { 417 case HID_REQ_GET_REPORT: 418 case HID_REQ_GET_IDLE: 419 case HID_REQ_GET_PROTOCOL: 420 case HID_REQ_SET_REPORT: 421 case HID_REQ_SET_IDLE: 422 case HID_REQ_SET_PROTOCOL: 423 break; 424 default: 425 return -EINVAL; 426 } 427 428 dma_data = kmemdup(buf, size, GFP_KERNEL); 429 if (!dma_data) 430 return -ENOMEM; 431 432 ret = hid_ops->hid_hw_raw_request(ctx->hid, 433 dma_data[0], 434 dma_data, 435 size, 436 rtype, 437 reqtype, 438 (u64)(long)ctx, 439 true); /* prevent infinite recursions */ 440 441 if (ret > 0) 442 memcpy(buf, dma_data, ret); 443 444 kfree(dma_data); 445 return ret; 446 } 447 448 /** 449 * hid_bpf_hw_output_report - Send an output report to a HID device 450 * 451 * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context() 452 * @buf: a %PTR_TO_MEM buffer 453 * @buf__sz: the size of the data to transfer 454 * 455 * Returns the number of bytes transferred on success, a negative error code otherwise. 456 */ 457 __bpf_kfunc int 458 hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz) 459 { 460 struct hid_bpf_ctx_kern *ctx_kern; 461 size_t size = buf__sz; 462 u8 *dma_data; 463 int ret; 464 465 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 466 if (ctx_kern->from_bpf) 467 return -EDEADLOCK; 468 469 /* check arguments */ 470 ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT); 471 if (ret) 472 return ret; 473 474 dma_data = kmemdup(buf, size, GFP_KERNEL); 475 if (!dma_data) 476 return -ENOMEM; 477 478 ret = hid_ops->hid_hw_output_report(ctx->hid, dma_data, size, (u64)(long)ctx, true); 479 480 kfree(dma_data); 481 return ret; 482 } 483 484 static int 485 __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, 486 size_t size, bool lock_already_taken) 487 { 488 struct hid_bpf_ctx_kern *ctx_kern; 489 int ret; 490 491 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 492 if (ctx_kern->from_bpf) 493 return -EDEADLOCK; 494 495 /* check arguments */ 496 ret = __hid_bpf_hw_check_params(ctx, buf, &size, type); 497 if (ret) 498 return ret; 499 500 return hid_ops->hid_input_report(ctx->hid, type, buf, size, 0, (u64)(long)ctx, true, 501 lock_already_taken); 502 } 503 504 /** 505 * hid_bpf_try_input_report - Inject a HID report in the kernel from a HID device 506 * 507 * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context() 508 * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT) 509 * @buf: a %PTR_TO_MEM buffer 510 * @buf__sz: the size of the data to transfer 511 * 512 * Returns %0 on success, a negative error code otherwise. This function will immediately 513 * fail if the device is not available, thus can be safely used in IRQ context. 514 */ 515 __bpf_kfunc int 516 hid_bpf_try_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, 517 const size_t buf__sz) 518 { 519 struct hid_bpf_ctx_kern *ctx_kern; 520 bool from_hid_event_hook; 521 522 ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx); 523 from_hid_event_hook = ctx_kern->data && ctx_kern->data == ctx->hid->bpf.device_data; 524 525 return __hid_bpf_input_report(ctx, type, buf, buf__sz, from_hid_event_hook); 526 } 527 528 /** 529 * hid_bpf_input_report - Inject a HID report in the kernel from a HID device 530 * 531 * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context() 532 * @type: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT) 533 * @buf: a %PTR_TO_MEM buffer 534 * @buf__sz: the size of the data to transfer 535 * 536 * Returns %0 on success, a negative error code otherwise. This function will wait for the 537 * device to be available before injecting the event, thus needs to be called in sleepable 538 * context. 539 */ 540 __bpf_kfunc int 541 hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *buf, 542 const size_t buf__sz) 543 { 544 int ret; 545 546 ret = down_interruptible(&ctx->hid->driver_input_lock); 547 if (ret) 548 return ret; 549 550 /* check arguments */ 551 ret = __hid_bpf_input_report(ctx, type, buf, buf__sz, true /* lock_already_taken */); 552 553 up(&ctx->hid->driver_input_lock); 554 555 return ret; 556 } 557 __bpf_kfunc_end_defs(); 558 559 /* 560 * The following set contains all functions we agree BPF programs 561 * can use. 562 */ 563 BTF_KFUNCS_START(hid_bpf_kfunc_ids) 564 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL) 565 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE) 566 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE | KF_SLEEPABLE) 567 BTF_ID_FLAGS(func, hid_bpf_hw_request, KF_SLEEPABLE) 568 BTF_ID_FLAGS(func, hid_bpf_hw_output_report, KF_SLEEPABLE) 569 BTF_ID_FLAGS(func, hid_bpf_input_report, KF_SLEEPABLE) 570 BTF_ID_FLAGS(func, hid_bpf_try_input_report) 571 BTF_KFUNCS_END(hid_bpf_kfunc_ids) 572 573 static const struct btf_kfunc_id_set hid_bpf_kfunc_set = { 574 .owner = THIS_MODULE, 575 .set = &hid_bpf_kfunc_ids, 576 }; 577 578 /* for syscall HID-BPF */ 579 BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids) 580 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL) 581 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE) 582 BTF_ID_FLAGS(func, hid_bpf_hw_request) 583 BTF_ID_FLAGS(func, hid_bpf_hw_output_report) 584 BTF_ID_FLAGS(func, hid_bpf_input_report) 585 BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids) 586 587 static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = { 588 .owner = THIS_MODULE, 589 .set = &hid_bpf_syscall_kfunc_ids, 590 }; 591 592 int hid_bpf_connect_device(struct hid_device *hdev) 593 { 594 bool need_to_allocate = false; 595 struct hid_bpf_ops *e; 596 597 rcu_read_lock(); 598 list_for_each_entry_rcu(e, &hdev->bpf.prog_list, list) { 599 if (e->hid_device_event) { 600 need_to_allocate = true; 601 break; 602 } 603 } 604 rcu_read_unlock(); 605 606 /* only allocate BPF data if there are programs attached */ 607 if (!need_to_allocate) 608 return 0; 609 610 return hid_bpf_allocate_event_data(hdev); 611 } 612 EXPORT_SYMBOL_GPL(hid_bpf_connect_device); 613 614 void hid_bpf_disconnect_device(struct hid_device *hdev) 615 { 616 kfree(hdev->bpf.device_data); 617 hdev->bpf.device_data = NULL; 618 hdev->bpf.allocated_data = 0; 619 } 620 EXPORT_SYMBOL_GPL(hid_bpf_disconnect_device); 621 622 void hid_bpf_destroy_device(struct hid_device *hdev) 623 { 624 if (!hdev) 625 return; 626 627 /* mark the device as destroyed in bpf so we don't reattach it */ 628 hdev->bpf.destroyed = true; 629 630 __hid_bpf_ops_destroy_device(hdev); 631 632 synchronize_srcu(&hdev->bpf.srcu); 633 cleanup_srcu_struct(&hdev->bpf.srcu); 634 } 635 EXPORT_SYMBOL_GPL(hid_bpf_destroy_device); 636 637 int hid_bpf_device_init(struct hid_device *hdev) 638 { 639 INIT_LIST_HEAD(&hdev->bpf.prog_list); 640 mutex_init(&hdev->bpf.prog_list_lock); 641 return init_srcu_struct(&hdev->bpf.srcu); 642 } 643 EXPORT_SYMBOL_GPL(hid_bpf_device_init); 644 645 static int __init hid_bpf_init(void) 646 { 647 int err; 648 649 /* Note: if we exit with an error any time here, we would entirely break HID, which 650 * is probably not something we want. So we log an error and return success. 651 * 652 * This is not a big deal: nobody will be able to use the functionality. 653 */ 654 655 err = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &hid_bpf_kfunc_set); 656 if (err) { 657 pr_warn("error while setting HID BPF tracing kfuncs: %d", err); 658 return 0; 659 } 660 661 err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set); 662 if (err) { 663 pr_warn("error while setting HID BPF syscall kfuncs: %d", err); 664 return 0; 665 } 666 667 return 0; 668 } 669 670 late_initcall(hid_bpf_init); 671 MODULE_AUTHOR("Benjamin Tissoires"); 672 MODULE_LICENSE("GPL"); 673