DF-1337 / fix.diff
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1759,6 +1759,17 @@ CHN_LOCKASSERT(c); + /* + * Wait for any in-flight chn_read/chn_write to finish before resizing + * the buffer. chn_read/chn_write drop the channel lock across uiomove() + * while holding a raw pointer into bs->buf; a concurrent remalloc here + * would free that buffer from under them (use-after-free write/read). + * The SILENCE/SKIP ioctls already wait via this counter (see dsp.c); the + * blocksize/fragment/format-change ioctls must do the same. + */ + while (c->inprog != 0) + cv_wait(&c->cv, c->lock); + if ((c->flags & (CHN_F_MMAP | CHN_F_TRIGGERED)) || !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC)) return EINVAL; |