treat null vdso base same as missing
authorBobby Bingham <koorogi@koorogi.info>
Tue, 26 Jul 2016 03:52:58 +0000 (22:52 -0500)
committerRich Felker <dalias@aerifal.cx>
Fri, 11 Nov 2016 17:58:27 +0000 (12:58 -0500)
On s390x, the kernel provides AT_SYSINFO_EHDR, but sets it to zero, if the
program being run does not have a program interpreter.  This causes
problems when running the dynamic linker directly.

ldso/dynlink.c
src/internal/vdso.c

index ad49cac28ccd12f8c1e937b4931a2bad1a7ddd00..c689084564e6e2e8bd67029a7ca69d10b5c252e9 100644 (file)
@@ -1550,7 +1550,7 @@ _Noreturn void __dls3(size_t *sp)
        }
 
        /* Attach to vdso, if provided by the kernel */
-       if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
+       if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR) && vdso_base) {
                Ehdr *ehdr = (void *)vdso_base;
                Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
                vdso.phnum = ehdr->e_phnum;
index a4862171e306d58082df8190410a6f8ce409438d..d46d32281e64943d0bae9a4be42dc64147538d40 100644 (file)
@@ -45,6 +45,7 @@ void *__vdsosym(const char *vername, const char *name)
        size_t i;
        for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
                if (!libc.auxv[i]) return 0;
+       if (!libc.auxv[i+1]) return 0;
        Ehdr *eh = (void *)libc.auxv[i+1];
        Phdr *ph = (void *)((char *)eh + eh->e_phoff);
        size_t *dynv=0, base=-1;