DF-4952 / fix.diff
--- a/sys/dev/sound/pcm/feeder_mixer.c +++ b/sys/dev/sound/pcm/feeder_mixer.c @@ -198,6 +198,16 @@ cnt = FEEDER_FEED(c->feeder->source, c, b->tmpbuf, min(cnt, maxfeed), c->bufhard); if (cnt != 0) { + if (cnt > sndbuf_getfree(b)) { + /* + * Feeder-contract violation (over-return): + * clamp so b->rl can never pass b->bufsize + * and sndbuf_getfree() wrap to ~4G, which + * would re-arm min(cnt, maxfeed) requests + * far past b->tmpbuf (heap OOB write). + */ + cnt = sndbuf_getfree(b); + } sndbuf_acquire(b, b->tmpbuf, cnt); cnt = sndbuf_getfree(b); } @@ -359,6 +369,8 @@ if (rcnt == 0) { rcnt = SND_FXROUND(FEEDER_FEED(ch->feeder, ch, b, count, ch->bufsoft), sz); + if (rcnt > count) + rcnt = count; /* no mcnt underflow */ mcnt = count - rcnt; } else { cnt = SND_FXROUND(FEEDER_FEED(ch->feeder, ch, |