From 6668ed271eaefaa63e686bdfbedaeb7b8e492722 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Fri, 4 Sep 2026 10:43:19 +0200 Subject: selftests/bpf: Reject graph kptr use after RCU unlock Add a sleepable verifier test that loads a graph-node local kptr in an explicit RCU read-side critical section, then passes its node to bpf_rbtree_remove() after the section ends. Before the verifier fix, the stale NON_OWN_REF flag makes the node look like a live borrowed reference and the program is accepted. After the fix, the pointer is demoted without NON_OWN_REF and the graph kfunc argument is rejected. Also exercise a graph kptr loaded while a spin lock provides implicit RCU protection. The pointer must be invalidated when the lock is released, which guards the required ordering between non-owning-reference invalidation and RCU demotion. Update the existing fault-protected load test state description. The post-unlock pointer no longer carries NON_OWN_REF, but remains readable because the load is rewritten to use BPF_PROBE_MEM. Signed-off-by: Kumar Kartikeya Dwivedi Link: https://lore.kernel.org/r/20260904084325.52250-7-memxor@gmail.com Signed-off-by: Alexei Starovoitov --- drivers/hid/hid-zpff.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 drivers/hid/hid-zpff.c (limited to 'drivers/hid/hid-zpff.c') diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c new file mode 100644 index 000000000..b565c59d3 --- /dev/null +++ b/drivers/hid/hid-zpff.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Force feedback support for Zeroplus based devices + * + * Copyright (c) 2005, 2006 Anssi Hannula + */ + +/* + */ + + +#include +#include +#include +#include + +#include "hid-ids.h" + +#ifdef CONFIG_ZEROPLUS_FF + +struct zpff_device { + struct hid_report *report; +}; + +static int zpff_play(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct hid_device *hid = input_get_drvdata(dev); + struct zpff_device *zpff = data; + int left, right; + + /* + * The following is specified the other way around in the Zeroplus + * datasheet but the order below is correct for the XFX Executioner; + * however it is possible that the XFX Executioner is an exception + */ + + left = effect->u.rumble.strong_magnitude; + right = effect->u.rumble.weak_magnitude; + dbg_hid("called with 0x%04x 0x%04x\n", left, right); + + left = left * 0x7f / 0xffff; + right = right * 0x7f / 0xffff; + + zpff->report->field[2]->value[0] = left; + zpff->report->field[3]->value[0] = right; + dbg_hid("running with 0x%02x 0x%02x\n", left, right); + hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); + + return 0; +} + +static int zp_input_configured(struct hid_device *hid, struct hid_input *hidinput) +{ + struct zpff_device *zpff; + struct hid_report *report; + struct input_dev *dev = hidinput->input; + int i, error; + + if (!list_is_first(&hidinput->list, &hid->inputs)) + return 0; + + for (i = 0; i < 4; i++) { + report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); + if (!report) + return -ENODEV; + } + + zpff = kzalloc_obj(struct zpff_device); + if (!zpff) + return -ENOMEM; + + zpff->report = report; + set_bit(FF_RUMBLE, dev->ffbit); + + error = input_ff_create_memless(dev, zpff, zpff_play); + if (error) { + kfree(zpff); + return error; + } + + zpff->report->field[0]->value[0] = 0x00; + zpff->report->field[1]->value[0] = 0x02; + zpff->report->field[2]->value[0] = 0x00; + zpff->report->field[3]->value[0] = 0x00; + hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); + + hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula \n"); + + return 0; +} +#else +static inline int zp_input_configured(struct hid_device *hid, + struct hid_input *hidinput) +{ + return 0; +} +#endif + +static const struct hid_device_id zp_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, + { } +}; +MODULE_DEVICE_TABLE(hid, zp_devices); + +static struct hid_driver zp_driver = { + .name = "zeroplus", + .id_table = zp_devices, + .input_configured = zp_input_configured, +}; +module_hid_driver(zp_driver); + +MODULE_DESCRIPTION("Force feedback support for Zeroplus based devices"); +MODULE_LICENSE("GPL"); -- cgit v1.3.1