On Sat, Sep 21, 2019 at 12:19:19PM -0400, Ryan Stone wrote: > If I try direct exec ld via rtld, I get the following failure: > > # /libexec/ld-elf.so.1 /usr/bin/ld > ld-elf.so.1: /usr/bin/ld: mmap of entire address space failed: Cannot > allocate memory > > Is there some sysctl limit I need to bump up to get around this? I > presume that the binary is just too large given that I can direct exec > smaller binaries like /bin/cat. No, this is not due to a limit, rather it is some unfortunate consequence of layout and default choices. Non-PIE binaries must be loaded at the fixed address. PIE binaries, which rtld pretends to be, are not. The loading address for PIE in non-ASLR mode is fixed per-arch, and it is not too far away from the default linking address of non-PIE. As result, it is possible for sufficiently large non-PIE binary to extend into already allocated range from rtld. We use MAP_FIXED | MAP_EXCL to avoid destroying existing mappings in linker, which fails when pre-allocating the space for whole future mappings of the object. I believe this is what happens in your case. I think that we finally should make the fixed PIE loading address a tunable. (patch was not tested) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 305e49c2e22..4678d7465b8 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c _at__at_ -135,6 +135,11 _at__at_ SYSCTL_INT(_kern_elf32, OID_AUTO, read_exec, CTLFLAG_RW, &i386_read_exec, 0, "enable execution from readable segments"); #endif +static u_long __elfN(pie_base) = ET_DYN_LOAD_ADDR; +SYSCTL_ULONG(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, pie_base, + CTLFLAG_RWTUN, &__elfN(pie_base), 0, + "PIE load base without randomization"); + SYSCTL_NODE(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO, aslr, CTLFLAG_RW, 0, ""); #define ASLR_NODE_OID __CONCAT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), _aslr) _at__at_ -1146,13 +1151,13 _at__at_ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) if (baddr == 0) { if ((sv->sv_flags & SV_ASLR) == 0 || (fctl0 & NT_FREEBSD_FCTL_ASLR_DISABLE) != 0) - et_dyn_addr = ET_DYN_LOAD_ADDR; + et_dyn_addr = __elfN(pie_base); else if ((__elfN(pie_aslr_enabled) && (imgp->proc->p_flag2 & P2_ASLR_DISABLE) == 0) || (imgp->proc->p_flag2 & P2_ASLR_ENABLE) != 0) et_dyn_addr = ET_DYN_ADDR_RAND; else - et_dyn_addr = ET_DYN_LOAD_ADDR; + et_dyn_addr = __elfN(pie_base); } }Received on Sat Sep 21 2019 - 14:49:10 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:21 UTC