Closed ivmai closed 6 months ago
More of a CheriBSD issue than a cheribsd-ports issue, but I'll address it here.
TL;DR: in order to preserve provenance and intentionality we greatly restrict the use of MAP_FIXED. You can likely just define ac_cv_func_mmap_fixed_mapped=yes when running configure to skip this test (we probably didn't notice this because the cheribsd_ports system already does this).
The generated test tries something we've deliberately broken to avoid races and confusing runtime behavior. Specifically, the failing part of the code does approximately:
char *data2 = mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L);
munmap (data2, pagesize);
assert(data2 == mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L));
On CheriBSD 22.12 this will attempt to perform a MAP_FIXED mapping using a tagged capability to a location with no existing mapping (despite the comment in the test implying there is one). We reject this because in the general case another thread could trigger an mmap between the munmap
and the mmap
allocating this address space and then you've got an aliasing violation. On 22.11 one could work around this by changing the second mmap to:
assert(data2 == mmap ((void*)(uintptr_t)(ptraddr_t)data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L));
This strips the provenance from the pointer (it will be untagged and metadata will be cleared) and works because we allow mappings at arbitrary addresses so long as nothing is there as a compatibility measure.
On CheriBSD 23.11 this will fail for a slightly different reason. Because we have enabled heap temporal safety, after the munmap
, a quarantined vm entry remains until such a time as a relocation pass picks that one to revoke and invalidates all references. Thus the mapping fails because the code is attempting to make a fixed mapping (implicitly exclusive as above) on top of an existing mapping. Should revocation have happened between munmap
and mmap
we'd reject the mmap
without the cast above because the capability would have metadata, but not tag and we thing it's better to fail consistently in that case rather than sometimes succeeding depending on activity in other threads.
In the end, I think the test is testing something people might care about, but I doubt it affects most mmap
consumers or platforms so maybe it shouldn't be in the main test. (It's perhaps worth noting that the test doesn't test what the comments say it does due to the munmap
...)
Hopefully that longwinded writeup is somewhat informative.
This will be fixed in autoconf 2.72e (https://lists.gnu.org/r/autoconf/2023-12/msg00026.html). The workaround is to set ac_cv_func_mmap_fixed_mapped=yes
in the environment.
Thank you for the detailed explanation and the fix!
I confirm autoconf 2.72e solves the issue.
Not sure I'm reporting the issue in the proper space but I found that AC_FUNC_MMAP in configure does reports that mmap() is not working. Host: GCC farm cfarm240 (Morello CheriBSD/arm64) autoreconf: v2.71
How to reproduce:
configure.ac content:
type: autoreconf -i && ./configure
output (see "checking for working mmap..." line):