Information Disclosure: Medium
The MD5_hash() function formats password material into a 1024-byte
stack buffer for hashing but never clears it afterward. Similarly,
the Basic auth path in rtsp_add_raop_auth_header() formats
username:password into a stack buffer without clearing it.
These buffers remain on the stack after the functions return, and
could be exposed through memory disclosure vulnerabilities, core
dumps, or memory inspection.
Clear the buffers with explicit_bzero() immediately after they are
no longer needed, consistent with the existing practice of clearing
the password before freeing in impl_destroy().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
In netjack2_recv_float(), several values from untrusted network packet
headers are used in arithmetic without overflow protection:
1. active_ports from the network header had no upper bound check. A
very large value causes `active_ports * sub_period_bytes` to
overflow uint32_t, producing a small value that passes the length
check, then the loop iterates out of bounds on the receive buffer.
2. The sub_cycle bounds check `sub_cycle * sub_period_size >
quantum_limit` can overflow, allowing a large sub_cycle to pass
the check and cause an out-of-bounds write when computing the
destination offset.
Fix by capping active_ports to MAX_CHANNELS, casting to size_t for the
length check to prevent overflow, and rewriting the sub_cycle check as
a division to avoid overflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
In netjack2_recv_midi(), the offset calculation `max_size * sub_cycle`
uses sub_cycle from an untrusted network packet header. A large
sub_cycle value could cause integer overflow, producing a small offset
that passes the subsequent bounds check and leads to an out-of-bounds
write into the MIDI data buffer.
Similarly, the bounds check `offset + len < midi_size` could itself
overflow, and the `used` size calculation from network-controlled
event_count and write_pos fields could overflow to bypass the size
check.
Fix by adding an explicit overflow check before the multiplication,
rewriting the bounds check to use subtraction (which cannot overflow
after the prior check), and adding an underflow check on the `used`
calculation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
In ensure_size(), the check `m->length + size <= m->allocated` could
overflow when both m->length and size are large uint32_t values,
wrapping around to a small number and incorrectly passing the bounds
check. This could allow writing past the end of the allocated buffer.
Rewrite the check as `size <= m->allocated - m->length` which cannot
overflow since we already verified m->length <= m->allocated. Also add
an explicit overflow check for the new allocation size calculation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: Medium
In pw_conf_save_state(), the return value of fdopen() was not checked
for NULL. If fdopen() fails, subsequent fprintf() and fclose() calls
would operate on a NULL FILE pointer, causing a crash. Additionally,
the file descriptor would be leaked since fclose() would not be called.
Added a NULL check after fdopen() that closes the raw fd and returns
an error on failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Information Disclosure: Medium
The RAOP authentication password was freed without first clearing the
memory contents. This leaves the plaintext password in freed heap
memory where it could be recovered by an attacker with access to
process memory (e.g. via /proc/pid/mem, core dumps, or a separate
memory safety vulnerability).
Use explicit_bzero() to securely clear the password before freeing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
When parsing a DSF audio file, blocksize and channels are read as
uint32_t from untrusted file data and multiplied together for the
buffer allocation. A malicious file could set these to values whose
product overflows, resulting in a small allocation followed by
out-of-bounds writes when the buffer is filled.
Add overflow checking before the multiplication and validate that
neither value is zero. Also use calloc(channels, blocksize) instead
of calloc(1, blocksize * channels) to let calloc perform its own
internal overflow check.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
In rtsp_do_options_auth(), the return values of strdup() for
auth_method, realm, and nonce were not checked for NULL. If strdup()
fails due to memory exhaustion, spa_streq() on auth_method will
dereference NULL, and the realm/nonce pointers will be used later in
MD5_hash() causing NULL pointer dereferences.
Add NULL checks after each strdup() call, returning -ENOMEM on failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: High
In dot_data_init(), the return value of malloc() was not checked before
dereferencing, causing a NULL pointer dereference if allocation fails.
In dot_data_ensure_max_size(), the return value of realloc() was
assigned directly to dd->data without checking for NULL, which both
loses the original pointer (memory leak) and causes a NULL pointer
dereference on subsequent use.
Add NULL checks for both cases. For realloc, use a temporary variable
to preserve the original pointer on failure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There is nothing wrong with the use of strcat here but security tools
keep complaining about it and creating bad patches for it so fix it
with a strbuf.
Memory Safety: High
Three malloc calls for ring buffers (rec_buffer, play_buffer,
out_buffer) had no NULL checks. If any allocation fails, the
NULL pointers would be passed to memset and ringbuffer
operations in reset_buffers(), causing a NULL pointer
dereference crash.
Additionally, the ring size calculations used uint32_t
arithmetic which could overflow with large user-configurable
buffer.max_size values. Cast to size_t to perform the
multiplication in 64-bit, preventing intermediate overflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: Low
sprintf was used to format a temporary filename into an alloca'd
buffer. While the buffer was correctly sized (strlen + 5), using
snprintf with an explicit size makes the bound check enforceable
and prevents potential overflow if the sizing logic is modified
in the future.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: Low
sprintf was used to format MD5 hex digest bytes into a fixed-size
buffer without explicit bounds. While the output is bounded by the
fixed MD5 digest length (16 bytes = 32 hex chars), using snprintf
with an explicit size of 3 (2 hex chars + null) ensures correctness
even if the surrounding code changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Memory Safety: Medium
sprintf was used to format a /proc path without bounds checking.
While pid_t values are practically bounded, using snprintf with
sizeof(root_path) ensures the buffer cannot overflow regardless
of the input value, following defense-in-depth principles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
We don't need 2 convolvers anymore, we can use the same convolver with
2 outputs with the left and right ir.
Add latency option to the sofa plugin. I believe the latency of the
SOFA filters is by default 0, so use that.
Add support for multiple convolver outputs. This makes things more
efficient because we only need to do the input FFT once to produce the N
outputs.
Add convolver2 that can have multiple outputs.
We need to deactivate the graph when the format was cleared on both the
input and output. This means we got suspended and we need to clear. We
can safely do this now because we take the right locks.
SF_FORMAT_WAVEX is not supported to SF_ENDIAN_CPU. Due to that, unable
to record in .wav file (for > 2 channels). Add case for SF_FORMAT_WAVEX
to get assign SF_ENDIAN_FILE.
Fixes#5233
1. The period calls were added to handle timeouts.
2. Handle the case where lock must be unlocked after 60s if the
controller owning the locked does not release it.
Takes an input file, processes it with audioconvert and writes to an
output file. Can be used to test all audioconvert features such as
resample, channelmix, filter-graph, format conversion, dither, etc.
Boilerplate written by Claude.
The object, node, client, factory, module, and link IDs are all uint32_t values but were being formatted with %d.
This would produce incorrect negative values if an ID ever exceeded INT_MAX
When a node is inactive but linked to a driver, the only reason it is
not being scheduled is because it is inactive.
We already set up the links and negotiate the format and buffers to
prepare going to RUNNING. This patch now also make the node go to IDLE,
which makes the adapter negotiate a forma and buffers with the internal
node.
This makes things more symetrical, when linking a node, it becomes IDLE,
when activating it becomes RUNNABLE, when inactive it goes back to IDLE.
The switch to RUNNING will also be faster when things are already set up
in the IDLE state.
The main advantage is that it allows us to implement the startup of
corked streams in pulseaudio better. Before this patch we had to set the
stream to active to make it go through the Format and buffer negotiation
and then quickly set it back to inactive, hopefully without skipping a
cycle. After this patch, the corked stream goes all the way to IDLE,
where it then waits to become active.
See #4991
When the search path is /usr/lib/, /usr/lib/foo.so fails to load because
there is no / after the search path. Fix this by requiring that either
the search path end with / or the following char is a /.
When pw_init() was not called and the init_count is 0, the plugin path
was not set and loading plugins will fail/segfault.
Avoid this and return en error early instead with a message that
pw_init() should be called first.
See !2784
COLS could be very small and the statusbar array might overflow with
strcpy and strcat. Also initializing the variable array seems to cause
problems on older compilers.
Instead use a fixed array that is big enough to hold all possible
values we write into it.
Add a standalone tool that creates virtual AVB talker/listener endpoints
visible in the PipeWire graph (e.g. Helvum). Uses the loopback transport
so no AVB hardware or network access is needed.
The sink node consumes audio silently, the source produces silence.
Supports --milan flag for Milan v1.2 mode and --name for custom node
name prefix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add stream_setup_socket and stream_send ops to avb_transport_ops so the
stream data plane can use the same pluggable transport backend as the
control plane. Move the raw AF_PACKET socket setup from stream.c into
avdecc.c as raw_stream_setup_socket(), and add a raw_stream_send()
wrapper around sendmsg().
Add a stream list (spa_list) to struct server so streams can be iterated
after creation, and add stream_activate_virtual() for lightweight
activation without MRP/MAAP network operations.
Implement loopback stream ops: eventfd-based dummy sockets and no-op
send that discards audio data. This enables virtual AVB nodes that work
without network hardware or privileges.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a test suite for the AVB (Audio Video Bridging) protocol stack that
runs entirely in software, requiring no hardware, root privileges, or
running PipeWire daemon.
The loopback transport (avb-transport-loopback.h) replaces raw AF_PACKET
sockets with in-memory packet capture, using a synthetic MAC address and
eventfd for protocol handlers that need a valid fd.
Test utilities (test-avb-utils.h) provide helpers for creating test
servers, injecting packets, advancing time, and building ADP packets.
Tests cover:
- ADP entity available/departing/discover/timeout
- MRP attribute lifecycle (create, begin, join)
- Milan v1.2 mode server creation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce struct avb_transport_ops vtable with setup/send_packet/
make_socket/destroy callbacks. The existing raw AF_PACKET socket code
becomes the default "raw" transport. avdecc_server_new() defaults to
avb_transport_raw if no transport is set, and avdecc_server_free()
delegates cleanup through the transport ops.
This enables alternative transports (e.g. loopback for testing) without
modifying protocol handler code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two bugs in handle_cmd_lock_entity_milan_v12():
1. When server_find_descriptor() returns NULL, reply_status() was called
with the AEM packet pointer instead of the full ethernet frame,
corrupting the response ethernet header.
2. When refreshing an existing lock, the expire timeout was extended by
raw seconds (60) instead of nanoseconds (60 * SPA_NSEC_PER_SEC),
causing the lock to expire almost immediately after re-lock.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>