Skip to content

[Problem]: DSP buffer overflow when resampling 48 kHz audio to 192 kHz #2261

Description

@cwawak

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?

  • Check if your system uses a Sound Server.

How did you install Shairport Sync?

Built from source

Check previous issues

  • Confirm

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions