lkml.org 
[lkml]   [2016]   [Jul]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] x86/vdso: Error out if the vDSO isn't a valid DSO
Date
Some distros has been playing with toolchain changes that can affect
the type of ELF objects built. Occasionally, this goes wrong and
the vDSO ends up not being a DSO at all. This causes the kernel to
end up broken in a surprisingly subtle way -- glibc apparently
silently ignores a vDSO that isn't a DSO, so everything works,
albeit slowly, until users try a different libc implementation.

Make the kernel build process a bit more robust: fail outright if
the vDSO isn't ET_DYN or is missing its PT_DYNAMIC segment. I've
never seen this in an unmodified kernel.

See https://github.com/docker/docker/issues/23378

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
arch/x86/entry/vdso/vdso2c.h | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h
index 63a03bb91497..4f741192846d 100644
--- a/arch/x86/entry/vdso/vdso2c.h
+++ b/arch/x86/entry/vdso/vdso2c.h
@@ -22,6 +22,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,

ELF(Phdr) *pt = (ELF(Phdr) *)(raw_addr + GET_LE(&hdr->e_phoff));

+ if (hdr->e_type != ET_DYN)
+ fail("input is not a shared object\n");
+
/* Walk the segment table. */
for (i = 0; i < GET_LE(&hdr->e_phnum); i++) {
if (GET_LE(&pt[i].p_type) == PT_LOAD) {
@@ -49,6 +52,9 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
if (stripped_len < load_size)
fail("stripped input is too short\n");

+ if (!dyn)
+ fail("input has no PT_DYNAMIC section -- your toolchain is buggy\n");
+
/* Walk the dynamic table */
for (i = 0; dyn + i < dyn_end &&
GET_LE(&dyn[i].d_tag) != DT_NULL; i++) {
--
2.7.4
\
 
 \ /
  Last update: 2016-07-19 00:21    [W:0.040 / U:0.312 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site