* [PATCH 0/2] media: fix em28xx v4l2 init failure refcount underflow and a media core unregister race
@ 2026-11-02 14:14 Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 1/2] media: em28xx: clear dev->v4l2 on v4l2 init failure Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 2/2] media: mc: fix race in media_device_unregister_entity() Deepanshu Kartikey
0 siblings, 2 replies; 4+ messages in thread
From: Deepanshu Kartikey @ 2026-11-02 14:14 UTC (permalink / raw)
To: mchehab, sakari.ailus, laurent.pinchart, hverkuil
Cc: linux-media, linux-kernel, Deepanshu Kartikey
syzbot reported a slab-use-after-free in dev_dbg_obj() on the close path
of a video device node. It is triggered when em28xx_v4l2_init() fails
after the video devices are registered while userspace still holds one
of the nodes open:
https://syzkaller.appspot.com/bug?extid=54648a6c1187a7ef46a6
The cause is a double drop of the initial v4l2_device reference. When
init fails (e.g. in v4l2_mc_create_media_graph()), the unregister_dev
error path drops the initial reference but leaves dev->v4l2 set. On USB
disconnect, em28xx_v4l2_fini() sees the non-NULL pointer and drops the
reference a second time. The refcount underflows, em28xx_free_v4l2()
frees struct em28xx_v4l2 while the file handle is still open, and the
later close() makes v4l2_device_release() call
media_device_unregister_entity() on a media entity embedded in the freed
memory.
Patch 1 clears dev->v4l2 in the init error path, so that
em28xx_v4l2_fini() returns early and does not put the reference again.
With patch 1 applied, the same reproducer hits a second, separate
crash: a general protection fault in ida_free(), called from
__media_device_unregister_entity() via
v4l2_open() -> video_put() -> v4l2_device_release() ->
media_device_unregister_entity(). This is a race in
media_device_unregister_entity(). It checks entity->graph_obj.mdev for
NULL before taking mdev->graph_mutex, but not again afterwards. When
media_device_unregister() runs concurrently on USB disconnect (via
em28xx_release_resources()), it unregisters every entity and clears
graph_obj.mdev while the other thread waits for the mutex. The waiter
then calls __media_device_unregister_entity() with a NULL mdev and
faults on &mdev->entity_internal_idx.
Patch 2 re-checks graph_obj.mdev under graph_mutex and skips the
unregister if the entity is already gone. This GPF has no syzbot report
of its own, so patch 2 carries no Reported-by/Closes tags.
Testing:
Both patches were applied together on top of current mainline master and
tested with syzbot using the reproducer for the bug above. syzbot
reported no crash.
Known limitation:
Patch 2 does not close a remaining window in em28xx. After
media_device_unregister() drops graph_mutex,
em28xx_unregister_media_device() calls media_device_cleanup() and
kfree()s dev->media_dev without waiting for the last video device to be
released. A thread already waiting on graph_mutex could in principle
still lock a freed mutex. A complete fix would tie the media_device
lifetime to the last v4l2_device reference. I left that out because it
is a larger change to em28xx. I am happy to look at it as a follow-up if
the maintainers agree with the approach.
Deepanshu Kartikey (2):
media: em28xx: clear dev->v4l2 on v4l2 init failure
media: mc: fix race in media_device_unregister_entity()
drivers/media/mc/mc-device.c | 3 ++-
drivers/media/usb/em28xx/em28xx-video.c | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] media: em28xx: clear dev->v4l2 on v4l2 init failure
2026-11-02 14:14 [PATCH 0/2] media: fix em28xx v4l2 init failure refcount underflow and a media core unregister race Deepanshu Kartikey
@ 2026-11-02 14:14 ` Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 2/2] media: mc: fix race in media_device_unregister_entity() Deepanshu Kartikey
1 sibling, 0 replies; 4+ messages in thread
From: Deepanshu Kartikey @ 2026-11-02 14:14 UTC (permalink / raw)
To: mchehab, sakari.ailus, laurent.pinchart, hverkuil
Cc: linux-media, linux-kernel, Deepanshu Kartikey,
syzbot+54648a6c1187a7ef46a6
If em28xx_v4l2_init() fails after registering the video devices (for
example in v4l2_mc_create_media_graph()), the unregister_dev error path
drops the initial v4l2_device reference but leaves dev->v4l2 set.
If userspace still holds an open file handle to a video node, the
structure stays alive. On USB disconnect, em28xx_v4l2_fini() sees the
non-NULL dev->v4l2 and drops the initial reference a second time. The
refcount underflows, em28xx_free_v4l2() frees struct em28xx_v4l2, and
the later close() makes v4l2_device_release() touch a media entity in
freed memory:
BUG: KASAN: slab-use-after-free in dev_dbg_obj+0x630/0x830
Read of size 4 at addr ffff888023601bd0 by task v4l_id/6384
Clear dev->v4l2 in the error path after dropping the initial reference,
so that em28xx_v4l2_fini() returns early and does not put it again.
Fixes: 288254383674 ("media: em28xx: use v4l2_device release callback")
Reported-by: syzbot+54648a6c1187a7ef46a6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=54648a6c1187a7ef46a6
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
drivers/media/usb/em28xx/em28xx-video.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 84424284d486..ec4ed2b0e5fd 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -3137,6 +3137,7 @@ static int em28xx_v4l2_init(struct em28xx *dev)
* v4l2_device refcount to zero.
*/
v4l2_device_put(&v4l2->v4l2_dev);
+ dev->v4l2 = NULL;
return ret;
}
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] media: mc: fix race in media_device_unregister_entity()
2026-11-02 14:14 [PATCH 0/2] media: fix em28xx v4l2 init failure refcount underflow and a media core unregister race Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 1/2] media: em28xx: clear dev->v4l2 on v4l2 init failure Deepanshu Kartikey
@ 2026-11-02 14:14 ` Deepanshu Kartikey
2026-11-02 15:13 ` laurent.pinchart
1 sibling, 1 reply; 4+ messages in thread
From: Deepanshu Kartikey @ 2026-11-02 14:14 UTC (permalink / raw)
To: mchehab, sakari.ailus, laurent.pinchart, hverkuil
Cc: linux-media, linux-kernel, Deepanshu Kartikey, stable
media_device_unregister_entity() checks entity->graph_obj.mdev for NULL
before taking mdev->graph_mutex, but does not check again afterwards.
If media_device_unregister() runs concurrently (for example on USB
disconnect), it unregisters every entity and clears graph_obj.mdev while
this function waits for the mutex. The waiter then calls
__media_device_unregister_entity() with a NULL mdev and faults in
ida_free(&mdev->entity_internal_idx, ...):
Oops: general protection fault, KASAN: null-ptr-deref in range
[0x00000000000000c8-0x00000000000000cf]
ida_free
__media_device_unregister_entity
media_device_unregister_entity
v4l2_device_release
v4l2_open
Re-check graph_obj.mdev under the lock and skip the unregister if the
entity is already gone.
Found while testing the fix for the syzbot report at
https://syzkaller.appspot.com/bug?extid=54648a6c1187a7ef46a6
Fixes: e2c91d4d78ee ("[media] media-device: get rid of the spinlock")
Cc: stable@vger.kernel.org
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
drivers/media/mc/mc-device.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c
index f8ea7cfe10b2..039ef7d04ac7 100644
--- a/drivers/media/mc/mc-device.c
+++ b/drivers/media/mc/mc-device.c
@@ -674,7 +674,8 @@ void media_device_unregister_entity(struct media_entity *entity)
return;
mutex_lock(&mdev->graph_mutex);
- __media_device_unregister_entity(entity);
+ if (entity->graph_obj.mdev)
+ __media_device_unregister_entity(entity);
mutex_unlock(&mdev->graph_mutex);
}
EXPORT_SYMBOL_GPL(media_device_unregister_entity);
--
2.43.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] media: mc: fix race in media_device_unregister_entity()
2026-11-02 14:14 ` [PATCH 2/2] media: mc: fix race in media_device_unregister_entity() Deepanshu Kartikey
@ 2026-11-02 15:13 ` laurent.pinchart
0 siblings, 0 replies; 4+ messages in thread
From: laurent.pinchart @ 2026-11-02 15:13 UTC (permalink / raw)
To: Deepanshu Kartikey
Cc: mchehab, sakari.ailus, hverkuil, linux-media, linux-kernel,
Deepanshu Kartikey, stable
Hello,
This is an automated reply.
You have sent a patch or bug report that appears to have been generated
by an LLM. The commit message, code and/or problem description show
little to no real understanding of the issue and changes being proposed.
Such patches or reports require a large amount of work to handle. They
rely on maintainers to propose - and often even implement - a proper
design. The probability that the author will learn from the experience
to improve their future contributions is close to zero.
As a result, to make good use of maintainer time and keep the kernel
development process sustainable, your contribution has been rejected.
If you believe the change you proposed is important, take time to study
the problem, learn, and develop a solution without AI assistance.
Answering this e-mail or generating a new version of a patch by feeding
this reply to an LLM will only result in your e-mails being ignored.
Please note that if your patch attempted to address an important
problem, maintainers or other contributors can submit and merge a
similar or entirely different fix without crediting you.
Your contributions to the Linux kernel will be welcome if you genuinely
desire to invest your time and learn.
Thank you,
Laurent's mail bot
On Mon, 02 Nov 2026 19:44:39 +0530, Deepanshu Kartikey <kartikey406@gmail.com> wrote:
> media_device_unregister_entity() checks entity->graph_obj.mdev for NULL
> before taking mdev->graph_mutex, but does not check again afterwards.
> If media_device_unregister() runs concurrently (for example on USB
> disconnect), it unregisters every entity and clears graph_obj.mdev while
> this function waits for the mutex. The waiter then calls
> __media_device_unregister_entity() with a NULL mdev and faults in
> ida_free(&mdev->entity_internal_idx, ...):
>
> Oops: general protection fault, KASAN: null-ptr-deref in range
> [0x00000000000000c8-0x00000000000000cf]
> ida_free
> __media_device_unregister_entity
> media_device_unregister_entity
> v4l2_device_release
> v4l2_open
>
> Re-check graph_obj.mdev under the lock and skip the unregister if the
> entity is already gone.
>
> Found while testing the fix for the syzbot report at
> https://syzkaller.appspot.com/bug?extid=54648a6c1187a7ef46a6
>
> Fixes: e2c91d4d78ee ("[media] media-device: get rid of the spinlock")
> Cc: stable@vger.kernel.org
> Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
> ---
> drivers/media/mc/mc-device.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c
> index f8ea7cfe10b2..039ef7d04ac7 100644
> --- a/drivers/media/mc/mc-device.c
> +++ b/drivers/media/mc/mc-device.c
> @@ -674,7 +674,8 @@ void media_device_unregister_entity(struct media_entity *entity)
> return;
>
> mutex_lock(&mdev->graph_mutex);
> - __media_device_unregister_entity(entity);
> + if (entity->graph_obj.mdev)
> + __media_device_unregister_entity(entity);
> mutex_unlock(&mdev->graph_mutex);
> }
> EXPORT_SYMBOL_GPL(media_device_unregister_entity);
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-02 15:13 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 14:14 [PATCH 0/2] media: fix em28xx v4l2 init failure refcount underflow and a media core unregister race Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 1/2] media: em28xx: clear dev->v4l2 on v4l2 init failure Deepanshu Kartikey
2026-11-02 14:14 ` [PATCH 2/2] media: mc: fix race in media_device_unregister_entity() Deepanshu Kartikey
2026-11-02 15:13 ` laurent.pinchart
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®