Commit graph

14749 commits

Author SHA1 Message Date
Wim Taymans
1b1c5bda98 security: fix integer overflow in PulseAudio message buffer allocation
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>
2026-05-08 13:41:56 +02:00
Wim Taymans
00a2fcbceb security: fix missing fdopen() NULL check in conf.c
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>
2026-05-08 13:41:50 +02:00
Wim Taymans
0b11792194 filter-graph: error when there are no valid nodes
The nodes might have failed to load or there was an empty array or the
array did not contain objects.
2026-05-08 13:28:28 +02:00
Wim Taymans
c91e9ded7d modules: handle more stream setup failures
Instead of silently ignoring things.
2026-05-08 13:23:32 +02:00
Wim Taymans
3ad062247d loopback: handle stream setup failure
Instead of silently failing.
Also when we do the cleanup, make sure we don't free the props twice.
2026-05-08 13:23:25 +02:00
Wim Taymans
1d3eb1025c impl-link: use the right port direction string
We might swap input and output so make sure we use the right one in the
debug log to avoid confusion.
2026-05-08 13:22:57 +02:00
Wim Taymans
3eb7315bda connection: reject too large messages
Instead of silently truncating the message size in the header, simply
reject the complete message.
2026-05-08 12:37:40 +02:00
Wim Taymans
08f7fef820 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-05-08 12:36:44 +02:00
Wim Taymans
9b04249f37 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-05-08 12:23:36 +02:00
Wim Taymans
4a303edb9e spa: limit the number of buffer blocks
Unbounded values might overflow the stack.
2026-05-08 12:17:50 +02:00
Wim Taymans
3a503ea4b6 filter-graph: remove the pipe filter
It's a terrible idea, doesn't work so well (locks up the data-loop when
read is blocked) and a security mightmare. If you really need to pipe
samples through some program, do that somewhere else, like from the
command line with pw-cat and pw-record.
2026-05-08 12:03:37 +02:00
Wim Taymans
82dbfd558f acp: partially revert f76327e076
The Line Out mute seems to break things.

See #5246
2026-04-28 12:11:53 +02:00
Wim Taymans
8bf7ae5e74 audiomixer: rate limit the "out of buffers" debug
See #5249
2026-04-28 12:11:42 +02:00
Wim Taymans
1825bf696e roc-source: handle some errors better 2026-04-28 12:11:27 +02:00
Wim Taymans
30a77456fc 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-28 12:10:54 +02:00
Wim Taymans
3e67b89a1a 1.6.4 2026-04-22 10:30:36 +02:00
Charles
51c6e70ae5 gst: fix crop height typo in pipewiresink do_send_buffer
The crop region height was incorrectly set to meta->width instead of
meta->height when copying GstVideoCropMeta into the SPA buffer.
2026-04-22 10:18:20 +02:00
zuozhiwei
e01ff7e67e audioconvert: fix tmp_datas[1] when scratch ports grow 2026-04-21 17:17:31 +02:00
Masum Reza
cf8a0b012f alsa: acp: don’t override user-selected port on availability changes
ACP was re-selecting the “best” port on every port availability event,
even when a port was already explicitly selected by the user. This
differs from PulseAudio’s behavior, where port switching decisions are
left to higher-level policy.

This caused issues on devices where Line Out (speakers) and Headphones
share the same analog interface: when headphones are plugged in, ACP
would immediately switch away from the user-selected Line Out, or end up
in a state where no sound is produced despite selecting speakers explicitly from
clients like pwvucontrol.

Fix this by only re-evaluating and switching ports when:
  - no active port is currently selected, or
  - the active port has become unavailable

This preserves manual user choices and prevents ACP from fighting client
port selections during route activation.

Additionally, adjust ALSA mixer paths to better separate Line Out and
Headphones behavior:
  - Disable Line Out controls in the headphones path
  - Add explicit Line Out and Auto-Mute Mode handling in the lineout path

Together, these changes align PipeWire’s behavior more closely with
PulseAudio and fix cases where selecting speakers while headphones are
plugged results in no audio output.

Signed-off-by: John Titor <masumrezarock100@gmail.com>
2026-04-21 17:15:05 +02:00
Pauli Virtanen
04af44d5c3 bluez5: more MT7925 quirks
The MT7925 chipset has several alternative USB ids recognized by kernel,
list them all.

(cherry picked from commit cee1bdfb5a)
2026-04-19 19:15:23 +03:00
Pauli Virtanen
bb6199214d bluez5: add quirk for LC3-24kHz for HFP
MT7925 fails to setup a SCO connection that results to working LC3-24kHz
audio. Other controllers (Intel etc) appear to work OK.

Add quirk for disabling this codec, and disable it for this Mediatek
controller.

(cherry picked from commit 84e6845aa6)
2026-04-19 19:15:23 +03:00
Pauli Virtanen
b2028a03f0 bluez5: fix disabling HFP codecs via bluez5.codecs
backend-native should not advertise disabled HFP codecs as available.

(cherry picked from commit 6e8e234e61)
2026-04-19 19:15:23 +03:00
Martin Geier
c148028f5a bluez5: iso-io: don't use streams without tx_latency enabled for fill level calculation
When there is a stream without tx_latency enabled, the fill_count ends
with MIN_FILL value. This causes one buffer of silence to be written to
every stream before the actual data in each iteration.
Consequently, more data is written than consumed in each iteration.
After several iterations, spa_bt_send fails, triggering a
group_latency_check failure in few next iterations and leading to
dropped data.

Skip streams without tx_latency enabled in fill level calculations
to prevent these audio glitches.

(cherry picked from commit 42415eadd9)
2026-04-19 19:15:23 +03:00
Alexander Sarmanow
78888a78c3 bluez5: bap: add support for manual BIS config
(cherry picked from commit 54a4515b09)
2026-04-19 19:15:23 +03:00
ValdikSS
5918e6f05d bluez5: aac: Use VBR encoding with Mode 5 by default
(cherry picked from commit ee1b429441)
2026-04-19 19:15:23 +03:00
ValdikSS
cb1d19e433 bluez5: aac: use higher band limit for CBR mode
FDK-AAC encoder uses band pass filter, which is automatically
applied at all bitrates.
For CBR encoding mode, its values are as follows (for stereo):

* 0-12 kb/s:   5   kHz
* 12-20 kb/s:  6.4 kHz
* 20-28 kb/s:  9.6 kHz
* 40-56 kb/s:  13  kHz
* 56-72 kb/s:  16  kHz
* 72-576 kb/s: 17  kHz

VBR uses the following table (stereo):

* Mode 1: 13   kHz
* Mode 2: 13   kHz
* Mode 3: 15.7 kHz
* Mode 4: 16.5 kHz
* Mode 5: 19.3 kHz

17 kHz for CBR is a limiting value for high bitrate.

Assume >110 kbit/s as a "high bitrate" CBR and increase the
band pass cutout up to 19.3 kHz (as in mode 5 VBR).

Link: d8e6b1a3aa/libAACenc/src/bandwidth.cpp (L114-L160)
(cherry picked from commit a35b6b0c4b)
2026-04-19 19:15:23 +03:00
ValdikSS
cc71d011e0 bluez5: aac: use maximum possible peak bitrate according to MTU
Android 11 and newer, in both CBR and VBR modes,
* Sets bitrate (AACENC_BITRATE) to the max_bitrate value of A2DP
* Sets peak bitrate (AACENC_PEAK_BITRATE) according to the maximum data
   which could fit into single audio packet based on MTU

AACENC_BITRATE is used only in CBR mode. For VBR mode, the only limiting
factor is AACENC_PEAK_BITRATE.

Do the same in Pipewire.

Link: https://gitlab.freedesktop.org/pipewire/pipewire/-/work_items/1482#note_2949680
Link: https://cs.android.com/android/platform/superproject/+/android16-qpr2-release:packages/modules/Bluetooth/system/stack/a2dp/a2dp_aac_encoder.cc;drc=37d7b4549f7b8740df1a290f04c20c591a2d3391;l=269
(cherry picked from commit 49d5f4f236)
2026-04-19 19:15:23 +03:00
Chiluka Rohith
d444eebea4 pw-cat: Fix waveX format endian assign
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
2026-04-16 13:57:37 +02:00
Wim Taymans
686095ea97 pipewire-jack: also ignore ports with other DSP type
The DSP port type needs to be something else than "other" for it
to become visible. This way we can also remove the IS_VISIBLE check
because we never add invisible ports to the object list.
2026-04-16 13:57:34 +02:00
Wim Taymans
c3c3cb7ef2 jack: don't emit "other" ports
When we see a non-dsp port, simply ignore it. This will make sure also
the links are ignored.

See #3512
2026-04-16 13:57:31 +02:00
Wim Taymans
e0697f52c3 alsa-seq: add : between client and port name
The separator is important for applications to find the client name and
group ports.

Fixes #5229
2026-04-16 10:19:05 +02:00
zuozhiwei
b0f719edd4 alsa: fix inverted port validity check in port_reuse_buffer
The CHECK_PORT condition in impl_node_port_reuse_buffer was inverted with a negation operator, causing the function to reject valid output ports and accept invalid ones.

Fixes the logic so that valid ports proceed to buffer recycling and invalid ports are properly rejected.
2026-04-16 10:18:58 +02:00
Wim Taymans
db0fa4b419 filter-graph: allow negative Gain in mixer
To allow for polarity changes.

Fixes #5228
2026-04-16 10:18:47 +02:00
Wim Taymans
d9b6153123 alsa-seq: remove port from mix_list on destroy
When the port is destroyed we need to remove it from the mix_list or
else the process function will keep trying to use the invalid memory.

This is because the port logic does not want to call any functions on
the port (like clearing the IO or Format) after it emitted the destroy
signal and we need to clean up ourselves.

Fixes #5221
2026-04-16 10:18:30 +02:00
Wim Taymans
8be0d7534b dlopen: support search path ending in /
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 /.
2026-04-16 10:18:03 +02:00
Wim Taymans
00b12dc67a pipewire: check init count before loading plugins
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
2026-04-16 10:17:52 +02:00
Wim Taymans
cc3d0d1191 1.6.3 2026-04-08 18:00:08 +02:00
Wim Taymans
cf88df2185 filter-chain: don't corrupt the enumerated properties
When we add a Format property after we dereffed all the other params in
the builder, we might relocate the builder memory and invalidate all
previously dereffed params, causing corruption.

Instead, first add all the params to the builder and then deref the
params.

There is a special case when we have both a capture and playback
stream. The capture stream will receive all filter params and the
playback stream will just receive its Format param.

Fixes #5202
2026-04-08 17:55:36 +02:00
Wim Taymans
d6adf944df filter-graph: return current control value correctly
The control values are only set in the port control_data after the
filter has been activated and the instances are created.

Property enumerations might happen before that and then we can either
return the current_value (when set in a control section or later with a
param property) or the default value.
2026-04-08 17:55:33 +02:00
Wim Taymans
821b62dac5 dlopen: improve prefix check some more
If we pass a path /usr/libevil/mycode.so, it might have a prefix of
/usr/lib but we should still reject it. Do thi by checking that after
the prefix match, we start a new directory.
2026-04-08 16:22:04 +02:00
Wim Taymans
1ac706c3bc mem: handle overflow in pw_map_range_init()
Integer overflows can result in map_range_init() to return wrong offset
or size that can result in access to invalid or unmapped memory.

Check for the overflows and return an EOVERFLOW error.

Found by Claude Code.
2026-04-08 16:21:38 +02:00
Wim Taymans
6c00e598e5 protocol-native: check msg fds against available fds
Check that the number of fds for the message does not exceed the number
of received fds with SCM_RIGHTS.

The check was simply doing an array bounds check. This could still lead
to out-of-sync fds or usage of uninitialized/invalid fds when the
message header claims more fds than there were passed with SCM_RIGHTS.

Found by Claude Code.
2026-04-08 16:21:24 +02:00
Wim Taymans
aed82af07f module-rtp: handle the send_packet/feedback as callbacks
They are emited from the streaming thread and therefore can be emitted
concurrently with the events on the main thread. This can cause crashes
when the hook list is iterated.

Instead, make those events into callbacks that are more efficient,
and threadsafe.
2026-04-07 10:54:37 +02:00
Wim Taymans
fd867cf655 mixer: handle control.ump property
Add a control.ump port property. When true, the port wants UMP and the
mixer will convert to it. When false, the port supports both UMP and
Midi1 and no conversions will happen. When unset, the mixer will always
convert UMP to midi1.

Remove the CONTROL_types property from the filter. This causes problems
because this is the format negotiated with peers, which might not
support the types but can still be linked because the mixer will
convert.

The control.ump port property is supposed to be a temporary fix until we
can negotiate the mixer ports properly with the CONTROL_types.

Remove UMP handling from bluetooth midi, just use the raw Midi1 events
now that the mixer will give those and we are supposed to output our
unconverted format.

Fix midi events in-place in netjack because we can.

Update docs and pw-mididump to note that we are back to midi1 as the
default format.

With this, most of the midi<->UMP conversion should be gone again and we
should be able to avoid conversion problems in ALSA and PipeWire.

Fixes #5183
2026-04-07 10:08:14 +02:00
Wim Taymans
6a8bf93768 midi: don't convert Midi in nodes
Avoid doing conversions in the nodes between Midi formats, just assume
the imput is what we expect and output what we naturally produce.

For ALSA this means we produce and consume Midi1 or Midi2 depending on the
configurtation.

All of the other modules (ffado, RTP, netjack and VBAN) really only
produce and consume MIDI1.

Set the default MIDI format to MIDI1 in ALSA.

Whith this change, almost everything now produces and consumes MIDI1
again (previously the buffer format was forced to MIDI2).

The problem is that MIDI2 to and from MIDI1 conversion has problems in
some cases in PipeWire and ALSA and breaks compatibility with some
hardware.

The idea is to let elements produce their prefered format and that the
control mixer also negotiates and converts to the node prefered format.
There is then a mix of MIDI2 and MIDI1 on ports but with the control
port adapting, this should not be a problem.

There is one remaining problem to make this work, the port format is
taken from the node port and not the mixer port, which would then expose
the prefered format on the port and force negotiation to it with the
peer instead of in the mixer.

See #5183
2026-04-07 10:07:00 +02:00
Wim Taymans
a0c3c2d9e4 mixer: only add input ports to mixer 2026-04-07 10:05:20 +02:00
Wim Taymans
6bc07dfe0e only dlopen from the defined search paths
Don't accept absolute library paths that are not in the search path,
skip the ../ in paths to avoid opening arbitrary libraries from
unexpected places.
2026-04-07 09:51:47 +02:00
Wim Taymans
1689b441d3 Revert "impl-node: Don't suspend when links are busy"
This reverts commit bb0efd777f.

It is unclear what the problem was before this commit. If there are any
pending operations, the suspend should simply cancel them.

See #5207
2026-04-06 10:40:46 +02:00
Wim Taymans
9afb0f1cc6 modules: align rtp_timestamps for sender
When the driver changes, the clock position can also change and there
would be a discont in the rtp_timestamp.

This is not usually a problem except in RAOP mode where the base rtp
timestamp is negotiated and anything that deviates too much is to be
discarded.

If we are not using direct_timestamp for the sender, make sure we always
keep the rtp_time aligned to avoid this problem.

See #5167
2026-03-31 16:41:32 +02:00
Wim Taymans
f83d379a68 modules: improve debug in RTP 2026-03-31 16:41:26 +02:00