diff options
author | Rich Felker <dalias@aerifal.cx> | 2015-10-28 21:45:31 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2015-10-28 21:45:31 -0400 |
commit | fead7e3fc04729b4cc8a5feec4a172b389395212 (patch) | |
tree | 8038978002444ed95bc85c7bdbec97ca8306c591 /src/ldso | |
parent | 6eada2edb302ff061be8546b23c9cb836621d122 (diff) | |
download | musl-fead7e3fc04729b4cc8a5feec4a172b389395212.tar.gz musl-fead7e3fc04729b4cc8a5feec4a172b389395212.tar.xz musl-fead7e3fc04729b4cc8a5feec4a172b389395212.zip |
fix missing bss handling in FDPIC ELF loader
when a library being loaded has bss (i.e. data segment with p_memsz>p_filesz), this region needs to be zeroed with a combination of memset and/or mmap. the regular ELF loader always did this but the FDPIC code path omitted it, leading to objects in bss having uninitialized/junk contents.
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/dynlink.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 642ecc30..a6484dd5 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -604,6 +604,19 @@ static void *map_library(int fd, struct dso *dso) dso->loadmap->segs[i].p_vaddr = ph->p_vaddr; dso->loadmap->segs[i].p_memsz = ph->p_memsz; i++; + if (prot & PROT_WRITE) { + size_t brk = (ph->p_vaddr & PAGE_SIZE-1) + + ph->p_filesz; + size_t pgbrk = brk + PAGE_SIZE-1 & -PAGE_SIZE; + size_t pgend = brk + ph->p_memsz - ph->p_filesz + + PAGE_SIZE-1 & -PAGE_SIZE; + if (pgend > pgbrk && mmap_fixed(map+pgbrk, + pgend-pgbrk, prot, + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, + -1, off_start) == MAP_FAILED) + goto error; + memset(map + brk, 0, pgbrk-brk); + } } map = (void *)dso->loadmap->segs[0].addr; map_len = 0; |