git: 0f4aac7ed5ae - stable/15 - sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 27 Jun 2026 09:56:00 UTC
The branch stable/15 has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=0f4aac7ed5ae5b5cc8bd45597a91b7011067a6ef
commit 0f4aac7ed5ae5b5cc8bd45597a91b7011067a6ef
Author: Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2026-06-12 06:19:07 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2026-06-27 09:55:21 +0000
sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()
We drop the channel lock to execute cdev_pager_allocate(). By the time
we pick up the lock again, CHN_F_MMAP_INVALID might be set, so make sure
we fail and free the vm handle.
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj, kib
Pull-Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
(cherry picked from commit 47efa8128268c35ac8f0a552d7a7ce43cd1c5925)
---
sys/dev/sound/pcm/dsp.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 3f0c5d622f99..471db6524aa2 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -1957,6 +1957,7 @@ dsp_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
struct snddev_info *d;
struct pcm_channel *c;
int err;
+ bool dealloc;
if (*offset >= *offset + size)
return (EINVAL);
@@ -2008,12 +2009,25 @@ dsp_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
*object = cdev_pager_allocate(handle, OBJT_DEVICE, &dsp_dev_pager_ops,
size, nprot, *offset, curthread->td_ucred);
PCM_GIANT_LEAVE(d);
- if (*object == NULL) {
+ if (*object != NULL) {
+ err = 0;
+ dealloc = false;
+ CHN_LOCK(c);
+ if (c->flags & CHN_F_MMAP_INVALID) {
+ c->flags &= ~CHN_F_MMAP;
+ err = EINVAL;
+ dealloc = true;
+ }
+ CHN_UNLOCK(c);
+ /* We use a helper bool to keep the channel locking simpler. */
+ if (dealloc)
+ vm_object_deallocate(*object);
+ } else {
free(handle, M_DEVBUF);
- return (EINVAL);
+ err = ENOMEM;
}
- return (0);
+ return (err);
}
static const char *dsp_aliases[] = {