--- 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);