Skip to content

AmB2BMedia::writeStream: guard zero sample rate to prevent SIGFPE crash#551

Open
hecko wants to merge 1 commit into
masterfrom
hecko/amb2bmedia-writestream-zero-sample-rate
Open

AmB2BMedia::writeStream: guard zero sample rate to prevent SIGFPE crash#551
hecko wants to merge 1 commit into
masterfrom
hecko/amb2bmedia-writestream-zero-sample-rate

Conversation

@hecko

@hecko hecko commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Bug

AudioStreamData::writeStream (core/AmB2BMedia.cpp) does:

int sample_rate = stream->getSampleRate();
int got = 0;
if (in) got = in->get(ts, buffer, sample_rate, f_size);
...
  got = src_stream->get(ts, buffer, sample_rate, f_size);
...
  return stream->put(ts, buffer, sample_rate, got);

getSampleRate() returns 0 when the stream format is not yet set (or a zero-clock-rate codec was negotiated). sample_rate is then used as the divisor deeper in the AmAudio chain — e.g. AmBufferedAudio::get:

size_t nget = PCM16_S2B(nb_samples * getSampleRate() / output_sample_rate);

With output_sample_rate == 0 this is an integer divide-by-zero → SIGFPE, whole process crash. It is reachable on the B2B/SBC media path whenever a leg with a custom input (announcement / hold music / playback = an AmBufferedAudio) is attached to a stream whose sample rate is still 0.

Fix

Return early when sample_rate == 0, before any get()/put() call. This mirrors the identical guard already merged for AmSession::writeStreams (#542); this parallel B2B path was left unpatched.

int sample_rate = stream->getSampleRate();
if (sample_rate == 0) return 0;

Validation

  • Confirmed the buggy path is present in current master and that the divide sink (AmBufferedAudio::get, core/AmBufferedAudio.cpp:90) performs integer division by output_sample_rate.
  • Confirmed AmSession::writeStreams already carries the equivalent guard (with the same SIGFPE comment), so this only closes the remaining sibling gap.

Acknowledgement

Backport of the fix from the yeti-switch/sems fork, commit dc7aa5563d705eb7be1ee46706a9eda18fbbeb88 ("AmSession,AmB2BMedia::writeStreams: return 0 on zero output_sample_rate"). Thanks to the yeti-switch maintainers.


Generated by Claude Code

…FPE)

AudioStreamData::writeStream fetches sample_rate = stream->getSampleRate()
and passes it as the output sample rate into the AmAudio get()/put() chain.
getSampleRate() returns 0 when the stream format is not set yet or a
zero-clock-rate codec was negotiated, and that value is used as a divisor
in AmBufferedAudio::get (nb_samples * getSampleRate() / output_sample_rate),
raising SIGFPE and taking down the whole process on the B2B/SBC media path.

Return early when sample_rate == 0, mirroring the guard already present in
AmSession::writeStreams. Backport of yeti-switch/sems dc7aa556.
Copilot AI review requested due to automatic review settings July 10, 2026 03:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds a safeguard in the B2B media send path to prevent a divide-by-zero (SIGFPE) crash when the stream sample rate is still unset (0).

Changes:

  • Early-return from AudioStreamData::writeStream when stream->getSampleRate() returns 0
  • Documents why the guard is needed and aligns behavior with AmSession::writeStreams

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants