Commit graph

15223 commits

Author SHA1 Message Date
Pauli Virtanen
13ba0a28e5 Merge branch 'aac-eld-a' into 'master'
Draft: bluez5: add AAC-ELD vendor codec used by Airpods

Closes #1492

See merge request pipewire/pipewire!2808
2026-05-01 11:41:37 +00:00
Wim Taymans
f29d7875cf connection: reject too large messages
Instead of silently truncating the message size in the header, simply
reject the complete message.
2026-05-01 13:04:02 +02:00
Wim Taymans
ceb80723a9 modules: unset buffer and size after alloc failure
Set the buffer_data to NULL and the size to 0 after we free the
buffer in realloc failure to avoid problems later.
2026-05-01 13:02:00 +02:00
Wim Taymans
a4fb06073c modules: protect against invalid input and 0 division
Don't crash when the AEC reported latency is invalid.

Check that the parsed values make sense and avoid division by 0.
2026-05-01 12:42:53 +02:00
Wim Taymans
6f6b58785e modules: handle allocation errors 2026-05-01 12:29:54 +02:00
Wim Taymans
a55546c9df filter-chain: limit the number of graph in/out
There is no limit on the number of inputs/outputs of a graph but the
filter-chain assumes it is at most 128 and also that there are at most
128 buffer datas.

Increase the limit (1024) and clamp and log an error when the
filter-graph has more channels. Also clamp the buffer datas so that we
don't overflow the stack allocated buffers.
2026-05-01 12:29:12 +02:00
Wim Taymans
6cc92c0e2b security: add missing NULL checks and fix error handling in modules
module-access: add NULL check after pw_properties_new for
socket_access.

module-pulse-tunnel: add NULL check after 4MB calloc for ring
buffer.

module-rt: add NULL check after calloc in thread create.

module-rtp-session: add goto error after failed
pw_net_parse_address instead of falling through.

module-snapcast-discover: fix missing null-termination on
network-received data before logging it as a string.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 18:38:32 +02:00
Wim Taymans
47ca937905 fix capture rate assignment using logical NOT instead of copy
Three modules had "impl->capture_info.rate = !impl->playback_info.rate"
which evaluates to 0 (logical NOT of a non-zero rate) instead of
copying the playback rate. This is a copy-paste typo from the line
above which correctly uses "= impl->capture_info.rate".

Affects module-filter-chain, module-loopback, module-example-filter.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 18:38:26 +02:00
Wim Taymans
4b64b81d21 security: fix crash and overflow bugs in network-facing modules
module-filter-chain: fix NULL pointer dereference when
pw_stream_dequeue_buffer returns NULL and out->requested is
accessed outside the NULL check.

module-zeroconf-discover: add NULL checks for name, type,
host_name, address, and port from mDNS lookups that could be
missing in malformed announcements.

module-raop-sink: cap net.mtu to 9000 to prevent stack overflow
via VLA uint32_t out[8 + mtu].

module-rtp-sap: fix buffer over-read in SDP "i=" line parsing
that read past a self-inserted null terminator. Also fix fd leak
when fd is 0 (fd > 0 should be fd >= 0).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 18:38:19 +02:00
Wim Taymans
c551408ec2 security: reject path traversal in echo-cancel aec_method parameter
The aec_method parameter is interpolated into a SPA library path
as "aec/libspa-aec-%s". A client could use "../" sequences to
load arbitrary SPA plugins. Reject values containing ".." or "/".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:44:28 +02:00
Wim Taymans
5d0e806bdb security: limit blocklist regex length in switch-on-connect module
A PulseAudio client can load this module with an arbitrarily complex
blocklist regex, causing catastrophic backtracking in regexec on
every new device. Cap the regex string at 1024 characters.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:40:25 +02:00
Wim Taymans
dac6b4f2c5 security: clamp negative max-clients config to zero in pulse server
A negative max-clients value in the config is parsed as int then
assigned to uint32_t, wrapping to UINT32_MAX and effectively
disabling the client limit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:28:02 +02:00
Wim Taymans
c38a32e2e1 security: fix NULL pointer dereference in LADSPA sink/source modules
When sink_name/source_name is not provided, pw_properties_get for
PW_KEY_NODE_NAME returns NULL, which is then passed to
pw_properties_setf as a %s argument.

Add NULL check before calling pw_properties_setf.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:24:52 +02:00
Wim Taymans
99a89f8bd4 security: fix stack overflow via strndupa on long device names
A client-supplied device name ending in ".monitor" was stack-allocated
via strndupa without any size limit. Since protocol messages can be up
to 16MB, a malicious client could send a very long device name and
overflow the stack, crashing the daemon.

Cap the strndupa length at MAX_NAME (1024) in both find_device and
do_set_default.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:18:06 +02:00
Wim Taymans
6ea673b68a security: fix issues in pulse module core files
- volume.c: add spa_pod_is_object check before casting param to
  spa_pod_object, preventing out-of-bounds reads on malformed pods
- manager.c: add NULL check for p->param in has_param before
  dereferencing via SPA_POD_SIZE
- snap-policy.c: check strings1[1] and strings2[1] for NULL before
  passing to g_str_equal, fixing wrong operand order
- format.c: use map->channels consistently in format_build_param

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:08:04 +02:00
Wim Taymans
ef2541a1ef security: fix multiple issues in pulse module implementations
- module-zeroconf-publish: guard spa_hook_remove of impl_listener with
  a flag to prevent operating on uninitialized hook when unload is called
  after a partial load failure; bail out of create_service when
  pw_properties_new fails to prevent NULL dereference in publish_service
- module-device-restore: add missing NULL check after message_alloc in
  emit_event; make manager_events static const
- module-jackdbus-detect: fix memory leak on error paths in prepare by
  using goto out instead of early return; free props/sink_props/source_props
  in unload
- module-roc-sink-input: add missing valid_args whitelist
- module-rtp-recv: add missing valid_args whitelist
- module-rtp-send: add missing valid_args whitelist
- module-gsettings: add missing NULL check after strdup in load_group

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 16:50:30 +02:00
Wim Taymans
8e596bd85f impl-link: handle copy errors 2026-04-30 16:41:43 +02:00
Wim Taymans
dfc5fd86a7 pulse: only fixate when necessary
Check if the format is already fixated before doing a copy and fixate.
The copy can fail so we need to check this.
2026-04-30 16:27:15 +02:00
Wim Taymans
b7aae374bf pulse-server: keep allocate buffer size around
For playback and capture streams we allocate MAXLENGTH (4M) buffers but
for upload streams we must allow space for the total upload stream, which
can be up to the max allowed sample size (16M).

Keep the allocated size for the stream around in a variable so that we
can use it when writing/reading to/from the ringbuffer.

This could later also be extended to use the attr.maxlength variable to
size the buffer (but it's usually 4M anyway). This is more complicated
because we need to grow the buffer size when new attributes are set,
which is probably more complicated than useful.
2026-04-30 15:25:31 +02:00
Wim Taymans
32648b7cc7 pulse: handle wraparound near the end correctly
If offsetis near MAXLENGTH, we can still read past the end of the
buffer. Use the ringbuffer to wraparound.
2026-04-30 14:14:59 +02:00
Wim Taymans
b9b93f3cdb pulse: use json builder for message handler output
Makes sure we escape the string correctly.
2026-04-30 13:53:20 +02:00
Wim Taymans
96c3ada6f2 JSON: use the json builder instead of memstream and fprintf
Use the JSON builder to prepare arguments for modules and metadata
instead of custom memopen and fprintf. This makes it easier to ensure
the strings are all properly escaped.

This removes the use of spa_json_encode_string(), which could return a
truncated, non-zero terminated result, which we needed to check
everywhere.
2026-04-30 13:23:23 +02:00
Wim Taymans
4ddedc72cd security: add missing NULL checks after reply_new in stream creation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 10:23:07 +02:00
Wim Taymans
f29a4e6e14 pulse-server: fix loading of defaults 2026-04-30 10:11:38 +02:00
Wim Taymans
57c621e654 server: use the right client_fd
After accept, we transfered ownership of the client_fd to the source so
use the fd on the new owner.
2026-04-30 10:00:53 +02:00
Wim Taymans
4a34da368e security: fix potential buffer over-read in combine-sink name encoding
spa_json_encode_string was called with sizeof(name)-1, which would
not write a null terminator on truncation. Use sizeof(name) and skip
sink names that don't fit in the buffer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 09:27:37 +02:00
Wim Taymans
912f7f5c64 security: add missing NULL check after pw_properties_new in zeroconf
pw_properties_new can return NULL under OOM. The result was used
directly without a check, leading to a NULL pointer dereference.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 09:25:19 +02:00
Wim Taymans
e1f4c441f4 security: fix OOB read in IEC958 format enum parsing
In the SPA_CHOICE_Enum case, values[index+1] was used to skip the
default value at index 0, but the bounds check only validated index,
not index+1. Move bounds checks into each case with the correct limit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 09:19:41 +02:00
Wim Taymans
390874e7c3 security: fix JSON injection in simple-protocol-tcp address
The listen address was inserted into a JSON array without escaping.
Build the address string first, then encode it with
spa_json_encode_string.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 09:15:36 +02:00
Wim Taymans
0ae17566f2 security: reject unknown tags in message_get to prevent va_arg desync
The switch in message_get had no default case. An unrecognized tag byte
from a malicious client would skip the switch body without consuming
the va_arg parameter, desynchronizing all subsequent argument reads
and causing undefined behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 09:14:08 +02:00
Wim Taymans
d4a1278018 security: add missing create_tag checks in stream command handlers
do_cork_stream, do_flush_trigger_prebuf_stream, and do_set_stream_name
did not check whether the stream had completed format negotiation.
Add create_tag guards matching the pattern in do_set_stream_buffer_attr.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:26:01 +02:00
Wim Taymans
6d2600c09d security: fix one-byte OOB read in module_args_add_props
A trailing backslash in a module argument string would cause the
escape handling to advance past the null terminator, reading one
byte out of bounds on the next loop iteration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:24:13 +02:00
Wim Taymans
c6faaff410 security: add missing NULL check after strndup in cmd.c
strndup can return NULL under OOM. The result was passed directly to
spa_json_begin_array which would dereference the NULL pointer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:21:16 +02:00
Wim Taymans
8e7ca70352 security: add missing create_tag check in update_stream_sample_rate
If a client sends UPDATE_PLAYBACK_STREAM_SAMPLE_RATE before format
negotiation completes, stream->ss.rate could be 0, causing a
floating-point division by zero. Add the same create_tag guard used
in do_set_stream_buffer_attr.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:20:04 +02:00
Wim Taymans
890c06117a security: fix integer overflow in port latency offset conversion
Client-supplied int64_t offset was multiplied by 1000 without overflow
check. Use spa_overflow_mul to detect and reject values that would
overflow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:19:03 +02:00
Wim Taymans
6a8c2469c5 security: fix create_tag check to allow upload stream memblocks
The create_tag guard added in a2de6c886 also rejected memblocks for
upload streams, which never clear create_tag. Upload streams allocate
their buffer immediately, so the NULL deref risk does not apply to
them. Exempt STREAM_TYPE_UPLOAD from the check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:16:52 +02:00
Wim Taymans
3a3579ed68 security: fix operation counter leak in operation_complete
operation_complete removed the operation from the list and freed it
but never decremented client->n_operations. After 64 completed
operations the client would be permanently locked out.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 18:15:22 +02:00
Wim Taymans
344c9265a6 security: fix JSON injection in pulse module arguments
Use spa_json_encode_string to escape user-supplied strings before
inserting them into JSON configs in module-always-sink,
module-x11-bell, and module-switch-on-connect.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:56:12 +02:00
Wim Taymans
7c2d8f7251 security: add missing NULL checks after message_alloc in reply
Both reply_new and reply_error passed the message_alloc result directly
to message_put without checking for NULL, which would cause a NULL
pointer dereference on allocation failure.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:54:21 +02:00
Wim Taymans
1b8962d7c2 security: fix JSON injection in native-protocol-tcp address
The listen address was inserted into JSON without escaping. Build the
address string first, then encode it with spa_json_encode_string to
prevent injection of arbitrary JSON keys.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:52:19 +02:00
Wim Taymans
c5c2d197dc security: fix JSON injection in LADSPA plugin/label strings
The plugin and label parameters in module-ladspa-sink and
module-ladspa-source were inserted into the filter-chain JSON config
without escaping. Use spa_json_encode_string to prevent injection.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:50:49 +02:00
Wim Taymans
bc4e1a989c security: reject zero-channel volume in PulseAudio message parsing
read_cvolume accepted channels=0, creating a degenerate zero-length
volume array that is passed to pw_stream_set_control and SPA pod
building. Reject zero channels alongside the existing CHANNELS_MAX
upper bound check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:23:43 +02:00
Wim Taymans
807b93fb05 security: add per-client pending sample limit in PulseAudio protocol
There was no limit on concurrent PLAY_SAMPLE operations per client.
Each creates a PipeWire stream, allowing a client to exhaust server
resources. Add a MAX_PENDING_SAMPLES (64) limit per client.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:19:08 +02:00
Wim Taymans
138e30df38 security: add per-client operation count limit in PulseAudio protocol
There was no limit on pending operations per client. Commands like
SET_SINK_VOLUME each allocate an operation that persists until a
manager sync completes. A client flooding these commands can exhaust
server memory. Add a MAX_OPERATIONS (64) limit per client.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:17:38 +02:00
Wim Taymans
f32295429f security: fix module leak on OOM in PulseAudio do_load_module
If module_create succeeded but the subsequent calloc for
pending_module failed, the module was leaked in the modules map.
Move the calloc before module_create so failure cleanup is trivial.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:13:56 +02:00
Wim Taymans
2d8dc8b457 security: fix JSON injection in PulseAudio do_set_default
The device name was interpolated into a JSON metadata string without
escaping. A node with crafted name containing quote characters could
inject arbitrary JSON keys into the default sink/source metadata.
Use spa_json_encode_string to properly escape the value.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:09:50 +02:00
Wim Taymans
d3e1be8b6e security: fix division by zero in PulseAudio set_stream_buffer_attr
A client can create a stream with invalid sample_spec (rate=0) via
format_info negotiation, then send SET_STREAM_BUFFER_ATTR before
negotiation completes. fix_playback_buffer_attr divides by ss.rate,
crashing the daemon. Reject buffer attr changes on streams that
have not completed format negotiation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 17:08:17 +02:00
Wim Taymans
cd7bb1e37d security: validate sample rate in PulseAudio update_stream_sample_rate
The client-provided rate was used without validation. A zero or
excessively large rate produces extreme correction values passed
to pw_stream_set_control. Reject rates that are zero or exceed
RATE_MAX.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 16:51:46 +02:00
Wim Taymans
5f02641859 security: add missing NULL check in PulseAudio message_dump
pw_properties_new can return NULL on OOM. Passing NULL to read_props
causes a NULL pointer dereference through pw_properties_set. Only
reachable when debug logging is enabled.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 16:45:09 +02:00
Wim Taymans
9c1bc64af4 security: add missing NULL check after message_alloc in PulseAudio server
message_alloc can return NULL on allocation failure but the result
was not checked, causing the next do_read call to misinterpret
the NULL as a protocol error instead of an OOM condition.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 16:42:59 +02:00