* [PATCH v3 00/13] Fix leaks in rc core @ 2026-07-22 10:23 Sean Young 2026-07-22 10:23 ` [PATCH v3 12/13] media: rc: Fix use after free in bpf progs Sean Young 0 siblings, 1 reply; 3+ messages in thread From: Sean Young @ 2026-07-22 10:23 UTC (permalink / raw) To: linux-media; +Cc: Sean Young, bpf Changes since v2: - sashiko had many more good review comments Changes since v1: - sashiko had many good review comments - Added fix rc: Use after free in ir_raw_event_handle() - Added fix meson-ir-tx: Ensure probe error is propagated - Added fix redrat3: Ensure all urbs are suspended - Added fix media: redrat3: Error path leaves device in transmitting state - streamzap fix was incorrect - Other minor fixes Sean Young (13): media: streamzap: Add missing rc_unregister_device() media: redrat3: Ensure rc device is freed if enable_detector() fails media: redrat3: Ensure we don't read beyond the end of the packet media: redrat3: Ensure all urbs are suspended media: redrat3: Error path leaves device in transmitting state media: sunxi-cir: Ensure no more interrupts can occur before free media: meson-ir-tx: Ensure clock is disabled on unbind media: meson-ir-tx: Ensure rc_free_device() is called on unbind media: meson-ir-tx: Ensure probe error is propagated media: ir-hix5hd2: Ensure rdev is setup before interrupts are enabled media: rc: Use after free in ir_raw_event_handle() media: rc: Fix use after free in bpf progs media: rc: Fix race condition during rc_register_device() drivers/media/rc/bpf-lirc.c | 18 ++++++++++----- drivers/media/rc/ir-hix5hd2.c | 5 +++-- drivers/media/rc/meson-ir-tx.c | 14 +++++------- drivers/media/rc/rc-ir-raw.c | 40 ++++++++++------------------------ drivers/media/rc/rc-main.c | 18 +++++++++------ drivers/media/rc/redrat3.c | 35 ++++++++++++++++++++++++----- drivers/media/rc/streamzap.c | 1 + drivers/media/rc/sunxi-cir.c | 2 +- 8 files changed, 75 insertions(+), 58 deletions(-) -- 2.55.0 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v3 12/13] media: rc: Fix use after free in bpf progs 2026-07-22 10:23 [PATCH v3 00/13] Fix leaks in rc core Sean Young @ 2026-07-22 10:23 ` Sean Young 2026-07-22 10:49 ` sashiko-bot 0 siblings, 1 reply; 3+ messages in thread From: Sean Young @ 2026-07-22 10:23 UTC (permalink / raw) To: linux-media, Sean Young, Mauro Carvalho Chehab, Patrice Chotard, Hans Verkuil Cc: linux-kernel, bpf Since commit dccc0c3ddf8f ("media: rc: fix race between unregister and urb/irq callbacks"), rcdev->raw is no longer set to NULL after device unregister. raw->progs could point to stale data. Fixes: dccc0c3ddf8f ("media: rc: fix race between unregister and urb/irq callbacks") Signed-off-by: Sean Young <sean@mess.org> --- drivers/media/rc/bpf-lirc.c | 18 +++++++++++++----- drivers/media/rc/rc-ir-raw.c | 11 +++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index 2f7564f26445..14ab611e7445 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c @@ -148,12 +148,13 @@ static int lirc_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog) if (ret) return ret; - raw = rcdev->raw; - if (!raw) { + if (!rcdev->registered) { ret = -ENODEV; goto unlock; } + raw = rcdev->raw; + old_array = lirc_rcu_dereference(raw->progs); if (old_array && bpf_prog_array_length(old_array) >= BPF_MAX_PROGS) { ret = -E2BIG; @@ -186,12 +187,13 @@ static int lirc_bpf_detach(struct rc_dev *rcdev, struct bpf_prog *prog) if (ret) return ret; - raw = rcdev->raw; - if (!raw) { + if (!rcdev->registered) { ret = -ENODEV; goto unlock; } + raw = rcdev->raw; + old_array = lirc_rcu_dereference(raw->progs); ret = bpf_prog_array_copy(old_array, prog, NULL, 0, &new_array); /* @@ -235,7 +237,8 @@ void lirc_bpf_free(struct rc_dev *rcdev) struct bpf_prog_array_item *item; struct bpf_prog_array *array; - array = lirc_rcu_dereference(rcdev->raw->progs); + array = rcu_replace_pointer(rcdev->raw->progs, NULL, + lockdep_is_held(&ir_raw_handler_lock)); if (!array) return; @@ -316,6 +319,11 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) if (ret) goto put; + if (!rcdev->registered) { + ret = -ENODEV; + goto unlock; + } + progs = lirc_rcu_dereference(rcdev->raw->progs); cnt = progs ? bpf_prog_array_length(progs) : 0; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index f066176c9f37..26962b500b0c 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -650,8 +650,11 @@ int ir_raw_event_register(struct rc_dev *dev) void ir_raw_event_free(struct rc_dev *dev) { if (dev->raw) { + mutex_lock(&ir_raw_handler_lock); if (dev->raw->thread) put_task_struct(dev->raw->thread); + lirc_bpf_free(dev); + mutex_unlock(&ir_raw_handler_lock); kfree(dev->raw); dev->raw = NULL; } @@ -661,9 +664,6 @@ void ir_raw_event_unregister(struct rc_dev *dev) { struct ir_raw_handler *handler; - if (!dev || !dev->raw) - return; - kthread_stop(dev->raw->thread); timer_delete_sync(&dev->raw->edge_handle); @@ -676,11 +676,6 @@ void ir_raw_event_unregister(struct rc_dev *dev) lirc_bpf_free(dev); - /* - * A user can be calling bpf(BPF_PROG_{QUERY|ATTACH|DETACH}), so - * ensure that the raw member is null on unlock; this is how - * "device gone" is checked. - */ mutex_unlock(&ir_raw_handler_lock); } -- 2.55.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3 12/13] media: rc: Fix use after free in bpf progs 2026-07-22 10:23 ` [PATCH v3 12/13] media: rc: Fix use after free in bpf progs Sean Young @ 2026-07-22 10:49 ` sashiko-bot 0 siblings, 0 replies; 3+ messages in thread From: sashiko-bot @ 2026-07-22 10:49 UTC (permalink / raw) To: Sean Young; +Cc: bpf, media-ci Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] NULL pointer dereference in BPF LIRC operations due to missing `!raw` check on device registration error path. -- --- Patch [12]: [PATCH v3 12/13] media: rc: Fix use after free in bpf progs --- commit 7dc21e94d34583cca33adec11dc3c1b8af880d26 Author: Sean Young <sean@mess.org> media: rc: Fix use after free in bpf progs Since commit dccc0c3ddf8f ("media: rc: fix race between unregister and urb/irq callbacks"), rcdev->raw is no longer set to NULL after device unregister. raw->progs could point to stale data. > diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c > index 2f7564f26445c..14ab611e74457 100644 > --- a/drivers/media/rc/bpf-lirc.c > +++ b/drivers/media/rc/bpf-lirc.c > @@ -148,12 +148,13 @@ static int lirc_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog) > if (ret) > return ret; > > - raw = rcdev->raw; > - if (!raw) { > + if (!rcdev->registered) { > ret = -ENODEV; > goto unlock; > } > > + raw = rcdev->raw; > + > old_array = lirc_rcu_dereference(raw->progs); [Severity: High] Can this lead to a NULL pointer dereference if rc_register_device() fails? In rc_register_device(), dev->registered is set to true before lirc_register() makes the device visible to userspace. If a subsequent initialization step fails (such as input_register_device() or ir_raw_event_register()), the error path calls ir_raw_event_free(dev), which frees dev->raw and sets it to NULL. However, dev->registered is never reverted to false. If a concurrent userspace process opens /dev/lircX and calls bpf(BPF_PROG_ATTACH) while the fd is kept open, the !rcdev->registered check here would pass. The raw pointer would then be NULL, causing lirc_rcu_dereference(raw->progs) to crash. [ ... ] > @@ -186,12 +187,13 @@ static int lirc_bpf_detach(struct rc_dev *rcdev, struct bpf_prog *prog) > if (ret) > return ret; > > - raw = rcdev->raw; > - if (!raw) { > + if (!rcdev->registered) { > ret = -ENODEV; > goto unlock; > } > > + raw = rcdev->raw; > + > old_array = lirc_rcu_dereference(raw->progs); [Severity: High] Could the same NULL pointer dereference occur here in lirc_bpf_detach() if userspace races with device registration failure? [ ... ] > @@ -316,6 +319,11 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) > if (ret) > goto put; > > + if (!rcdev->registered) { > + ret = -ENODEV; > + goto unlock; > + } > + > progs = lirc_rcu_dereference(rcdev->raw->progs); [Severity: High] Does this code also suffer from the same NULL pointer dereference risk on rcdev->raw when rc_register_device() hits an error path? -- Sashiko AI review · https://sashiko.dev/#/patchset/cover.1784715737.git.sean@mess.org?part=12 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-22 10:49 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-22 10:23 [PATCH v3 00/13] Fix leaks in rc core Sean Young 2026-07-22 10:23 ` [PATCH v3 12/13] media: rc: Fix use after free in bpf progs Sean Young 2026-07-22 10:49 ` sashiko-bot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox