* Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
@ 2026-03-19 9:00 ` Edward Adam Davis
2026-03-19 9:29 ` syzbot
2026-03-19 12:20 ` Edward Adam Davis
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Edward Adam Davis @ 2026-03-19 9:00 UTC (permalink / raw)
To: syzbot+1a7507a194fff09e5c44; +Cc: linux-kernel, syzkaller-bugs
#syz test
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6ce623a1245a..0639315f9611 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -423,7 +423,6 @@ static int v4l2_open(struct inode *inode, struct file *filp)
}
/* and increase the device refcount */
video_get(vdev);
- mutex_unlock(&videodev_lock);
if (!video_is_registered(vdev)) {
ret = -ENODEV;
@@ -448,6 +447,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
+ mutex_unlock(&videodev_lock);
return ret;
}
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open
2026-03-19 9:00 ` Edward Adam Davis
@ 2026-03-19 9:29 ` syzbot
0 siblings, 0 replies; 10+ messages in thread
From: syzbot @ 2026-03-19 9:29 UTC (permalink / raw)
To: eadavis, linux-kernel, syzkaller-bugs
Hello,
syzbot has tested the proposed patch but the reproducer is still triggering an issue:
possible deadlock in em28xx_v4l2_open
======================================================
WARNING: possible circular locking dependency detected
syzkaller #0 Not tainted
------------------------------------------------------
v4l_id/6669 is trying to acquire lock:
ffff888030ac9cd0 (&dev->lock#3){+.+.}-{4:4}
, at: em28xx_v4l2_open+0xf0/0xa20 drivers/media/usb/em28xx/em28xx-video.c:2146
but task is already holding lock:
ffffffff8f6a0520 (videodev_lock){+.+.}-{4:4}, at: v4l2_open+0x32/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:417
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (videodev_lock
){+.+.}-{4:4}:
__mutex_lock_common kernel/locking/mutex.c:632 [inline]
__mutex_lock+0x19e/0x1420 kernel/locking/mutex.c:794
__video_register_device+0x54e/0x4d20 drivers/media/v4l2-core/v4l2-dev.c:1008
video_register_device include/media/v4l2-dev.h:390 [inline]
em28xx_v4l2_init+0x1d32/0x2e70 drivers/media/usb/em28xx/em28xx-video.c:2788
em28xx_init_extension+0x120/0x1c0 drivers/media/usb/em28xx/em28xx-core.c:1117
process_one_work+0x9ab/0x1780 kernel/workqueue.c:3288
process_scheduled_works kernel/workqueue.c:3379 [inline]
worker_thread+0xba8/0x11e0 kernel/workqueue.c:3465
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
-> #0 (&dev->lock#3){+.+.}-{4:4}:
check_prev_add kernel/locking/lockdep.c:3165 [inline]
check_prevs_add kernel/locking/lockdep.c:3284 [inline]
validate_chain kernel/locking/lockdep.c:3908 [inline]
__lock_acquire+0x15a5/0x2cf0 kernel/locking/lockdep.c:5237
lock_acquire+0xf0/0x2e0 kernel/locking/lockdep.c:5868
__mutex_lock_common kernel/locking/mutex.c:632 [inline]
__mutex_lock+0x19e/0x1420 kernel/locking/mutex.c:794
em28xx_v4l2_open+0xf0/0xa20 drivers/media/usb/em28xx/em28xx-video.c:2146
v4l2_open+0x1b1/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:432
chrdev_open+0x4cd/0x5e0 fs/char_dev.c:411
do_dentry_open+0x785/0x14e0 fs/open.c:949
vfs_open+0x3b/0x340 fs/open.c:1081
do_open fs/namei.c:4693 [inline]
path_openat+0x2e08/0x3860 fs/namei.c:4852
do_file_open+0x23e/0x4a0 fs/namei.c:4881
do_sys_openat2+0x113/0x200 fs/open.c:1366
do_sys_open fs/open.c:1372 [inline]
__do_sys_openat fs/open.c:1388 [inline]
__se_sys_openat fs/open.c:1383 [inline]
__x64_sys_openat+0x138/0x170 fs/open.c:1383
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(videodev_lock);
lock(&dev->lock#3);
lock(videodev_lock);
lock(&dev->lock#3
);
*** DEADLOCK ***
1 lock held by v4l_id/6669:
#0:
ffffffff8f6a0520 (videodev_lock){+.+.}-{4:4}, at: v4l2_open+0x32/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:417
stack backtrace:
CPU: 0 UID: 0 PID: 6669 Comm: v4l_id Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
Call Trace:
<TASK>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
print_circular_bug+0x2e1/0x300 kernel/locking/lockdep.c:2043
check_noncircular+0x12e/0x150 kernel/locking/lockdep.c:2175
check_prev_add kernel/locking/lockdep.c:3165 [inline]
check_prevs_add kernel/locking/lockdep.c:3284 [inline]
validate_chain kernel/locking/lockdep.c:3908 [inline]
__lock_acquire+0x15a5/0x2cf0 kernel/locking/lockdep.c:5237
lock_acquire+0xf0/0x2e0 kernel/locking/lockdep.c:5868
__mutex_lock_common kernel/locking/mutex.c:632 [inline]
__mutex_lock+0x19e/0x1420 kernel/locking/mutex.c:794
em28xx_v4l2_open+0xf0/0xa20 drivers/media/usb/em28xx/em28xx-video.c:2146
v4l2_open+0x1b1/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:432
chrdev_open+0x4cd/0x5e0 fs/char_dev.c:411
do_dentry_open+0x785/0x14e0 fs/open.c:949
vfs_open+0x3b/0x340 fs/open.c:1081
do_open fs/namei.c:4693 [inline]
path_openat+0x2e08/0x3860 fs/namei.c:4852
do_file_open+0x23e/0x4a0 fs/namei.c:4881
do_sys_openat2+0x113/0x200 fs/open.c:1366
do_sys_open fs/open.c:1372 [inline]
__do_sys_openat fs/open.c:1388 [inline]
__se_sys_openat fs/open.c:1383 [inline]
__x64_sys_openat+0x138/0x170 fs/open.c:1383
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f80328a7407
Code: 48 89 fa 4c 89 df e8 38 aa 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
RSP: 002b:00007ffdfce9d3b0 EFLAGS: 00000202 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 00007f8033087880 RCX: 00007f80328a7407
RDX: 0000000000000000 RSI: 00007ffdfce9df1d RDI: ffffffffffffff9c
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000
R13: 00007ffdfce9d600 R14: 00007f80331ee000 R15: 0000556e3f2c74d8
</TASK>
Tested on:
commit: 8e42d251 Add linux-next specific files for 20260318
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=178e4a06580000
kernel config: https://syzkaller.appspot.com/x/.config?x=7f5b21566f9d8af6
dashboard link: https://syzkaller.appspot.com/bug?extid=1a7507a194fff09e5c44
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=12e57352580000
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
2026-03-19 9:00 ` Edward Adam Davis
@ 2026-03-19 12:20 ` Edward Adam Davis
2026-03-20 5:31 ` syzbot
2026-03-19 12:40 ` Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path syzbot
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Edward Adam Davis @ 2026-03-19 12:20 UTC (permalink / raw)
To: syzbot+1a7507a194fff09e5c44; +Cc: linux-kernel, syzkaller-bugs
#syz test
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6ce623a1245a..cf9279a2d990 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -423,14 +423,18 @@ static int v4l2_open(struct inode *inode, struct file *filp)
}
/* and increase the device refcount */
video_get(vdev);
- mutex_unlock(&videodev_lock);
if (!video_is_registered(vdev)) {
ret = -ENODEV;
goto done;
}
+ set_bit(V4L2_FL_BUSY, &vdev->flags);
+ mutex_unlock(&videodev_lock);
+
ret = vdev->fops->open(filp);
+
+ mutex_lock(&videodev_lock);
if (ret)
goto done;
@@ -448,6 +452,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* decrease the refcount in case of an error */
if (ret)
video_put(vdev);
+ clear_bit(V4L2_FL_BUSY, &vdev->flags);
+ mutex_unlock(&videodev_lock);
return ret;
}
@@ -1121,6 +1127,11 @@ void video_unregister_device(struct video_device *vdev)
return;
mutex_lock(&videodev_lock);
+ while (test_bit(V4L2_FL_BUSY, &vdev->flags)) {
+ mutex_unlock(&videodev_lock);
+ cond_resched();
+ mutex_lock(&videodev_lock);
+ }
/* This must be in a critical section to prevent a race with v4l2_open.
* Once this bit has been cleared video_get may never be called again.
*/
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2e0f6d2e6a78..83feb0a4f4d3 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -95,6 +95,7 @@ enum v4l2_video_device_flags {
V4L2_FL_USES_V4L2_FH = 1,
V4L2_FL_QUIRK_INVERTED_CROP = 2,
V4L2_FL_SUBDEV_RO_DEVNODE = 3,
+ V4L2_FL_BUSY = 4,
};
/* Priority helper functions */
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open
2026-03-19 12:20 ` Edward Adam Davis
@ 2026-03-20 5:31 ` syzbot
0 siblings, 0 replies; 10+ messages in thread
From: syzbot @ 2026-03-20 5:31 UTC (permalink / raw)
To: eadavis, linux-kernel, syzkaller-bugs
Hello,
syzbot tried to test the proposed patch but the build/boot failed:
failed to create instance: googleapi: Error 400: Invalid value for field 'resource.scheduling.preemptible': 'false'. Scheduling must have preemptible be false when OnHostMaintenance isn't TERMINATE., invalid
syzkaller build log:
go env (err=<nil>)
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='auto'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/syzkaller/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/syzkaller/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build258299175=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/syzkaller/jobs-2/linux/gopath/src/github.com/google/syzkaller/go.mod'
GOMODCACHE='/syzkaller/jobs-2/linux/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/syzkaller/jobs-2/linux/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/syzkaller/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.26.0'
GOWORK=''
PKG_CONFIG='pkg-config'
git status (err=<nil>)
HEAD detached at c88105488a
nothing to commit, working tree clean
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
go list -f '{{.Stale}}' -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=c88105488a5620be13a34f467b1b811950c61bdd -X github.com/google/syzkaller/prog.gitRevisionDate=20260317-161255" ./sys/syz-sysgen | grep -q false || go install -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=c88105488a5620be13a34f467b1b811950c61bdd -X github.com/google/syzkaller/prog.gitRevisionDate=20260317-161255" ./sys/syz-sysgen
make .descriptions
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
Makefile:31: run command via tools/syz-env for best compatibility, see:
Makefile:32: https://github.com/google/syzkaller/blob/master/docs/contributing.md#using-syz-env
bin/syz-sysgen
touch .descriptions
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X github.com/google/syzkaller/prog.GitRevision=c88105488a5620be13a34f467b1b811950c61bdd -X github.com/google/syzkaller/prog.gitRevisionDate=20260317-161255" -o ./bin/linux_amd64/syz-execprog github.com/google/syzkaller/tools/syz-execprog
mkdir -p ./bin/linux_amd64
g++ -o ./bin/linux_amd64/syz-executor executor/executor.cc \
-m64 -O2 -pthread -Wall -Werror -Wparentheses -Wunused-const-variable -Wframe-larger-than=16384 -Wno-stringop-overflow -Wno-array-bounds -Wno-format-overflow -Wno-unused-but-set-variable -Wno-unused-command-line-argument -static-pie -std=c++17 -I. -Iexecutor/_include -DGOOS_linux=1 -DGOARCH_amd64=1 \
-DHOSTGOOS_linux=1 -DGIT_REVISION=\"c88105488a5620be13a34f467b1b811950c61bdd\"
/usr/bin/ld: /tmp/cciJK4vT.o: in function `Connection::Connect(char const*, char const*)':
executor.cc:(.text._ZN10Connection7ConnectEPKcS1_[_ZN10Connection7ConnectEPKcS1_]+0x386): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
./tools/check-syzos.sh 2>/dev/null
Tested on:
commit: b5d083a3 Add linux-next specific files for 20260319
git tree: linux-next
kernel config: https://syzkaller.appspot.com/x/.config?x=9e197b084b913f8d
dashboard link: https://syzkaller.appspot.com/bug?extid=1a7507a194fff09e5c44
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
patch: https://syzkaller.appspot.com/x/patch.diff?x=12bb6e16580000
^ permalink raw reply [flat|nested] 10+ messages in thread
* Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
2026-03-19 9:00 ` Edward Adam Davis
2026-03-19 12:20 ` Edward Adam Davis
@ 2026-03-19 12:40 ` syzbot
2026-03-19 16:45 ` [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open Edward Adam Davis
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: syzbot @ 2026-03-19 12:40 UTC (permalink / raw)
To: linux-kernel, syzkaller-bugs
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.
***
Subject: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
em28xx_v4l2_init() calls video_register_device() which makes the video
device immediately visible to userspace. At this point, v4l2_open() can
be called concurrently and access vdev->dev_debug which is embedded
inside the em28xx_v4l2 structure.
If a subsequent initialization step fails after video_register_device()
succeeds, the error cleanup path calls kref_put(&v4l2->ref) which drops
the reference count to zero and frees the em28xx_v4l2 structure via
em28xx_free_v4l2(). This results in a use-after-free when v4l2_open()
reads vdev->dev_debug from the already freed structure.
Fix this by adding kref_get(&v4l2->ref) at the end of successful
initialization, matching the kref_put() already present in
em28xx_v4l2_fini(). This ensures the v4l2 structure is not freed while
it is still accessible through the registered video device.
The following race triggers the bug:
em28xx_v4l2_init()
video_register_device() <- device visible to userspace
later step fails
goto unregister_dev
kref_put(&v4l2->ref) <- ref hits 0, struct freed!
v4l2_open() <- runs concurrently
reads vdev->dev_debug <- use-after-free!
Fixes: 47677e51e2a4 ("[media] em28xx: Only deallocate struct em28xx after finishing all extensions")
Reported-by: syzbot+1a7507a194fff09e5c44@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=1a7507a194fff09e5c44
Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
---
drivers/media/usb/em28xx/em28xx-video.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 5f13f63fbdee..fe2a7771275d 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -2876,7 +2876,7 @@ static int em28xx_v4l2_init(struct em28xx *dev)
"V4L2 extension successfully initialized\n");
kref_get(&dev->ref);
-
+ kref_get(&v4l2->ref);
mutex_unlock(&dev->lock);
return 0;
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
` (2 preceding siblings ...)
2026-03-19 12:40 ` Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path syzbot
@ 2026-03-19 16:45 ` Edward Adam Davis
2026-03-20 10:30 ` syzbot
2026-03-19 16:49 ` [PATCH] media: usb: em28xx: fix the race condition between init extension and open Edward Adam Davis
2026-03-20 6:23 ` Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path syzbot
5 siblings, 1 reply; 10+ messages in thread
From: Edward Adam Davis @ 2026-03-19 16:45 UTC (permalink / raw)
To: syzbot+1a7507a194fff09e5c44; +Cc: linux-kernel, syzkaller-bugs
#syz test
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index b0c184f237a7..563b4267588e 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -2147,7 +2147,7 @@ static int em28xx_v4l2_open(struct file *filp)
video_device_node_name(vdev), v4l2_type_names[fh_type],
v4l2->users);
- if (mutex_lock_interruptible(&dev->lock))
+ if (!mutex_trylock(&dev->lock))
return -ERESTARTSYS;
ret = v4l2_fh_open(filp);
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH] media: usb: em28xx: fix the race condition between init extension and open
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
` (3 preceding siblings ...)
2026-03-19 16:45 ` [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open Edward Adam Davis
@ 2026-03-19 16:49 ` Edward Adam Davis
2026-03-20 6:23 ` Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path syzbot
5 siblings, 0 replies; 10+ messages in thread
From: Edward Adam Davis @ 2026-03-19 16:49 UTC (permalink / raw)
To: syzbot+1a7507a194fff09e5c44
Cc: linux-kernel, linux-media, linux-usb, mchehab, syzkaller-bugs
The em28xx video device utilizes the same em28xx->lock during both the
extension initialization process and the open system call. This design
creates a race condition: if the extension initialization fails, the
video device undergoes a unregister a video4linux device process;
should an open call be initiated during this unregister, it is highly
likely to enter the open routine within the em28xx driver. At this
juncture, however, em28xx->lock remains held by the kwork responsible
for the extension initialization. Consequently, the open routine is
forced to wait for the unregister process to complete before it can
acquire em28xx->lock, once the lock is finally acquired, the subsequent
code execution proceeds to access the video device instance, an instance
that has, by that time, already been deregistered, thereby triggering
the uaf described in [1].
To mitigate this issue and prevent the UAF resulting from lock contention
over em28xx->lock between the open call and the extension initialization
routine, the lock acquisition method within the em28xx open call has been
modified to use trylock.
[1]
BUG: KASAN: slab-use-after-free in v4l2_open+0x395/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:444
Call Trace:
v4l2_open+0x395/0x3a0 drivers/media/v4l2-core/v4l2-dev.c:444
chrdev_open+0x4cd/0x5e0 fs/char_dev.c:411
do_dentry_open+0x785/0x14e0 fs/open.c:949
vfs_open+0x3b/0x340 fs/open.c:1081
Allocated by task 809:
em28xx_v4l2_init+0x10b/0x2e70 drivers/media/usb/em28xx/em28xx-video.c:2538
em28xx_init_extension+0x120/0x1c0 drivers/media/usb/em28xx/em28xx-core.c:1117
Freed by task 809:
em28xx_free_v4l2 drivers/media/usb/em28xx/em28xx-video.c:2118 [inline]
kref_put include/linux/kref.h:65 [inline]
em28xx_v4l2_init+0x1683/0x2e70 drivers/media/usb/em28xx/em28xx-video.c:2907
em28xx_init_extension+0x120/0x1c0 drivers/media/usb/em28xx/em28xx-core.c:1117
Reported-by: syzbot+1a7507a194fff09e5c44@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1a7507a194fff09e5c44
Tested-by: syzbot+1a7507a194fff09e5c44@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
drivers/media/usb/em28xx/em28xx-video.c | 2 +-
1 file changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index b0c184f237a7..563b4267588e 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -2147,7 +2147,7 @@ static int em28xx_v4l2_open(struct file *filp)
video_device_node_name(vdev), v4l2_type_names[fh_type],
v4l2->users);
- if (mutex_lock_interruptible(&dev->lock))
+ if (!mutex_trylock(&dev->lock))
return -ERESTARTSYS;
ret = v4l2_fh_open(filp);
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Forwarded: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path
2026-03-19 7:21 [syzbot] [media?] [usb?] KASAN: slab-use-after-free Read in v4l2_open syzbot
` (4 preceding siblings ...)
2026-03-19 16:49 ` [PATCH] media: usb: em28xx: fix the race condition between init extension and open Edward Adam Davis
@ 2026-03-20 6:23 ` syzbot
5 siblings, 0 replies; 10+ messages in thread
From: syzbot @ 2026-03-20 6:23 UTC (permalink / raw)
To: linux-kernel, syzkaller-bugs
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.
***
Subject: [PATCH] media: em28xx: fix use-after-free in v4l2_open() during init error path
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
em28xx_v4l2_init() calls video_register_device() which makes the video
device immediately visible to userspace. At this point, v4l2_open() can
be called concurrently and access vdev->dev_debug which is embedded
inside the em28xx_v4l2 structure.
If a subsequent initialization step fails after video_register_device()
succeeds, the error cleanup path calls kref_put(&v4l2->ref) which drops
the reference count to zero and frees the em28xx_v4l2 structure via
em28xx_free_v4l2(). This results in a use-after-free when v4l2_open()
reads vdev->dev_debug from the already freed structure.
Fix this by adding kref_get(&v4l2->ref) at the end of successful
initialization, matching the kref_put() already present in
em28xx_v4l2_fini(). This ensures the v4l2 structure is not freed while
it is still accessible through the registered video device.
The following race triggers the bug:
em28xx_v4l2_init()
video_register_device() <- device visible to userspace
later step fails
goto unregister_dev
kref_put(&v4l2->ref) <- ref hits 0, struct freed!
v4l2_open() <- runs concurrently
reads vdev->dev_debug <- use-after-free!
Fixes: 47677e51e2a4 ("[media] em28xx: Only deallocate struct em28xx after finishing all extensions")
Reported-by: syzbot+1a7507a194fff09e5c44@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=1a7507a194fff09e5c44
Signed-off-by: Deepanshu Kartikey <Kartikey406@gmail.com>
---
drivers/media/usb/em28xx/em28xx-video.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 5f13f63fbdee..fe2a7771275d 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -2876,7 +2876,7 @@ static int em28xx_v4l2_init(struct em28xx *dev)
"V4L2 extension successfully initialized\n");
kref_get(&dev->ref);
-
+ kref_get(&v4l2->ref);
mutex_unlock(&dev->lock);
return 0;
--
2.43.0
^ permalink raw reply [flat|nested] 10+ messages in thread