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