sound: Refactor dsp_mmap_single() #30

Manually merged
christos merged 4 commits from christos/mmap into main 2026-06-20 19:05:53 +00:00 AGit
Member

Sponsored by: The FreeBSD Foundation
MFC after: 1 week

Sponsored by: The FreeBSD Foundation MFC after: 1 week
dsp_mmap_single() mmaps one of the channels associated with a
dsp_cdevpriv, based on the nprot argument. PROT_WRITE and
PROT_READ|PROT_WRITE select the output channel for mmaping, and
PROT_READ the input one. Instead of locking and modifying the flags of
all dsp_cdevpriv channels, do it only for the one we actually use.

While here, retire the now unused dsp_lock_chans() and
dsp_unlock_chans().

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This makes it easier to read. While here, remove some unnecessary
parentheses.

No functional change intended.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Also fix the return value when vm_pager_allocate() fails.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
sound: Ignore user-set offset argument in dsp_mmap_single()
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
166fdfbf20
dsp_mmap_single() re-defines its offset argument in the following line:

	*offset = (uintptr_t)sndbuf_getbufofs(c->bufsoft, *offset);

What sndbuf_getbufofs() does is add the offset to the buffer's head, and
return the resulting address. Most programs do not define the offset
argument in their mmap(2) calls, so this ends up returning the beginning
address of the buffer. However, there are a few problems that can arise
if the offset is defined. A few lines above, we the following check to
make sure that we stay within the buffer's boundaries:

	c->bufsoft->allocsize < *offset + size

Consider a buffer layout with allocsize=8. We have the following
scenarios with regards to the offset and size arguments:

1) offset is 0 and size is less than allocsize: mmap(2) will work
   properly, because we'll end up mapping only a part of the buffer.

2) offset is 0 but size is larger than allocsize: mmap(2) will fail
   because we want to map a region larger than the buffer's.

3) offset is 8 and size is 0: mmap(2) will fail because size=0 is not
   allowed in the first place.

3) offset is 7 and size is 2: mmap(2) will fail because, even though
   size=2, offset+size=9. This is technically fine, but there is
   actually no reason for us to do this. Each buffer is dedicated to a
   single file descriptor, so mapping regions of the buffer at arbitrary
   offsets does not do anything useful, apart from restrict mappings
   where the size is within bounds, but adding it to the offset is not.

4) sndbuf_getbufofs() defines the offset argument as uint32_t, but what
   we supply here is a vm_ooffset_t (uint64_t), so the high 32 bits get
   truncated if the offset cannot be stored in a uint32_t.

To address issues 3 and 4, Ignore the offset argument altogether and
only account for the size.

As a side effect, this patch also fixes a security issue reported to
secteam@ by Lexpl0it <nsa@linux.do>. In short, an unprivileged user
could panic the kernel by supplying specific offsets and sizes to
mmap(2), which could cause the offset+size calculation to overflow and
wrap back to 0, and as a result, pass the check shown before. Then, the
offset returned by sndbuf_getbufofs() would be an address that when
passed to vtophys() in dsp_mmap(), would trigger the following panic:

db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe008d9d67b0
vpanic() at vpanic+0x13f/frame 0xfffffe008d9d68e0
panic() at panic+0x43/frame 0xfffffe008d9d6940
trap_pfault() at trap_pfault+0x429/frame 0xfffffe008d9d69b0
calltrap() at calltrap+0x8/frame 0xfffffe008d9d69b0
--- trap 0xc, rip = 0xffffffff810cb48f, rsp = 0xfffffe008d9d6a80, rbp = 0xfffffe008d9d6a90 ---
pmap_kextract() at pmap_kextract+0x11f/frame 0xfffffe008d9d6a90
dsp_mmap() at dsp_mmap+0x2a/frame 0xfffffe008d9d6ab0
old_dev_pager_ctor() at old_dev_pager_ctor+0x64/frame 0xfffffe008d9d6b00
cdev_pager_allocate() at cdev_pager_allocate+0x297/frame 0xfffffe008d9d6b70
dev_pager_alloc() at dev_pager_alloc+0x28/frame 0xfffffe008d9d6b90
vm_pager_allocate() at vm_pager_allocate+0x2d/frame 0xfffffe008d9d6bb0
dsp_mmap_single() at dsp_mmap_single+0x27f/frame 0xfffffe008d9d6c10
vm_mmap_cdev() at vm_mmap_cdev+0x66/frame 0xfffffe008d9d6c60
devfs_mmap_f() at devfs_mmap_f+0x12a/frame 0xfffffe008d9d6ce0
kern_mmap() at kern_mmap+0x7e5/frame 0xfffffe008d9d6dc0
sys_mmap() at sys_mmap+0x42/frame 0xfffffe008d9d6e00
amd64_syscall() at amd64_syscall+0x16c/frame 0xfffffe008d9d6f30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe008d9d6f30

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
christos changed title from sound: Refactor dsp_mmap_single() to WIP: sound: Refactor dsp_mmap_single() 2026-05-18 15:58:09 +00:00
christos requested reviews from kib, markj 2026-05-18 15:58:10 +00:00
@ -1964,2 +1942,2 @@
(rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) {
dsp_unlock_chans(priv, FREAD | FWRITE);
CHN_LOCK(c);
if (c->flags & CHN_F_MMAP_INVALID || c->bufsoft->allocsize < size) {
Member

What if CHN_F_MMAP_INVALID is set during the region where c is unlocked?

IMO you should re-arrange the actions, not assigning to '*object' until the second CHN_LOCK(), and checking the conditions then. The pre-check for these conditions is useful still, I believe.

What if CHN_F_MMAP_INVALID is set during the region where c is unlocked? IMO you should re-arrange the actions, not assigning to '*object' until the second CHN_LOCK(), and checking the conditions then. The pre-check for these conditions is useful still, I believe.
christos marked this conversation as resolved
christos force-pushed christos/mmap from 166fdfbf20
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to dc63cdb6dc
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-05-20 15:39:06 +00:00
Compare
christos force-pushed christos/mmap from dc63cdb6dc
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to 3f8772bbbf
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-05-22 11:50:25 +00:00
Compare
Member

The solution to the overflow is to silently ignore the user-supplied offset? Isn't that likely to break something?

The solution to the overflow is to silently ignore the user-supplied offset? Isn't that likely to break something?
Author
Member

@markj wrote in #30 (comment):

The solution to the overflow is to silently ignore the user-supplied offset? Isn't that likely to break something?

It isn't the solution to the overflow per-se, more of a side effect. I explain that in the commit message, but I do not see why we should care about the offset, or how it can be useful, or how it is even currently useful, given how sound(4)'s buffer allocations work. That is, for each pcm_channel (assigned to one file descriptor) we allocate a pair snd_dbufs, one consumed by the device driver, one by userland. What mmap(2) does is simply map pages on top of that allocated buffer (the userland-facing one). I am skeptical about whether this is correct design, but it's how sound(4) has been doing it forever.

The reason I'm saying the offset is essentially useless, even with the current implementation, is because sndbuf_getbufofs() itself, as the commit message, as well as the bug submitter, suggests, truncates the vm_ooffset_t value, and also has a KASSERT to make sure the offset is always smaller than the buffer size. In other words, the offset is by design meant to be within the buffer's bounds. So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset.

The OSS manual itself [1] does not seem to include information about how the offset parameter should be handled.

[1] http://manuals.opensound.com/developer/mmap.html

@markj wrote in https://ron-dev.freebsd.org/FreeBSD/src/pulls/30#issuecomment-542: > The solution to the overflow is to silently ignore the user-supplied offset? Isn't that likely to break something? It isn't the solution to the overflow per-se, more of a side effect. I explain that in the commit message, but I do not see why we should care about the offset, or how it can be useful, or how it is even currently useful, given how sound(4)'s buffer allocations work. That is, for each `pcm_channel` (assigned to one file descriptor) we allocate a pair `snd_dbuf`s, one consumed by the device driver, one by userland. What mmap(2) does is simply map pages on top of that allocated buffer (the userland-facing one). I am skeptical about whether this is correct design, but it's how sound(4) has been doing it forever. The reason I'm saying the offset is essentially useless, even with the current implementation, is because `sndbuf_getbufofs()` itself, as the commit message, as well as the bug submitter, suggests, truncates the `vm_ooffset_t` value, and also has a `KASSERT` to make sure the offset is always smaller than the buffer size. In other words, the offset is by design meant to be within the buffer's bounds. So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset. The OSS manual itself [1] does not seem to include information about how the offset parameter should be handled. [1] http://manuals.opensound.com/developer/mmap.html
Member

So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset.

Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later.

> So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset. Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later.
Author
Member

@markj wrote in #30 (comment):

So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset.

Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later.

The current implementation is wrong though. We are passing a vm_ooffset_t to sndbuf_getbufofs() which expects a uint32_t, and because of the truncation combined with how sndbuf_getbufofs() actually works, we're changing the semantics of what the offset parameter is, and we use it as a buffer index instead, which from an application perspective, is useless. Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about.

@markj wrote in https://ron-dev.freebsd.org/FreeBSD/src/pulls/30#issuecomment-544: > > So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset. > > Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later. The current implementation is wrong though. We are passing a `vm_ooffset_t` to `sndbuf_getbufofs()` which expects a `uint32_t`, and because of the truncation combined with how `sndbuf_getbufofs()` actually works, we're changing the semantics of what the offset parameter is, and we use it as a buffer index instead, which from an application perspective, is useless. Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about.
Member

@christos wrote in #30 (comment):

@markj wrote in #30 (comment):

So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset.

Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later.

The current implementation is wrong though. We are passing a vm_ooffset_t to sndbuf_getbufofs() which expects a uint32_t, and because of the truncation combined with how sndbuf_getbufofs() actually works, we're changing the semantics of what the offset parameter is, and we use it as a buffer index instead, which from an application perspective, is useless.

What do you mean by "changing the semantics"? It's up to dsp_mmap_single() to define the semantics in the first place, and it's treating offset as an offset into the channel buffer selected by prot. Unless there are channel buffers larger than 4GB, there is no truncation happening.

Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about.

I'm worried about breaking applications with a security patch, that's all. If you're convinced that no applications are passing a non-zero offset, then fine, dsp_mmap_single() can be reworked, but to start we should land a minimal patch which fixes the overflow bug.

@christos wrote in https://ron-dev.freebsd.org/FreeBSD/src/pulls/30#issuecomment-546: > @markj wrote in #30 (comment): > > > > So what benefit is it? I don't see why someone would intentionally map their buffer just at a higher offset. > > > > > > Yes, the intent is to be able to map starting at some (page-aligned) offset in the buffer. I don't know what benefit that has either, but Chesterson's Fence seems to apply here. At least, I wouldn't be comfortable shipping this as a security patch if we don't know whether it might break something. Why not just directly fix the check to handle overflow? Then any needed cleanup can come later. > > The current implementation is wrong though. We are passing a `vm_ooffset_t` to `sndbuf_getbufofs()` which expects a `uint32_t`, and because of the truncation combined with how `sndbuf_getbufofs()` actually works, we're changing the semantics of what the offset parameter is, and we use it as a buffer index instead, which from an application perspective, is useless. What do you mean by "changing the semantics"? It's up to dsp_mmap_single() to define the semantics in the first place, and it's treating `offset` as an offset into the channel buffer selected by `prot`. Unless there are channel buffers larger than 4GB, there is no truncation happening. > Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about. I'm worried about breaking applications with a security patch, that's all. If you're convinced that no applications are passing a non-zero offset, then fine, dsp_mmap_single() can be reworked, but to start we should land a minimal patch which fixes the overflow bug.
christos force-pushed christos/mmap from 3f8772bbbf
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to 5812ee03ab
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
2026-05-27 15:55:59 +00:00
Compare
Author
Member

@markj wrote in #30 (comment):

Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about.

I'm worried about breaking applications with a security patch, that's all. If you're convinced that no applications are passing a non-zero offset, then fine, dsp_mmap_single() can be reworked, but to start we should land a minimal patch which fixes the overflow bug.

Updated the diff.

@markj wrote in https://ron-dev.freebsd.org/FreeBSD/src/pulls/30#issuecomment-551: > > Additionally, I cannot see how this could cause any issues, since these buffers are assigned to specific channels, and the offset functions as an index inside those per-channel buffers. Each mmap(2) call eventually returns the buffer for that specific channel, almost always at index 0 (I haven't seen an OSS mmap(2) call with a non-zero offset argument so far), or at some index inside that buffer. For this reason, we cannot end up with overlapping mappings, which I suppose would be an issue you'd be worried about. > > I'm worried about breaking applications with a security patch, that's all. If you're convinced that no applications are passing a non-zero offset, then fine, dsp_mmap_single() can be reworked, but to start we should land a minimal patch which fixes the overflow bug. Updated the diff.
christos changed title from WIP: sound: Refactor dsp_mmap_single() to sound: Refactor dsp_mmap_single() 2026-05-28 14:35:45 +00:00
Author
Member

Mark's comments are addressed. This should be good to go.

Mark's comments are addressed. This should be good to go.
@ -1921,2 +1902,4 @@
struct pcm_channel *c;
int err;
if (*offset >= (*offset + size))
Member

Extra ()

Extra ()
christos marked this conversation as resolved
christos force-pushed christos/mmap from 5812ee03ab
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
to bcb8de400a
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-05-29 12:10:47 +00:00
Compare
@ -1955,2 +1936,2 @@
(rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) {
dsp_unlock_chans(priv, FREAD | FWRITE);
CHN_LOCK(c);
if (c->flags & CHN_F_MMAP_INVALID ||
Member

(c->flags & CHN_F_MMAP_INVALID) != 0

(c->flags & CHN_F_MMAP_INVALID) != 0
Author
Member

This is an issue in many places throughout sound(4). I was thinking of fixing all these in a patch in one go instead, no?

This is an issue in many places throughout sound(4). I was thinking of fixing all these in a patch in one go instead, no?
christos marked this conversation as resolved
@ -1970,0 +1948,4 @@
if (*object != NULL) {
CHN_LOCK(c);
if (c->flags & CHN_F_MMAP_INVALID) {
Member

() != 0

() != 0
christos marked this conversation as resolved
@ -1967,3 +1944,1 @@
dsp_unlock_chans(priv, FREAD | FWRITE);
*object = vm_pager_allocate(OBJT_DEVICE, i_dev,
size, nprot, *offset, curthread->td_ucred);
CHN_UNLOCK(c);
Member

Does the invariant c->bufsoft->allocsize < *offset + size stays true after the channel unlock?

Does the invariant c->bufsoft->allocsize < *offset + size stays true after the channel unlock?
Author
Member

Theoretically, allocsize could change if the buffer gets resized during that window. I dont think such a scenario is likely at all, but I could add a check once we pick up the lock again for robustness.

Theoretically, allocsize could change if the buffer gets resized during that window. I dont think such a scenario is likely at all, but I could add a check once we pick up the lock again for robustness.
Member

Then it raises a more generic question, what would happen when (not even if) the buffer is resized after the object is allocated. Would it provide an access to some random memory after the buffer?

Then it raises a more generic question, what would happen when (not even if) the buffer is resized after the object is allocated. Would it provide an access to some random memory after the buffer?
Author
Member

I was thinking the exact same thing now. Because the mappings are essentially a pointer to the sound(4) buffer, then yes, if we re-allocate it, and we end up in different addresses, then the object allocation would still point to the old addresses.

sys/dev/sound/pcm/buffer.c doesn't seem to reallocate memory if the requested size is the same as the current one. I suppose we could cache allocsize when before we drop the lock, and test that against c->allocsize after we pick up the lock back. If the sizes are different, then we deallocate the object and fail. What do you think?

I was thinking the exact same thing now. Because the mappings are essentially a pointer to the sound(4) buffer, then yes, if we re-allocate it, and we end up in different addresses, then the object allocation would still point to the old addresses. `sys/dev/sound/pcm/buffer.c` doesn't seem to reallocate memory if the requested size is the same as the current one. I suppose we could cache `allocsize` when before we drop the lock, and test that against `c->allocsize` after we pick up the lock back. If the sizes are different, then we deallocate the object and fail. What do you think?
Member

How is the reallocation initiated? I would consider disabling it if there is at least one mapping.

How is the reallocation initiated? I would consider disabling it if there is at least one mapping.
Author
Member

There seem to be 2 reallocation functions, but one that actually remallocs c->bufsoft->buf, which is where the mmap address comes from, and that's in sndbuf_remalloc(). This one is called only from chn_resizebuf(), but the function fails at the very beginning if CHN_F_MMAP is set.

In one of my patches here I move the CHN_F_MMAP setting after everything has succeeded, so chn_resizebuf() will be able to continue. I could bring back the check before we unlock, and instead of setting the flag when everything succeeds, I can just clear it we fail.

The other function, sndbuf_resize() does change allocsize if the size is different than the current one, but doesn't remalloc buf, it just mallocs tmpbuf. I don't fully understand this, but this function is called only from the device drivers, so it actually affects c->bufhard, not c->bufsoft, so we can ignore it.

There seem to be 2 reallocation functions, but one that actually remallocs `c->bufsoft->buf`, which is where the mmap address comes from, and that's in `sndbuf_remalloc()`. This one is called only from `chn_resizebuf()`, but the function fails at the very beginning if `CHN_F_MMAP` is set. In one of my patches here I move the `CHN_F_MMAP` setting after everything has succeeded, so `chn_resizebuf()` will be able to continue. I could bring back the check before we unlock, and instead of setting the flag when everything succeeds, I can just clear it we fail. The other function, `sndbuf_resize()` does change `allocsize` if the size is different than the current one, but doesn't remalloc `buf`, it just mallocs `tmpbuf`. I don't fully understand this, but this function is called only from the device drivers, so it actually affects `c->bufhard`, not `c->bufsoft`, so we can ignore it.
christos marked this conversation as resolved
christos force-pushed christos/mmap from bcb8de400a
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to e610965bdf
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-05-29 12:56:38 +00:00
Compare
Member

Could there be more than one mapping for the channel? If yes, you cannot use a flag to track it.

Could there be more than one mapping for the channel? If yes, you cannot use a flag to track it.
Member

Thanks, I will stage the overflow check for the next secteam release. Please avoid landing patches in this area until then, as that will make life easier when we push patches to main/stable/releng branches, and since there will be another patch on top of this one in the secteam release (I will post a patch for review soon).

In general we should avoid publicly posting patches which fix severe security bugs. My workflow for this is to create a phab revision with git arc create -d, then in the webui, limit visibility to subscribers only, then public the review. This is not perfect but I don't think there's a better way to handle it, short of emailing patches around.

Thanks, I will stage the overflow check for the next secteam release. Please avoid landing patches in this area until then, as that will make life easier when we push patches to main/stable/releng branches, and since there will be another patch on top of this one in the secteam release (I will post a patch for review soon). In general we should avoid publicly posting patches which fix severe security bugs. My workflow for this is to create a phab revision with `git arc create -d`, then in the webui, limit visibility to subscribers only, then public the review. This is not perfect but I don't think there's a better way to handle it, short of emailing patches around.
Author
Member

@kib wrote in #30 (comment):

Could there be more than one mapping for the channel? If yes, you cannot use a flag to track it.

Each FD gets up to 2 channels, one recording and one for playback, depending on what's supported and how the FD was opened. So an mmap(2) call can map only one channel, no more mappings can happen.

One scenario I haven't investigated is: if for whatever reason, the application calls mmap(2) more than once, without the equivalent munmap()s before, will the mmap(2) handler ignore subsequent calls, or is it up to sound(4) to ignore it, for example by failing if CHN_F_MMAP is already set?

@kib wrote in https://ron-dev.freebsd.org/FreeBSD/src/pulls/30#issuecomment-648: > Could there be more than one mapping for the channel? If yes, you cannot use a flag to track it. Each FD gets up to 2 channels, one recording and one for playback, depending on what's supported and how the FD was opened. So an mmap(2) call can map only one channel, no more mappings can happen. One scenario I haven't investigated is: if for whatever reason, the application calls mmap(2) more than once, without the equivalent munmap()s before, will the mmap(2) handler ignore subsequent calls, or is it up to sound(4) to ignore it, for example by failing if `CHN_F_MMAP` is already set?
Member

For each mmap(2) call from userspace, there is a corresponding call to d_mmap_single() at the driver level.

For each mmap(2) call from userspace, there is a corresponding call to d_mmap_single() at the driver level.
Author
Member

There is no problem with multiple mappings, since all mappings happen inside the same channel buffer anyway. We don't need to do anything more.

There is no problem with multiple mappings, since all mappings happen inside the same channel buffer anyway. We don't need to do anything more.
christos force-pushed christos/mmap from e610965bdf
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to b3d631dd4e
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-12 06:24:17 +00:00
Compare
Author
Member

@markj Rebased to include the latest mmap patches. Do you have any comment, particularly for "sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()"?

@markj Rebased to include the latest mmap patches. Do you have any comment, particularly for "sound: Handle CHN_F_MMAP_INVALID after cdev_pager_allocate()"?
Author
Member

Bump.

Bump.
christos force-pushed christos/mmap from b3d631dd4e
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to e6eaf128f6
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-15 14:53:43 +00:00
Compare
@ -2009,0 +1986,4 @@
* PROT_WRITE|PROT_READ together select the output buffer.
*/
c = ((nprot & PROT_WRITE) != 0) ? priv->wrch : priv->rdch;
if (c == NULL)
Member

Missing PCM_GIANT_EXIT in the return path.

Missing PCM_GIANT_EXIT in the return path.
christos marked this conversation as resolved
@ -2035,0 +2011,4 @@
if (c->flags & CHN_F_MMAP_INVALID) {
err = EINVAL;
c->flags &= ~CHN_F_MMAP;
free(handle, M_DEVBUF);
Member

I believe you need to free the object as well, i.e., vm_object_deallocate(*object). Please check this.

I believe there is no risk of the buffer size changing, the CHN_F_MMAP flag should block that.

I believe you need to free the object as well, i.e., `vm_object_deallocate(*object)`. Please check this. I believe there is no risk of the buffer size changing, the CHN_F_MMAP flag should block that.
Author
Member

vm_object_deallocate() causes a double-free panic, just free(handle) is enough.

`vm_object_deallocate()` causes a double-free panic, just `free(handle)` is enough.
Member

I am skeptical. Where did you call vm_object_deallocate()? How did you trigger the race, and where did the kernel panic?

I am skeptical. Where did you call vm_object_deallocate()? How did you trigger the race, and where did the kernel panic?
Author
Member

It panicked when it was put both before and after the free().

Before free():

sys/sound/mmap:mmap_buffer_lifetime  ->  panic: Duplicate free of 0xfffff800031d5030 from zone 0xfffffe000ca04c00(malloc-16) slab 0xfffff800031d5fa8(3)
cpuid = 7
time = 1781979455
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x36/frame 0xfffffe008db5c920
vpanic() at vpanic+0x13f/frame 0xfffffe008db5ca50
panic() at panic+0x43/frame 0xfffffe008db5cab0
uma_dbg_free() at uma_dbg_free+0x105/frame 0xfffffe008db5cad0
uma_zfree_arg() at uma_zfree_arg+0x95/frame 0xfffffe008db5cb20
free() at free+0xb4/frame 0xfffffe008db5cb60
dsp_mmap_single() at dsp_mmap_single+0x2ff/frame 0xfffffe008db5cbd0
vm_mmap_cdev() at vm_mmap_cdev+0x66/frame 0xfffffe008db5cc20
devfs_mmap_f() at devfs_mmap_f+0x135/frame 0xfffffe008db5ccb0
kern_mmap() at kern_mmap+0x950/frame 0xfffffe008db5cda0
sys_mmap() at sys_mmap+0x4d/frame 0xfffffe008db5cdf0
amd64_syscall() at amd64_syscall+0x180/frame 0xfffffe008db5cf30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe008db5cf30
--- syscall (477, FreeBSD ELF64, mmap), rip = 0x27800fab702a, rsp = 0x27800c7cdcc8, rbp = 0x27800c7cdd10 ---
KDB: enter: panic
[ thread pid 9725 tid 100327 ]
Stopped at      kdb_enter+0x33: movq    $0,0x15ed172(%rip)
db>

After free():

Fatal trap 9: general protection fault while in kernel mode
cpuid = 7; apic id = 07
instruction pointer	= 0x20:0xffffffff80b2a7dd
stack pointer	        = 0x28:0xfffffe008da49aa0
frame pointer	        = 0x28:0xfffffe008da49ab0
processor eflags	= interrupt enabled, resume, IOPL = 0
current thread		= 3368/100236 (mmap/mmap)
rdi: ffffffff81d88018 rsi: 0000000000000008 rdx: 0000000000000000
rcx: 0000000000010000  r8: fffff8000492d000  r9: 000000000000002d
rax: fffff8000492d000 rbx: deadc0dedeadc0de rbp: fffffe008da49ab0
r10: ffffffff8125b121 r11: 0000000000000008 r12: fffffe008da49cc8
r13: fffff8000161b400 r14: fffff801790ce018 r15: fffff801790ce080
panic: general protection fault
cpuid = 7
time = 1781979519
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x36/frame 0xfffffe008da49820
vpanic() at vpanic+0x13f/frame 0xfffffe008da49950
panic() at panic+0x43/frame 0xfffffe008da499b0
trap_fatal() at trap_fatal+0x6f/frame 0xfffffe008da499d0
calltrap() at calltrap+0x8/frame 0xfffffe008da499d0
--- trap 0x9, rip = 0xffffffff80b2a7dd, rsp = 0xfffffe008da49aa0, rbp = 0xfffffe008da49ab0 ---
dev_rel() at dev_rel+0x3d/frame 0xfffffe008da49ab0
dsp_dev_pager_dtor() at dsp_dev_pager_dtor+0x1a/frame 0xfffffe008da49ad0
dev_pager_dealloc() at dev_pager_dealloc+0x33/frame 0xfffffe008da49af0
vm_object_terminate() at vm_object_terminate+0x16d/frame 0xfffffe008da49b30
vm_object_deallocate() at vm_object_deallocate+0x28c/frame 0xfffffe008da49b60
dsp_mmap_single() at dsp_mmap_single+0x2ff/frame 0xfffffe008da49bd0
vm_mmap_cdev() at vm_mmap_cdev+0x66/frame 0xfffffe008da49c20
devfs_mmap_f() at devfs_mmap_f+0x135/frame 0xfffffe008da49cb0
kern_mmap() at kern_mmap+0x950/frame 0xfffffe008da49da0
sys_mmap() at sys_mmap+0x4d/frame 0xfffffe008da49df0
amd64_syscall() at amd64_syscall+0x180/frame 0xfffffe008da49f30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe008da49f30
--- syscall (477, FreeBSD ELF64, mmap), rip = 0x6299884302a, rsp = 0x62994fea3a8, rbp = 0x62994fea3f0 ---
KDB: enter: panic
[ thread pid 3368 tid 100236 ]
Stopped at      kdb_enter+0x33: movq    $0,0x15ed172(%rip)
db>
It panicked when it was put both before and after the `free()`. Before `free()`: ``` sys/sound/mmap:mmap_buffer_lifetime -> panic: Duplicate free of 0xfffff800031d5030 from zone 0xfffffe000ca04c00(malloc-16) slab 0xfffff800031d5fa8(3) cpuid = 7 time = 1781979455 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x36/frame 0xfffffe008db5c920 vpanic() at vpanic+0x13f/frame 0xfffffe008db5ca50 panic() at panic+0x43/frame 0xfffffe008db5cab0 uma_dbg_free() at uma_dbg_free+0x105/frame 0xfffffe008db5cad0 uma_zfree_arg() at uma_zfree_arg+0x95/frame 0xfffffe008db5cb20 free() at free+0xb4/frame 0xfffffe008db5cb60 dsp_mmap_single() at dsp_mmap_single+0x2ff/frame 0xfffffe008db5cbd0 vm_mmap_cdev() at vm_mmap_cdev+0x66/frame 0xfffffe008db5cc20 devfs_mmap_f() at devfs_mmap_f+0x135/frame 0xfffffe008db5ccb0 kern_mmap() at kern_mmap+0x950/frame 0xfffffe008db5cda0 sys_mmap() at sys_mmap+0x4d/frame 0xfffffe008db5cdf0 amd64_syscall() at amd64_syscall+0x180/frame 0xfffffe008db5cf30 fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe008db5cf30 --- syscall (477, FreeBSD ELF64, mmap), rip = 0x27800fab702a, rsp = 0x27800c7cdcc8, rbp = 0x27800c7cdd10 --- KDB: enter: panic [ thread pid 9725 tid 100327 ] Stopped at kdb_enter+0x33: movq $0,0x15ed172(%rip) db> ``` After `free()`: ``` Fatal trap 9: general protection fault while in kernel mode cpuid = 7; apic id = 07 instruction pointer = 0x20:0xffffffff80b2a7dd stack pointer = 0x28:0xfffffe008da49aa0 frame pointer = 0x28:0xfffffe008da49ab0 processor eflags = interrupt enabled, resume, IOPL = 0 current thread = 3368/100236 (mmap/mmap) rdi: ffffffff81d88018 rsi: 0000000000000008 rdx: 0000000000000000 rcx: 0000000000010000 r8: fffff8000492d000 r9: 000000000000002d rax: fffff8000492d000 rbx: deadc0dedeadc0de rbp: fffffe008da49ab0 r10: ffffffff8125b121 r11: 0000000000000008 r12: fffffe008da49cc8 r13: fffff8000161b400 r14: fffff801790ce018 r15: fffff801790ce080 panic: general protection fault cpuid = 7 time = 1781979519 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x36/frame 0xfffffe008da49820 vpanic() at vpanic+0x13f/frame 0xfffffe008da49950 panic() at panic+0x43/frame 0xfffffe008da499b0 trap_fatal() at trap_fatal+0x6f/frame 0xfffffe008da499d0 calltrap() at calltrap+0x8/frame 0xfffffe008da499d0 --- trap 0x9, rip = 0xffffffff80b2a7dd, rsp = 0xfffffe008da49aa0, rbp = 0xfffffe008da49ab0 --- dev_rel() at dev_rel+0x3d/frame 0xfffffe008da49ab0 dsp_dev_pager_dtor() at dsp_dev_pager_dtor+0x1a/frame 0xfffffe008da49ad0 dev_pager_dealloc() at dev_pager_dealloc+0x33/frame 0xfffffe008da49af0 vm_object_terminate() at vm_object_terminate+0x16d/frame 0xfffffe008da49b30 vm_object_deallocate() at vm_object_deallocate+0x28c/frame 0xfffffe008da49b60 dsp_mmap_single() at dsp_mmap_single+0x2ff/frame 0xfffffe008da49bd0 vm_mmap_cdev() at vm_mmap_cdev+0x66/frame 0xfffffe008da49c20 devfs_mmap_f() at devfs_mmap_f+0x135/frame 0xfffffe008da49cb0 kern_mmap() at kern_mmap+0x950/frame 0xfffffe008da49da0 sys_mmap() at sys_mmap+0x4d/frame 0xfffffe008da49df0 amd64_syscall() at amd64_syscall+0x180/frame 0xfffffe008da49f30 fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe008da49f30 --- syscall (477, FreeBSD ELF64, mmap), rip = 0x6299884302a, rsp = 0x62994fea3a8, rbp = 0x62994fea3f0 --- KDB: enter: panic [ thread pid 3368 tid 100236 ] Stopped at kdb_enter+0x33: movq $0,0x15ed172(%rip) db> ```
Member

Eh, so that's because dsp_dev_pager_dtor() is running. You need to remove the free(handle), not the vm_object_deallocate().

Eh, so that's because dsp_dev_pager_dtor() is running. You need to remove the free(handle), not the vm_object_deallocate().
christos marked this conversation as resolved
christos force-pushed christos/mmap from e6eaf128f6
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to e0794c09a8
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-20 14:56:19 +00:00
Compare
christos force-pushed christos/mmap from e0794c09a8
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to 61fe5d1299
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-20 15:23:27 +00:00
Compare
@ -2035,0 +2013,4 @@
if (c->flags & CHN_F_MMAP_INVALID) {
err = EINVAL;
c->flags &= ~CHN_F_MMAP;
vm_object_deallocate(*object);
Member

I believe it is not safe to deallocate the object while holding the channel lock, vm_object_deallocate() may sleep in general.

I believe it is not safe to deallocate the object while holding the channel lock, vm_object_deallocate() may sleep in general.
christos marked this conversation as resolved
christos force-pushed christos/mmap from 61fe5d1299
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to 646c27f175
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-20 17:09:45 +00:00
Compare
markj approved these changes 2026-06-20 18:50:42 +00:00
christos force-pushed christos/mmap from 646c27f175
Some checks failed
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
to 730eaf4664
Some checks failed
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (push) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (push) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (push) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (push) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (push) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (push) Has been cancelled
Checklist / commit (pull_request_target) Has been cancelled
Cross-build Kernel / amd64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-22.04 (clang-15) (pull_request) Has been cancelled
Cross-build Kernel / amd64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 ubuntu-24.04 (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / amd64 macos-latest (clang-18) (pull_request) Has been cancelled
Cross-build Kernel / aarch64 macos-latest (clang-18) (pull_request) Has been cancelled
Style Checker / Style Checker (pull_request) Has been cancelled
2026-06-20 19:05:02 +00:00
Compare
christos manually merged commit 730eaf4664 into main 2026-06-20 19:05:53 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
FreeBSD/src!30
No description provided.