Commit graph

15132 commits

Author SHA1 Message Date
Wim Taymans
eaaf125d13 filter-graph: protect against large values
Limit the delay in the convolver to 10 seconds.

Limit the convolver block sizes to 64K.

Avoid overflows when using large rates, file size or number of
channels in the provided impulse response.
2026-04-29 11:02:11 +02:00
Wim Taymans
72b9577d3c filter: avoid losing buffers in some cases
If the filter process doesn't dequeue/queue a buffer (as can be the
case in jack-tunnel-sink under xrun cases), pw-filter will set the
io to NEED_DATA with ID_INVALID.

This will then make the mixer in the next cycle not recycle any buffers
and it won't be able to produce any new ones either.
If the filter the dequeues/queues a buffer in the next process, it won't
dequeue a buffer for recycle because io is NEED_DATA/INVALID from the
previous cycle (io != HAVE_DATA -> continue).

This will the continue in an infinite loop producing "out of buffers"
forever.

Also check that we actually have a buffer to recycle, if we don't we can
try to dequeue one and place that in the io. This will then unlock the
loop, make the mixer recycle the buffer and produce a new one.

This is the same logic as is present in pw-stream for the same reason.

Fixes #5246
Maybe also #3547
2026-04-28 14:55:13 +02:00
Wim Taymans
08efbf2254 security: add missing NULL check after calloc in plugin_builtin
Memory Safety: Medium

In the fallback code path when spa-plugins support is not compiled in,
calloc() for the output sample buffer was not checked for NULL. If the
allocation fails (e.g., due to a large n_samples value from filter
configuration), spa_memcpy would dereference a NULL pointer.

Fixed by adding a NULL check and returning NULL on allocation failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 13:05:38 +02:00
Wim Taymans
1de8615caf security: fix missing NULL check and integer overflow in AVB ringbuffer
Memory Safety: Medium

The AVB PCM ringbuffer allocation used calloc(1, size * 4) which has
two issues: the multiplication can overflow for large ringbuffer_size
values (derived from quantum_limit config parameter), and the return
value was never checked for NULL.

Fixed by using calloc(size, 4) which lets calloc check for overflow
internally, and added a NULL check for the allocation result.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 13:05:09 +02:00
Wim Taymans
bf614354cc security: fix integer overflow in pw-cli param info allocation
Memory Safety: High

Three places in pw-cli allocated param info arrays using
malloc(n_params * sizeof(struct spa_param_info)) where n_params
comes from remote protocol data. The multiplication can overflow,
causing a small buffer to be allocated while n_params remains large.
Later code iterating over n_params entries would read past the
allocated buffer.

Fixed by using calloc(n_params, sizeof(...)) which internally checks
for multiplication overflow and returns NULL on failure. Also added
NULL checks and proper fallback when allocation fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 13:04:45 +02:00
Wim Taymans
2fee779161 security: add missing NULL check after calloc in sendspin-recv
Memory Safety: Medium

The ring buffer allocation in the sendspin receiver module was not
checked for NULL. If calloc fails (e.g., due to a large stride value
from network-controlled audio format parameters), the code proceeds
to use the NULL pointer, causing a crash.

Also changed calloc(1, size*stride) to calloc(size, stride) so that
calloc itself checks for multiplication overflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 13:03:21 +02:00
Wim Taymans
e3c20982a8 security: add missing NULL checks after calloc in filter-graph
Memory Safety: Medium

Multiple calloc() calls for node port arrays and the graph handle
array were not checked for NULL returns. If memory allocation fails,
the code immediately dereferences the NULL pointers in subsequent
loops, causing a crash. An attacker who can influence the filter
graph configuration (e.g., through config files specifying many
ports) could potentially trigger this condition.

Fixed by adding NULL checks after all unchecked calloc calls and
properly cleaning up on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 13:02:50 +02:00
Wim Taymans
695f25600b security: add missing O_CLOEXEC flag to V4L2 device open
File and Resource Handling: Medium

The V4L2 device file descriptor was opened without the O_CLOEXEC flag.
If a child process is subsequently spawned (e.g., via fork+exec), the
video device fd would be inherited, potentially allowing the child
process unauthorized access to the camera device.

Fixed by adding O_CLOEXEC to the open() flags.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:56:40 +02:00
Wim Taymans
a12cc84df4 security: fix integer overflow in PulseAudio message read_arbitrary
Memory Safety: High

The read_arbitrary() bounds check used `m->offset + len > m->length`
where len is an attacker-controlled uint32_t read from the PulseAudio
protocol message. When m->offset is small and len is close to
UINT32_MAX, the addition wraps around to a small value, bypassing
the bounds check. This allows read_arbitrary() to return a pointer
within the message buffer but report an enormous length to the caller,
leading to out-of-bounds memory reads.

Fixed by rearranging the arithmetic to use subtraction:
`len > m->length - m->offset`, which cannot overflow since
m->offset <= m->length is maintained as an invariant.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:56:28 +02:00
Wim Taymans
7bfa93de05 security: add missing O_CLOEXEC/SOCK_CLOEXEC flags
File and Resource Handling: Medium

Several file and socket operations were missing the close-on-exec flag,
which causes file descriptors to leak to child processes created via
fork+exec. This could allow child processes unintended access to
privileged resources.

- node-driver.c: SOCK_DGRAM socket for SIOCETHTOOL ioctl leaked to
  child processes
- pw-container.c: Unix domain listen socket leaked to spawned
  container processes
- compress-offload-api.c: ALSA compress-offload device fd leaked to
  child processes

Added O_CLOEXEC to open() calls and SOCK_CLOEXEC to socket() calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:20:33 +02:00
Wim Taymans
3b7e9b0779 security: replace atoi() with validated parsing in RAOP module
Input Validation: Medium

The RAOP sink module used atoi() to parse port numbers from RTSP
Transport headers received over the network. atoi() does not validate
input and its int return was silently truncated to uint16_t, meaning
out-of-range or negative values could produce unexpected port numbers.

Replaced RTSP Transport header port parsing with strtoul() plus range
validation (1-65535). Replaced the raop.port property parsing with
spa_atou32() and range checking. Replaced raop.latency.ms parsing with
spa_atou32() for consistency with safe parsing patterns used elsewhere
in the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:16:06 +02:00
Wim Taymans
a1aa9b0d75 security: replace atoi() with spa_atou32() for RTP session parameters
Input Validation: Medium

The RTP-SAP module used atoi() to parse rtp.rate, rtp.channels,
rtp.ssrc, and rtp.ts-offset properties into uint32_t fields. atoi()
returns int, which has undefined behavior on overflow and silently
converts negative values. When assigned to uint32_t, a negative result
wraps to a large value.

These properties can originate from received SDP announcements over the
network. Replaced with spa_atou32() which properly validates the input
and rejects non-numeric or out-of-range values. This is consistent with
how the same function already handles rtp.framecount using spa_atou32().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:14:46 +02:00
Wim Taymans
7465199fff security: replace unsafe atoi() with validated parsing in websocket
Input Validation: High

The WebSocket HTTP reply parser used atoi() to parse the Content-Length
header from network data. atoi() does not detect overflow or invalid
input, and its int return value was assigned to a size_t, meaning a
negative value from a malicious server would silently convert to a very
large unsigned value, potentially causing excessive memory allocation.

Replaced with spa_atou32() which validates the entire string is a valid
number and fits in uint32_t, plus an explicit upper bound (16 MB) on
content length to prevent resource exhaustion.

Similarly, pw_websocket_listen() used atoi() to parse the port number
into a uint16_t without validation. Replaced with spa_atou32() and a
range check against 65535.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 12:14:36 +02:00
Wim Taymans
aaa7076b52 acp: partially revert f76327e076
The Line Out mute seems to break things.

See #5246
2026-04-28 12:01:06 +02:00
Wim Taymans
06421554d3 security: cap alloca size in JSON-to-POD string conversion
Memory Safety: Medium

spa_json_to_pod_part() uses alloca(len+1) to allocate a stack buffer
for JSON string values, where len comes from the JSON parser. Since
this function is recursive (for nested JSON objects/arrays), a
crafted JSON document with large string values can cause stack
exhaustion through unbounded alloca calls.

Add a size check capping the alloca to 8192 bytes, which is generous
for all legitimate PipeWire configuration values (type names, IDs,
property strings) while preventing stack overflow from malicious or
malformed JSON input.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 11:52:41 +02:00
Wim Taymans
39ac8cf996 filter-chain: improve docs about LADSPA 2026-04-28 11:32:53 +02:00
Wim Taymans
026ae3af7a security: add bounds check for exec argv array in filter-graph
Memory Safety: Medium

The do_exec() function in the filter-graph builtin plugin parses a
JSON array of arguments into a fixed-size argv[512] stack buffer
without checking whether argc exceeds the array bounds. A crafted
filter-graph configuration with more than 511 arguments would cause
a stack buffer overflow.

Add a bounds check before each insertion to ensure argc stays within
the array limits, reserving space for the NULL terminator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-28 10:41:34 +02:00
Wim Taymans
9f3d894c10 audiomixer: rate limit the "out of buffers" debug
See #5249
2026-04-28 10:34:39 +02:00
Wim Taymans
b2790f610c debug: demote some info log to debug 2026-04-28 09:50:02 +02:00
Wim Taymans
5faf043f6c roc-source: handle some errors better 2026-04-27 18:44:04 +02:00
Wim Taymans
c889edf172 roc-source: start/stop receiving in streaming/pause
Only start receiving packets when we are streaming.

Otherwise the ROC source will start receiving and queueing packets and
consume a lot of memory while we don't read the packets from the queue.

Likewise, stop receiving packets when we pause.

Fixes #5250
2026-04-27 18:29:39 +02:00
Wim Taymans
f00c84ccad security: replace strcpy with memcpy in alsa_id_decode
Memory Safety: Low

alsa_id_decode() uses strcpy() to copy into a caller-provided buffer
without knowing its size. Although all current callers allocate the
buffer correctly (via alloca(strlen(src) + 1) or with a pre-validated
fixed buffer), the function signature does not encode this requirement.
Replace strcpy with memcpy using the known source length to make the
bounded copy explicit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:15:10 +02:00
Wim Taymans
ebe9b087ad security: replace strcat with bounds-explicit memcpy in pulse utils
Memory Safety: Low

Although the preceding length check ensures the strcat is safe, using
strcat makes the bounds guarantee implicit. Replace with memcpy using
the already-computed length, making the bounded copy explicit and
avoiding a redundant scan of the destination string.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:14:23 +02:00
Wim Taymans
1ebbd9d7bc security: replace strcpy with memcpy using known lengths in pw-dump
Memory Safety: Low

The strcpy() calls here operate on buffers that are correctly sized,
but using strcpy obscures the bounds guarantee and forces redundant
strlen() calls to compute pointer offsets. Replace with memcpy()
using the lengths already computed for the allocation, making the
bounds safety explicit and avoiding repeated string scanning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:13:52 +02:00
Wim Taymans
d456be1943 security: fix strcpy into fixed-size buffer in netjack2 driver
Memory Safety: Low

strcpy() into the fixed-size params.type[8] buffer has no bounds
checking. While the current literal string "params" fits exactly,
this pattern is fragile and would silently overflow if the string
were ever changed. Use snprintf() with sizeof() for bounds safety,
consistent with how params.name and params.follower_name are
handled on the lines immediately following.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:13:34 +02:00
Wim Taymans
9b845f4415 security: fix unsafe atoi() on network RTSP status code
Input Validation: Medium

atoi() on network-received data returns 0 on parse failure, which is
indistinguishable from a valid "0" input. It also accepts negative
values and does not detect overflow. Replace with strtol() and
validate that the status code is in the valid HTTP/RTSP range
(100-599) to prevent protocol state confusion from malformed
responses.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:13:14 +02:00
Wim Taymans
ca0fa1e4e1 security: fix missing NULL check after strdup in module-raop-discover
Memory Safety: Medium

strdup() can return NULL on allocation failure. The return value was
used without checking, which would cause a NULL pointer dereference
(crash) when the name is later compared with spa_streq(). Add a NULL
check and free the partially-allocated struct on failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:12:47 +02:00
Wim Taymans
15c32c66f0 security: fix command injection via system() in pw-container
Input Validation: High

system() passes its argument to /bin/sh -c, which interprets shell
metacharacters (;, |, &&, $(), etc.). If pw-container is invoked by
another program with untrusted input, this allows arbitrary command
execution. Replace with fork()+execvp() which executes the command
directly without shell interpretation, and passes all remaining
arguments to the child process.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:12:26 +02:00
Wim Taymans
edb3c27aa4 channelmix: add SEE 7p1 to stereo downmix 2026-04-27 15:59:38 +02:00
Wim Taymans
67f1e3a889 combine-stream: add combine.mode = monitor
Add a monitor mode that creates an Audio/Source combining audio from the
monitor ports of all Audio/Sink nodes. This allows capturing everything
that is being played back across all sinks into a single source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 13:36:35 +02:00
Wim Taymans
87ee525b01 security: limit RTSP content-length and check allocation in RAOP client
Input Validation / Memory Safety: Medium

The RTSP client used for RAOP/AirPlay communication accepted arbitrarily
large Content-Length values from the remote server without any upper
bound. A malicious or compromised AirPlay server could specify a very
large Content-Length, causing the client to allocate unbounded memory
and potentially exhaust system resources (denial of service).

Additionally, the return value of pw_array_add() was not checked. If
the allocation failed, the subsequent memcpy would dereference a NULL
pointer, causing a crash.

Add a 64KB limit on Content-Length (more than sufficient for RTSP
control messages) and check the pw_array_add return value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 13:30:36 +02:00
hackerman-kl
74b6f237d1 milan-avb: mvu certification number Disclamer to avoid any confusion 2026-04-27 10:56:44 +00:00
hackerman-kl
30711940c4 milan-avb: aecp: route VENDOR_UNIQUE_COMMAND through msg_info table 2026-04-27 10:56:44 +00:00
hackerman-kl
a16f3d704e milan-avb: aecp-vendor-unique-milan-v12: dispatch via per-cmd table per Milan v1.2 Section 5.4.4 2026-04-27 10:56:44 +00:00
hackerman-kl
deeea620f6 milan-avb: aecp-aem: GET_AS_PATH placeholder per IEEE 1722.1-2021 Section 7.4.41 2026-04-27 10:56:44 +00:00
hackerman-kl
df1605a333 milan-avb: entity-model: advertise VENDOR_UNIQUE_SUPPORTED in capabilities 2026-04-27 10:56:44 +00:00
hackerman-kl
d8b9a0f5ab milan-avb: aecp-aem: GET_STREAM_INFO CDL excludes 12-octet AVTPDU common 2026-04-27 10:56:44 +00:00
hackerman-kl
c967b39f18 milan-avb: avdecc: drop dead debug gate around avb_log_state 2026-04-27 10:56:44 +00:00
hackerman-kl
9c0007173b milan-avb: stream: wire Milan Section 5.4.5 stream counters, TX heartbeat, and MAX_TRANSIT_TIME plumbing 2026-04-27 10:56:44 +00:00
hackerman-kl
16d793db38 milan-avb: acmp: fixing the missing stream deactivate 2026-04-27 10:56:44 +00:00
hackerman-kl
de17f14da4 milan-avb: introducing GET_AS_PATH and GET/SET_MAX_TRANSIT 2026-04-27 10:56:44 +00:00
hackerman-kl
197bab7931 milan-avb: hook stream output to MSRP listener_observed + add max_transit_time_ns 2026-04-27 10:56:44 +00:00
hackerman-kl
a5fbeef6f8 milan-avb: add AVDECC stream_format decoder in aecp-aem.h 2026-04-27 10:56:44 +00:00
hackerman-kl
d9f8bacc76 milan-avb: AEM non-success replies preserve command payload size 2026-04-27 10:56:44 +00:00
hackerman-kl
25e3556050 milan-avb: ACMP status use the status of the FSM rather than the connection count to decide if bound or not 2026-04-27 10:56:44 +00:00
hackerman-kl
52c6c0a0cf milan-avb: GET_STREAM_INFO: fixing the bound state according tol the ACMP status 2026-04-27 10:56:44 +00:00
hackerman-kl
0bf4864d84 milan-avb: move teh descriptor FAM at the end of the structure to avoid overflow 2026-04-27 10:56:44 +00:00
hackerman-kl
4d33f57325 milan-avb: msrp: add debug msrp_talker back 2026-04-27 10:56:44 +00:00
hackerman-kl
ce42b7c1da milan-avb: msrp: mark listener stream-info dirty on TA/TF registrar change 2026-04-27 10:56:44 +00:00
hackerman-kl
995def4927 milan-avb: msrp: log notify_* at info level by default 2026-04-27 10:56:44 +00:00