We want to map the whole lower 4 GB of address space inaccessible to catch accidental pointer truncation. We can only do this when the executable (as well as the interpreter, if any) is compiled as PIC/PIE, since otherwise we would violate the ABI requirement. Fortunately most distributions have already switched to using PIE by default, so this should not be an issue. --- exec/exec.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/exec/exec.c b/exec/exec.c index 2e5fbfcd..4415fa50 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -1263,8 +1263,21 @@ do_exec (file_t file, /* Map page zero redzoned. */ { vm_address_t addr = 0; + vm_size_t size = vm_page_size; + +#ifdef __LP64__ + /* On 64-bit, map the entire lower 4 GB redzoned to catch pointer + truncation, but only if the program is fine with being loaded at an + arbitrary address -- otherwise we'd violate the assumption of the small + code model (-mcmodel=small, which is the default) that all symbols are + located in the lower 2 GB of the address space. */ + if (e.info.elf.anywhere && (interp.file == MACH_PORT_NULL + || interp.info.elf.anywhere)) + size = (vm_size_t) 1 << 32; +#endif + e.error = vm_map (newtask, - &addr, vm_page_size, 0, 0, MACH_PORT_NULL, 0, 1, + &addr, size, 0, 0, MACH_PORT_NULL, 0, 1, VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY); if (e.error) goto out; -- 2.41.0