On Wed, Jun 26, 2024 at 6:46 AM Benjamin Tissoires <bentiss@xxxxxxxxxx> wrote: > > This allows to intercept and prevent or change the behavior of > hid_hw_raw_request() from a bpf program. > > The intent is to solve a couple of use case: > - firewalling a HID device: a firewall can monitor who opens the hidraw > nodes and then prevent or allow access to write operations on that > hidraw node. > - change the behavior of a device and emulate a new HID feature request > > The hook is allowed to be run as sleepable so it can itself call > hid_bpf_hw_request(), which allows to "convert" one feature request into > another or even call the feature request on a different HID device on the > same physical device. > > Signed-off-by: Benjamin Tissoires <bentiss@xxxxxxxxxx> > > --- > > changes in v2: > - make use of SRCU > --- > drivers/hid/bpf/hid_bpf_dispatch.c | 37 ++++++++++++++++++++++++++++++++++++ > drivers/hid/bpf/hid_bpf_struct_ops.c | 1 + > drivers/hid/hid-core.c | 6 ++++++ > include/linux/hid_bpf.h | 35 ++++++++++++++++++++++++++++++++++ > 4 files changed, 79 insertions(+) > > diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c > index c026248e3d73..ac98bab4c96d 100644 > --- a/drivers/hid/bpf/hid_bpf_dispatch.c > +++ b/drivers/hid/bpf/hid_bpf_dispatch.c > @@ -74,6 +74,43 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type > } > EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); > > +int dispatch_hid_bpf_raw_requests(struct hid_device *hdev, > + unsigned char reportnum, u8 *buf, > + u32 size, enum hid_report_type rtype, > + enum hid_class_request reqtype, > + u64 source) > +{ > + struct hid_bpf_ctx_kern ctx_kern = { > + .ctx = { > + .hid = hdev, > + .allocated_size = size, > + .size = size, > + }, > + .data = buf, > + }; > + struct hid_bpf_ops *e; > + int ret, idx; > + > + if (rtype >= HID_REPORT_TYPES) > + return -EINVAL; > + > + idx = srcu_read_lock(&hdev->bpf.srcu); > + list_for_each_entry_srcu(e, &hdev->bpf.prog_list, list, > + srcu_read_lock_held(&hdev->bpf.srcu)) { > + if (e->hid_hw_request) { > + ret = e->hid_hw_request(&ctx_kern.ctx, reportnum, rtype, reqtype, source); > + if (ret) > + goto out; > + } > + } here and in patch 7 I would reduce indent by doing: if (!e->hid_hw_request) continue; ret = e->hid_hw_request(...); otherwise lgtm