Package: obs-studio
Version: 30.2.3+dfsg-3
Severity: normal

Dear Maintainer,

Adding a "Video Capture Device (V4L2)" source makes OBS abort with
"free(): invalid pointer" as soon as the source properties are built.

Steps to reproduce:
1. Machine with a built-in PCI camera and no USB cameras, so /dev/v4l/by-id/
   does not exist (here: MacBookPro11,1, Apple FaceTime HD via the
   out-of-tree facetimehd module, only /dev/v4l/by-path/ exists).
2. Start OBS (a fresh configuration also crashes), create a scene.
3. Add a "Video Capture Device (V4L2)" source.
Result: OBS aborts. Reproduced with fresh config, on Wayland and under X11.
The camera itself works: v4l2-ctl --stream-mmap captures frames normally.

Backtrace (gdb, no debug symbols):
 #5 free () from libc.so.6
 #6 ??? from /usr/lib/x86_64-linux-gnu/obs-plugins/linux-v4l2.so
 #7 ??? from linux-v4l2.so
 #8 obs_source_properties () from libobs.so.0

Analysis (from reading the source, not confirmed with debug symbols):
The Debian patch linux-v4l2-Save-device-by-id-or-path.patch (from upstream
PR 6493, closed upstream) rewrites the device listing in
v4l2_device_add_devices_from(). It declares "struct dirent **namelist;"
without an initial value, scans /dev/v4l/by-id/ with scandir(), and calls
free(namelist) unconditionally at the end. When the directory does not
exist,
scandir() fails and leaves namelist uninitialized, so free() receives a
garbage pointer.

Fix: initialize it to NULL ("struct dirent **namelist = NULL;"). Patch
attached.

Testing: I rebuilt linux-v4l2.so from the Debian source package with this
one-line change and installed it over the packaged plugin. Adding the V4L2
source and opening its properties no longer crashes, and OBS exits cleanly.

Possibly related: #1151092 (crash when reconnecting a USB capture device,
also
in code added by the same patch, but as far as I can tell a different code
path), and the salsa merge request proposing to revert this patch
(multimedia-team/obs-studio MR 9).

-- System Information:
Debian Release: 13.7
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500,
'proposed-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.12.113+deb13-amd64 (SMP w/4 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_USER, TAINT_WARN,
TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=pt_PT.UTF-8, LC_CTYPE=pt_PT.UTF-8 (charmap=UTF-8),
LANGUAGE=pt:pt_BR:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages obs-studio depends on:
ii  libavcodec61               7:7.1.5-0+deb13u1
ii  libavdevice61              7:7.1.5-0+deb13u1
ii  libavformat61              7:7.1.5-0+deb13u1
ii  libavutil59                7:7.1.5-0+deb13u1
ii  libc6                      2.41-12+deb13u4
ii  libcurl3t64-gnutls         8.14.1-2+deb13u7
ii  libegl1                    1.7.0-1+b2
ii  libfontconfig1             2.15.0-2.3
ii  libfreetype6               2.13.3+dfsg-1+deb13u1
ii  libgcc-s1                  14.2.0-19
ii  libglx0                    1.7.0-1+b2
ii  libjansson4                2.14-2+b3
ii  libluajit-5.1-2            2.1.0+openresty20250117-2
ii  libmbedcrypto16            3.6.6-0.1~deb13u1
ii  libmbedtls21               3.6.6-0.1~deb13u1
ii  libmbedx509-7              3.6.6-0.1~deb13u1
ii  libobs0t64                 30.2.3+dfsg-3
ii  libopengl0                 1.7.0-1+b2
ii  libpci3                    1:3.13.0-2
ii  libpulse0                  17.0+dfsg1-2+b1
ii  libpython3.13              3.13.5-2+deb13u5
ii  libqrcodegencpp1           1.8.0-1.2+b2
ii  libqt6core6t64             6.8.2+dfsg-9+deb13u2
ii  libqt6dbus6                6.8.2+dfsg-9+deb13u2
ii  libqt6gui6                 6.8.2+dfsg-9+deb13u2
ii  libqt6network6             6.8.2+dfsg-9+deb13u2
ii  libqt6svg6                 6.8.2-3
ii  libqt6widgets6             6.8.2+dfsg-9+deb13u2
ii  libqt6xml6                 6.8.2+dfsg-9+deb13u2
ii  librist4                   0.2.11+dfsg-1
ii  libspeexdsp1               1.2.1-3
ii  libsrt1.5-openssl          1.5.4-1+deb13u1
ii  libstdc++6                 14.2.0-19
ii  libswscale8                7:7.1.5-0+deb13u1
ii  libudev1                   257.13-1~deb13u1
ii  libv4l-0t64                1.30.1-1
ii  libva-drm2                 2.22.0-3
ii  libva2                     2.22.0-3
ii  libx11-6                   2:1.8.12-1
ii  libx264-164                2:0.164.3108+git31e19f9-2+b1
ii  libxcb-composite0          1.17.0-2+b1
ii  libxcb-randr0              1.17.0-2+b1
ii  libxcb-shm0                1.17.0-2+b1
ii  libxcb-xfixes0             1.17.0-2+b1
ii  libxcb-xinerama0           1.17.0-2+b1
ii  libxcb1                    1.17.0-2+b1
ii  libxkbcommon0              1.7.0-2
ii  python3                    3.13.5-1
ii  python3.13                 3.13.5-2+deb13u5
ii  qt6-image-formats-plugins  6.8.2-4
ii  qt6-wayland                6.8.2-4

Versions of packages obs-studio recommends:
ii  obs-plugins  30.2.3+dfsg-3

Versions of packages obs-studio suggests:
ii  pkexec             126-2
ii  v4l2loopback-dkms  0.15.0-2

-- no debconf information
Description: linux-v4l2: initialize namelist so free() is safe when scandir() fails
 v4l2_device_add_devices_from() calls free(namelist) unconditionally, but
 namelist is only set by scandir() when it succeeds. When the scanned
 directory does not exist (for example /dev/v4l/by-id/ on a machine whose
 camera is not USB), scandir() fails and namelist is uninitialized, so
 free() is called on a garbage pointer and OBS aborts with
 "free(): invalid pointer" when the properties of a V4L2 source are opened.
 Initializing it to NULL makes the free() harmless.
Author: Carlos Castro <[email protected]>
Forwarded: not-needed
Last-Update: 2026-11-03
---
--- obs-studio-30.2.3+dfsg.orig/plugins/linux-v4l2/v4l2-input.c
+++ obs-studio-30.2.3+dfsg/plugins/linux-v4l2/v4l2-input.c
@@ -412,7 +412,7 @@ v4l2_device_add_devices_from(struct v4l2
 	struct dirent *dp;
 	struct dstr full_path;
 	const char *scanned_dir;
-	struct dirent **namelist;
+	struct dirent **namelist = NULL;
 	int no;
 
 #ifdef __FreeBSD__

Reply via email to