From 44c9aa49ea82d0884ba5b1fe0aa6638b2914de2a Mon Sep 17 00:00:00 2001 From: Brandon Bergren Date: Thu, 12 Dec 2019 17:40:32 +0000 Subject: [PATCH] rtld: do not try to mmap a zero-sized PT_LOAD When a PT_LOAD segment has a zero p_filesz, skip the data mmap, as mmapping zero bytes from a file is an error. A PT_LOAD with zero p_filesz is legal (but somewhat uncommon due to segment merging in modern linkers, as it is more efficient to merge .data and .bss by just extending p_memsz in the previous segment, assuming compatible page protection.) This was seen on ports/graphics/glew on a powerpc64 ELFv2 experimental build. Submitted by: Alfredo Dal'Ava Junior Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D22634 --- libexec/rtld-elf/map_object.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 61a18a46315..be95a953558 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -228,11 +228,12 @@ map_object(int fd, const char *path, const struct stat *sb) data_addr = mapbase + (data_vaddr - base_vaddr); data_prot = convert_prot(segs[i]->p_flags); data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; - if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, - data_flags | MAP_PREFAULT_READ, fd, data_offset) == (caddr_t) -1) { - _rtld_error("%s: mmap of data failed: %s", path, - rtld_strerror(errno)); - goto error1; + if (data_vlimit != data_vaddr && + mmap(data_addr, data_vlimit - data_vaddr, data_prot, + data_flags | MAP_PREFAULT_READ, fd, data_offset) == MAP_FAILED) { + _rtld_error("%s: mmap of data failed: %s", path, + rtld_strerror(errno)); + goto error1; } /* Do BSS setup */