Hi,

Running the attached C program results in this output:

    $ uname -mprsv
    OpenBSD 7.8 GENERIC.MP#1 amd64 amd64
    $ cc bug.c
    $ ./a.out
    0xffffffffffffffff (Cannot allocate memory)

By my reading of POSIX, this seems bad; the kernel is of course well within its 
rights to reject mappings past VM_MAXUSER_ADDRESS, but since MAP_FIXED is not 
used, I would expect the address hint to simply be ignored. AFAICT, every other 
POSIX-ish OS (other BSDs, Linux, macOS, etc) does exactly that.

For context, I ran into this on Zig's OpenBSD CI machine while fixing some bugs 
in our page allocator. We use address hints in mmap() to minimize address reuse 
with the goal of making use-after-frees easier to debug. For that to work 
reliably, we expect the kernel to just ignore any address hint it doesn't like 
and place the mapping somewhere actually sensible, after which we'll base our 
hints on that location.

For now, we're working around this by doing an extra mmap() without an address 
hint if we get ENOMEM on OpenBSD, but of course we'd prefer to not do that.

Regards,
Alex
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
int main() {
    long pgsz = sysconf(_SC_PAGE_SIZE);
    void *addr = mmap((void *)0x00007f7fffffc000, pgsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    printf("%p (%s)\n", addr, strerror(errno));
}

Reply via email to