diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2026-06-01 21:57:40 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2026-06-09 02:59:34 +0000 |
| commit | abc077216bac75eaa8ab517721e585d7e61e2d4f (patch) | |
| tree | 88af6e03dc167e12148b9d9c5bbea2655d0e2e77 /sys/dev/sound/pcm/buffer.h | |
| parent | 513db24414f0eae90c280b480b4453e9e4f04714 (diff) | |
sound: Fix software buffer lifetime issues
The channel buffer mapped by dsp_mmap_single() may be freed when the
device handle is closed, but the mapping persists beyond that, allowing
userspace to read or write memory owned by a different consumer.
Fix the problem by adding a reference counter to the sound buffer.
Define pager ops for the VM object returned by dsp_mmap_single() and use
them to manage the extra reference.
Add a regression test.
Approved by: re (cperciva)
Approved by: so
Security: FreeBSD-SA-26:27.sound
Security: CVE-2026-49417
Reported by: Lexpl0it, 75Acol, Liyw979, Rob1n
Reviewed by kib
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D57393
Diffstat (limited to 'sys/dev/sound/pcm/buffer.h')
| -rw-r--r-- | sys/dev/sound/pcm/buffer.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/sys/dev/sound/pcm/buffer.h b/sys/dev/sound/pcm/buffer.h index 371ba2dd94ce..fee41db2ff82 100644 --- a/sys/dev/sound/pcm/buffer.h +++ b/sys/dev/sound/pcm/buffer.h @@ -31,6 +31,7 @@ */ #define SNDBUF_F_MANAGED 0x00000001 +#define SNDBUF_F_DETACHED 0x00000002 #define SNDBUF_NAMELEN 48 @@ -53,6 +54,7 @@ struct snd_dbuf { bus_dma_tag_t dmatag; bus_addr_t buf_addr; int dmaflags; + unsigned int refcount; struct selinfo sel; struct pcm_channel *channel; char name[SNDBUF_NAMELEN]; @@ -60,6 +62,8 @@ struct snd_dbuf { struct snd_dbuf *sndbuf_create(struct pcm_channel *channel, const char *desc); void sndbuf_destroy(struct snd_dbuf *b); +void sndbuf_ref(struct snd_dbuf *b); +void sndbuf_rele(struct snd_dbuf *b); int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size); int sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size); |
