Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Jun 2026 09:56:00 +0000
From:      Christos Margiolis <christos@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 0f4aac7ed5ae - stable/15 - sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()
Message-ID:  <6a3f9e30.31f8b.1bca4ad6@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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[] = {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a3f9e30.31f8b.1bca4ad6>