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.
We might overflow the path buffer when we strcat the provided filename
into it, which might crash or cause unexpected behaviour.
Instead use spa_scnprintf which avoids overflow and properly truncates
and null-terminates the string.
Found by Claude Code.
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.
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
Using connect() on a UDP receiver creates a strict filter based on
the sender's _source_ port, not the sender's destination port. The
source port specifies at what sender port the packet exits the sender.
The destination port specifies at what receiver port the packet enters
the receiver. But, the RTP sink uses an ephemeral (= random) port as the
source port. Consequently, connect() at the receiver will cause a
comparison of that ephemeral port with the fixated one (which is actually
the number of the _destination_ port). This incorrect filtering causes
all packets to be dropped.
Use bind() to filter for the local destination port, and use recvmsg()
with manual IP comparison to filter for the sender's identity.
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.
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
Since abf37dbdde the param enumeration in
the client-node can return 0 when the parameter is supported but there
are no params uploaded.
When negotiating buffers we need to assume a 0 result as a NULL filter
as well or else we will error.
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
Previously, if a remote node was set to running and immediately reverted
to suspended state, the remote node stayed in running state. This occurred
because suspend_node sent suspend command only when the locally cached
state was "idle" or "running."
Modified to send suspend to a node whenever its pending state is not
"suspended," ensuring the command is sent during state transitions.
Fixes#5026
Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
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
Going from PLAYING to PAUSED will have basesrc calling unlock and
setting flushing to false. Going back to PLAYING may then fail in
wait_negotiated, as unlock_stop will be called after change_state.
Fix by remove the flushing check, since already in that "state".
This fixes a missing definition error in thread.c:
../src/pipewire/thread.c:129:30: error: use of undeclared identifier 'SCHED_RESET_ON_FORK'
129 | SPA_FLAG_UPDATE(new_policy, SCHED_RESET_ON_FORK, reset_on_fork);
As stated in https://pubs.opengroup.org/onlinepubs/9799919799//basedefs/netinet_in.h.html,
> The <netinet/in.h> header shall define the sockaddr_in structure [...]
This fixes the following build error:
In file included from ../src/modules/module-protocol-native.c:44:
../src/modules/network-utils.h:96:35: error: incomplete definition of type 'struct sockaddr_in'
96 | if (inet_ntop(sa->ss_family, &in->sin_addr, ip, len) == NULL)
| ~~^
NULL tags are never handled and so tags just keeps configured on the
ports. It's also hard to know the direction from the NULL data.
Instead, send an empty Tag with the direction to clear everything.
Don't close an -1 fd in clear_data.
If we let the client allocate buffer, set our fd and data to invalid
values. If the client decides to renegotiate before we get the buffer
data we might otherwise try to clear the mem_id (default 0) or
close the fd (also default 0).
Fixes#5162
If a file descriptor is expected to be closed by the associated `pw_memblock`,
and closing fails, then that usually signals a more serious issue in the memory
accounting. So add a log message when that happens.
Previously when parameters were enumarated, it was checked if at least one
param was known for `id`. If not, `-ENOENT` was returned to signal that
this param id is not supported.
This is not necessarily true, since a param id might be supported, but it
might have zero params at the moment, in which case an unexpected error
would be returned.
Fix that by using `pw_param_info_find()` with the underlying impl object
to check if the param id is actually supported.
If the param enumeration fails, do not set `spa_param_info::user` to 1
indicating that the result is cached. Doing so can lead to the first
(uncached) call failing, while the rest will succeed (with 0 params).