about summary refs log tree commit diff
path: root/src/ldso
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-10-28 21:45:31 -0400
committerRich Felker <dalias@aerifal.cx>2015-10-28 21:45:31 -0400
commitfead7e3fc04729b4cc8a5feec4a172b389395212 (patch)
tree8038978002444ed95bc85c7bdbec97ca8306c591 /src/ldso
parent6eada2edb302ff061be8546b23c9cb836621d122 (diff)
downloadmusl-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.c13
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;