When trying to test Is it allowed to access memory that spans the zero border in x86? in user space on Linux, I wrote a 32-bit test program that tries to display low and high pages of a 32-bit virtual address space.
After that echo 0 | sudo tee /proc/sys/vm/mmap_min_addrI can display the page zero, but I donβt know why I canβt match -4096, i.e. (void*)0xfffff000, highest page. Why mmap2((void*)-4096)returns -ENOMEM?
strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffe08827c10 ) = 0
strace: [ Process PID=1407 runs in 32 bit mode. ]
....
mmap2(0xfffff000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0
Also, which check rejects it in linux/mm/mmap.c, and why is it designed that way? Is this part of ensuring that creating a one-on-one-object pointer does not wrap and violate pointer comparisons , since ISO C and C ++ allow you to create a pointer to one end of the past, but otherwise not outside of the objects .
I work under a 64-bit kernel (4.12.8-2-ARCH on Arch Linux), so the 32-bit user space has all 4GiB available. (Unlike 64-bit code in a 64-bit kernel or with a 32-bit kernel, where the separation of the user and the kernel 2: 2 or 3: 1 will make a high-level page the address of the kernel.)
( CRT libc, asm), , . CRT .
/proc/PID/maps. . , .
00000000-00001000 rw-p 00000000 00:00 0
VMA, maps, ββ ? ENOMEM linux/mm/mmapc., , , , - . -, , ?
( PAGE_ALIGN , , ).
, gcc -O3 -fno-pie -no-pie -m32 address-wrap.c:
#include <sys/mman.h>
int main(void) {
volatile unsigned *high =
mmap((void*)-4096L, 4096, PROT_READ | PROT_WRITE,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
volatile unsigned *zeropage =
mmap((void*)0, 4096, PROT_READ | PROT_WRITE,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
return (high == MAP_FAILED) ? 2 : *high;
}
( , deef (int*)-2, , mmap .)