aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound/pcm/buffer.h
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-06-01 21:57:40 +0000
committerMark Johnston <markj@FreeBSD.org>2026-06-09 02:59:34 +0000
commitabc077216bac75eaa8ab517721e585d7e61e2d4f (patch)
tree88af6e03dc167e12148b9d9c5bbea2655d0e2e77 /sys/dev/sound/pcm/buffer.h
parent513db24414f0eae90c280b480b4453e9e4f04714 (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.h4
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);