fix missing bss handling in FDPIC ELF loader
authorRich Felker <dalias@aerifal.cx>
Thu, 29 Oct 2015 01:45:31 +0000 (21:45 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 29 Oct 2015 01:45:31 +0000 (21:45 -0400)
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.

src/ldso/dynlink.c

index 642ecc30035f0fedd51a3e827e93d2f313b119c6..a6484dd5a9b7b1347fefb53356eab701ca759b6a 100644 (file)
@@ -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;