What happened?
With convolution enabled, Shairport Sync reproducibly segfaulted when resampling an AirPlay 2 stream from 48 kHz to fixed 192 kHz output.
player.c allocates 1,024 floats per channel:
float (*fbufs)[1024] =
malloc(conn->input_num_channels * sizeof(*fbufs));
It then writes up to inframe->length. In the failing session, the resampled frame length was 4,032, so writes were out of bounds beginning at index 1,024.
A minimal tested fix is:
- float (*fbufs)[1024] = malloc(conn->input_num_channels * sizeof(*fbufs));
+ float (*fbufs)[inframe->length] =
+ malloc(conn->input_num_channels * sizeof(*fbufs));
The patched build successfully played the same 48 to 192 kHz stream with convolution.
Relevant log output
AirPlay 2 Buffered playback
Input format: AAC/48000/F24/2
Output format: 192000/S32_LE/2
Program terminated with signal SIGSEGV.
#0 player_thread_func (...) at player.c:4621
4621 fbufs[j][i] = tbuf32[conn->input_num_channels * i + j];
i = 1048
inframe->length = 4032
conn->input_num_channels = 2
convolver_is_valid = 0
The crash was captured with commit:
eb49aaabd29908f17b126fdca350aaaed1003e59
5.2-dev-44
A patched build based on fadd43d06e8685c7cb508042f5716f25828a77d8 completed the same playback without a crash or service restart.
A focused AddressSanitizer test reports a heap-buffer-overflow with the fixed allocation and passes with the dynamic allocation.
System Information.
Raspberry Pi 4 Model B Rev 1.4
Debian GNU/Linux 12 (bookworm)
Linux 6.6.70-v8+ aarch64
Yamaha USB DAC through ALSA
Configuration Information.
AirPlay supplies 48 kHz audio. This system uses a fixed 192 kHz S32_LE ALSA `dmix` device so Shairport Sync and MPD can coexist while MPD can play native 192 kHz sources without downsampling.
Shairport therefore resamples AirPlay to the shared device rate.
Relevant ALSA configuration:
pcm.shared_dac_dmix {
type dmix
slave {
pcm "hw:DAC"
format S32_LE
rate 192000
channels 2
}
}
pcm.shared_dac {
type plug
slave {
pcm "shared_dac_dmix"
format S32_LE
rate 192000
channels 2
}
}
Relevant Shairport Sync configuration:
alsa = {
output_device = "shared_dac";
output_rate = 192000;
output_format = "S32_LE";
};
dsp = {
convolution_enabled = "yes";
convolution_ir_files = "/etc/shairport-sync/filters/impulse-192000.wav";
};
The impulse response is a valid mono, 192 kHz floating-point WAV. The overflow occurs during deinterleaving, before the convolver is initialized.
PulseAudio or PipeWire installed?
How did you install Shairport Sync?
Built from source
Check previous issues
What happened?
With convolution enabled, Shairport Sync reproducibly segfaulted when resampling an AirPlay 2 stream from 48 kHz to fixed 192 kHz output.
player.callocates 1,024 floats per channel:It then writes up to
inframe->length. In the failing session, the resampled frame length was 4,032, so writes were out of bounds beginning at index 1,024.A minimal tested fix is:
The patched build successfully played the same 48 to 192 kHz stream with convolution.
Relevant log output
System Information.
Raspberry Pi 4 Model B Rev 1.4
Debian GNU/Linux 12 (bookworm)
Linux 6.6.70-v8+ aarch64
Yamaha USB DAC through ALSA
Configuration Information.
PulseAudio or PipeWire installed?
How did you install Shairport Sync?
Built from source
Check previous issues