Skip to content

Commit 5c24e4e

Browse files
committed
Merge tag 'hid-for-linus-2024020101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Benjamin Tissoires: - cleanups in the error path in hid-steam (Dan Carpenter) - fixes for Wacom tablets selftests that sneaked in while the CI was taking a break during the year end holidays (Benjamin Tissoires) - null pointer check in nvidia-shield (Kunwu Chan) - memory leak fix in hidraw (Su Hui) - another null pointer fix in i2c-hid-of (Johan Hovold) - another memory leak fix in HID-BPF this time, as well as a double fdget() fix reported by Dan Carpenter (Benjamin Tissoires) - fix for Cirque touchpad when they go on suspend (Kai-Heng Feng) - new device ID in hid-logitech-hidpp: "Logitech G Pro X SuperLight 2" (Jiri Kosina) * tag 'hid-for-linus-2024020101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: bpf: use __bpf_kfunc instead of noinline HID: bpf: actually free hdev memory after attaching a HID-BPF program HID: bpf: remove double fdget() HID: i2c-hid-of: fix NULL-deref on failed power up HID: hidraw: fix a problem of memory leak in hidraw_release() HID: i2c-hid: Skip SET_POWER SLEEP for Cirque touchpad on system suspend HID: nvidia-shield: Add missing null pointer checks to LED initialization HID: logitech-hidpp: add support for Logitech G Pro X Superlight 2 selftests/hid: wacom: fix confidence tests HID: hid-steam: Fix cleanup in probe() HID: hid-steam: remove pointless error message
2 parents f6cdd89 + 764ad6b commit 5c24e4e

File tree

12 files changed

+138
-85
lines changed

12 files changed

+138
-85
lines changed

drivers/hid/bpf/hid_bpf_dispatch.c

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
143143
}
144144
EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
145145

146+
/* Disables missing prototype warnings */
147+
__bpf_kfunc_start_defs();
148+
146149
/**
147150
* hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
148151
*
@@ -152,7 +155,7 @@ EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
152155
*
153156
* @returns %NULL on error, an %__u8 memory pointer on success
154157
*/
155-
noinline __u8 *
158+
__bpf_kfunc __u8 *
156159
hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)
157160
{
158161
struct hid_bpf_ctx_kern *ctx_kern;
@@ -167,6 +170,7 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
167170

168171
return ctx_kern->data + offset;
169172
}
173+
__bpf_kfunc_end_defs();
170174

171175
/*
172176
* The following set contains all functions we agree BPF programs
@@ -241,6 +245,42 @@ int hid_bpf_reconnect(struct hid_device *hdev)
241245
return 0;
242246
}
243247

248+
static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog,
249+
__u32 flags)
250+
{
251+
int fd, err, prog_type;
252+
253+
prog_type = hid_bpf_get_prog_attach_type(prog);
254+
if (prog_type < 0)
255+
return prog_type;
256+
257+
if (prog_type >= HID_BPF_PROG_TYPE_MAX)
258+
return -EINVAL;
259+
260+
if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) {
261+
err = hid_bpf_allocate_event_data(hdev);
262+
if (err)
263+
return err;
264+
}
265+
266+
fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags);
267+
if (fd < 0)
268+
return fd;
269+
270+
if (prog_type == HID_BPF_PROG_TYPE_RDESC_FIXUP) {
271+
err = hid_bpf_reconnect(hdev);
272+
if (err) {
273+
close_fd(fd);
274+
return err;
275+
}
276+
}
277+
278+
return fd;
279+
}
280+
281+
/* Disables missing prototype warnings */
282+
__bpf_kfunc_start_defs();
283+
244284
/**
245285
* hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device
246286
*
@@ -253,22 +293,17 @@ int hid_bpf_reconnect(struct hid_device *hdev)
253293
* is pinned to the BPF file system).
254294
*/
255295
/* called from syscall */
256-
noinline int
296+
__bpf_kfunc int
257297
hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
258298
{
259299
struct hid_device *hdev;
300+
struct bpf_prog *prog;
260301
struct device *dev;
261-
int fd, err, prog_type = hid_bpf_get_prog_attach_type(prog_fd);
302+
int err, fd;
262303

263304
if (!hid_bpf_ops)
264305
return -EINVAL;
265306

266-
if (prog_type < 0)
267-
return prog_type;
268-
269-
if (prog_type >= HID_BPF_PROG_TYPE_MAX)
270-
return -EINVAL;
271-
272307
if ((flags & ~HID_BPF_FLAG_MASK))
273308
return -EINVAL;
274309

@@ -278,25 +313,29 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
278313

279314
hdev = to_hid_device(dev);
280315

281-
if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) {
282-
err = hid_bpf_allocate_event_data(hdev);
283-
if (err)
284-
return err;
316+
/*
317+
* take a ref on the prog itself, it will be released
318+
* on errors or when it'll be detached
319+
*/
320+
prog = bpf_prog_get(prog_fd);
321+
if (IS_ERR(prog)) {
322+
err = PTR_ERR(prog);
323+
goto out_dev_put;
285324
}
286325

287-
fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, flags);
288-
if (fd < 0)
289-
return fd;
290-
291-
if (prog_type == HID_BPF_PROG_TYPE_RDESC_FIXUP) {
292-
err = hid_bpf_reconnect(hdev);
293-
if (err) {
294-
close_fd(fd);
295-
return err;
296-
}
326+
fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags);
327+
if (fd < 0) {
328+
err = fd;
329+
goto out_prog_put;
297330
}
298331

299332
return fd;
333+
334+
out_prog_put:
335+
bpf_prog_put(prog);
336+
out_dev_put:
337+
put_device(dev);
338+
return err;
300339
}
301340

302341
/**
@@ -306,7 +345,7 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
306345
*
307346
* @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
308347
*/
309-
noinline struct hid_bpf_ctx *
348+
__bpf_kfunc struct hid_bpf_ctx *
310349
hid_bpf_allocate_context(unsigned int hid_id)
311350
{
312351
struct hid_device *hdev;
@@ -323,8 +362,10 @@ hid_bpf_allocate_context(unsigned int hid_id)
323362
hdev = to_hid_device(dev);
324363

325364
ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL);
326-
if (!ctx_kern)
365+
if (!ctx_kern) {
366+
put_device(dev);
327367
return NULL;
368+
}
328369

329370
ctx_kern->ctx.hid = hdev;
330371

@@ -337,14 +378,19 @@ hid_bpf_allocate_context(unsigned int hid_id)
337378
* @ctx: the HID-BPF context to release
338379
*
339380
*/
340-
noinline void
381+
__bpf_kfunc void
341382
hid_bpf_release_context(struct hid_bpf_ctx *ctx)
342383
{
343384
struct hid_bpf_ctx_kern *ctx_kern;
385+
struct hid_device *hid;
344386

345387
ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
388+
hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */
346389

347390
kfree(ctx_kern);
391+
392+
/* get_device() is called by bus_find_device() */
393+
put_device(&hid->dev);
348394
}
349395

350396
/**
@@ -358,7 +404,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
358404
*
359405
* @returns %0 on success, a negative error code otherwise.
360406
*/
361-
noinline int
407+
__bpf_kfunc int
362408
hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
363409
enum hid_report_type rtype, enum hid_class_request reqtype)
364410
{
@@ -426,6 +472,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
426472
kfree(dma_data);
427473
return ret;
428474
}
475+
__bpf_kfunc_end_defs();
429476

430477
/* our HID-BPF entrypoints */
431478
BTF_SET8_START(hid_bpf_fmodret_ids)

drivers/hid/bpf/hid_bpf_dispatch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ struct hid_bpf_ctx_kern {
1212

1313
int hid_bpf_preload_skel(void);
1414
void hid_bpf_free_links_and_skel(void);
15-
int hid_bpf_get_prog_attach_type(int prog_fd);
15+
int hid_bpf_get_prog_attach_type(struct bpf_prog *prog);
1616
int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, int prog_fd,
17-
__u32 flags);
17+
struct bpf_prog *prog, __u32 flags);
1818
void __hid_bpf_destroy_device(struct hid_device *hdev);
1919
int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
2020
struct hid_bpf_ctx_kern *ctx_kern);

drivers/hid/bpf/hid_bpf_jmp_table.c

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx)
196196
static void hid_bpf_release_progs(struct work_struct *work)
197197
{
198198
int i, j, n, map_fd = -1;
199+
bool hdev_destroyed;
199200

200201
if (!jmp_table.map)
201202
return;
@@ -220,6 +221,12 @@ static void hid_bpf_release_progs(struct work_struct *work)
220221
if (entry->hdev) {
221222
hdev = entry->hdev;
222223
type = entry->type;
224+
/*
225+
* hdev is still valid, even if we are called after hid_destroy_device():
226+
* when hid_bpf_attach() gets called, it takes a ref on the dev through
227+
* bus_find_device()
228+
*/
229+
hdev_destroyed = hdev->bpf.destroyed;
223230

224231
hid_bpf_populate_hdev(hdev, type);
225232

@@ -232,12 +239,19 @@ static void hid_bpf_release_progs(struct work_struct *work)
232239
if (test_bit(next->idx, jmp_table.enabled))
233240
continue;
234241

235-
if (next->hdev == hdev && next->type == type)
242+
if (next->hdev == hdev && next->type == type) {
243+
/*
244+
* clear the hdev reference and decrement the device ref
245+
* that was taken during bus_find_device() while calling
246+
* hid_bpf_attach()
247+
*/
236248
next->hdev = NULL;
249+
put_device(&hdev->dev);
250+
}
237251
}
238252

239-
/* if type was rdesc fixup, reconnect device */
240-
if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP)
253+
/* if type was rdesc fixup and the device is not gone, reconnect device */
254+
if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP && !hdev_destroyed)
241255
hid_bpf_reconnect(hdev);
242256
}
243257
}
@@ -333,15 +347,10 @@ static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog)
333347
return err;
334348
}
335349

336-
int hid_bpf_get_prog_attach_type(int prog_fd)
350+
int hid_bpf_get_prog_attach_type(struct bpf_prog *prog)
337351
{
338-
struct bpf_prog *prog = NULL;
339-
int i;
340352
int prog_type = HID_BPF_PROG_TYPE_UNDEF;
341-
342-
prog = bpf_prog_get(prog_fd);
343-
if (IS_ERR(prog))
344-
return PTR_ERR(prog);
353+
int i;
345354

346355
for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) {
347356
if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) {
@@ -350,8 +359,6 @@ int hid_bpf_get_prog_attach_type(int prog_fd)
350359
}
351360
}
352361

353-
bpf_prog_put(prog);
354-
355362
return prog_type;
356363
}
357364

@@ -388,19 +395,13 @@ static const struct bpf_link_ops hid_bpf_link_lops = {
388395
/* called from syscall */
389396
noinline int
390397
__hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
391-
int prog_fd, __u32 flags)
398+
int prog_fd, struct bpf_prog *prog, __u32 flags)
392399
{
393400
struct bpf_link_primer link_primer;
394401
struct hid_bpf_link *link;
395-
struct bpf_prog *prog = NULL;
396402
struct hid_bpf_prog_entry *prog_entry;
397403
int cnt, err = -EINVAL, prog_table_idx = -1;
398404

399-
/* take a ref on the prog itself */
400-
prog = bpf_prog_get(prog_fd);
401-
if (IS_ERR(prog))
402-
return PTR_ERR(prog);
403-
404405
mutex_lock(&hid_bpf_attach_lock);
405406

406407
link = kzalloc(sizeof(*link), GFP_USER);
@@ -467,7 +468,6 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
467468
err_unlock:
468469
mutex_unlock(&hid_bpf_attach_lock);
469470

470-
bpf_prog_put(prog);
471471
kfree(link);
472472

473473
return err;

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@
298298

299299
#define USB_VENDOR_ID_CIDC 0x1677
300300

301+
#define I2C_VENDOR_ID_CIRQUE 0x0488
302+
#define I2C_PRODUCT_ID_CIRQUE_1063 0x1063
303+
301304
#define USB_VENDOR_ID_CJTOUCH 0x24b8
302305
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
303306
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040

drivers/hid/hid-logitech-hidpp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4610,6 +4610,8 @@ static const struct hid_device_id hidpp_devices[] = {
46104610
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
46114611
{ /* Logitech G Pro X Superlight Gaming Mouse over USB */
46124612
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
4613+
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
4614+
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
46134615

46144616
{ /* G935 Gaming Headset */
46154617
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),

drivers/hid/hid-nvidia-shield.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,8 @@ static inline int thunderstrike_led_create(struct thunderstrike *ts)
800800

801801
led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL,
802802
"thunderstrike%d:blue:led", ts->id);
803+
if (!led->name)
804+
return -ENOMEM;
803805
led->max_brightness = 1;
804806
led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN;
805807
led->brightness_get = &thunderstrike_led_get_brightness;
@@ -831,6 +833,8 @@ static inline int thunderstrike_psy_create(struct shield_device *shield_dev)
831833
shield_dev->battery_dev.desc.name =
832834
devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL,
833835
"thunderstrike_%d", ts->id);
836+
if (!shield_dev->battery_dev.desc.name)
837+
return -ENOMEM;
834838

835839
shield_dev->battery_dev.psy = power_supply_register(
836840
&hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg);

0 commit comments

Comments
 (0)