⬢ DragonFlyBSD Kernel Audit
DF-4952 / fix.diff
← back to finding ↓ download raw
--- 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,