⬢ DragonFlyBSD Kernel Audit
DF-3879 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -2339,7 +2339,13 @@
 
 	c = ((nprot & PROT_WRITE) != 0) ? wrch : rdch;
 	if (c == NULL || (c->flags & CHN_F_MMAP_INVALID) ||
-	    (*offset  + size) > sndbuf_getsize(c->bufsoft) ||
+	    /* DF-3879: vm_ooffset_t is SIGNED (__int64_t): a negative
+	     * *offset made the old (*offset + size) sum land within
+	     * [0, bufsize]; sndbuf_getbufofs() then truncated it to
+	     * unsigned int — wild kernel pointer into the device pager.
+	     * Compare unsigned so negative offsets are rejected. */
+	    (uint64_t)*offset > (uint64_t)sndbuf_getsize(c->bufsoft) ||
+	    size > (uint64_t)sndbuf_getsize(c->bufsoft) - (uint64_t)*offset ||
 	    (wrch != NULL && (wrch->flags & CHN_F_MMAP_INVALID)) ||
 	    (rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) {
 		relchns(i_dev, rdch, wrch, SD_F_PRIO_RD | SD_F_PRIO_WR);