]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
binfmt_elf: don't attempt to load FDPIC binaries
authorNicolas Pitre <nicolas.pitre@linaro.org>
Wed, 16 Aug 2017 20:05:13 +0000 (16:05 -0400)
committerNicolas Pitre <nicolas.pitre@linaro.org>
Sun, 10 Sep 2017 23:31:47 +0000 (19:31 -0400)
On platforms where both ELF and ELF-FDPIC variants are available, the
regular ELF loader will happily identify FDPIC binaries as proper ELF
and load them without the necessary FDPIC fixups, resulting in an
immediate user space crash. Let's prevent binflt_elf from loading those
binaries so binfmt_elf_fdpic has a chance to pick them up. For those
architectures that don't define elf_check_fdpic(), a default version
returning false is provided.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Acked-by: Mickael GUENE <mickael.guene@st.com>
Tested-by: Vincent Abriou <vincent.abriou@st.com>
Tested-by: Andras Szemzo <szemzo.andras@gmail.com>
fs/binfmt_elf.c

index 6466153f2bf099d357166192710167667abefa09..89536811d8f8a606331990495e2f6206404040c0 100644 (file)
 #define user_siginfo_t siginfo_t
 #endif
 
+/* That's for binfmt_elf_fdpic to deal with */
+#ifndef elf_check_fdpic
+#define elf_check_fdpic(ex) false
+#endif
+
 static int load_elf_binary(struct linux_binprm *bprm);
 static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
                                int, int, unsigned long);
@@ -541,7 +546,8 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
        if (interp_elf_ex->e_type != ET_EXEC &&
            interp_elf_ex->e_type != ET_DYN)
                goto out;
-       if (!elf_check_arch(interp_elf_ex))
+       if (!elf_check_arch(interp_elf_ex) ||
+           elf_check_fdpic(interp_elf_ex))
                goto out;
        if (!interpreter->f_op->mmap)
                goto out;
@@ -717,6 +723,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
                goto out;
        if (!elf_check_arch(&loc->elf_ex))
                goto out;
+       if (elf_check_fdpic(&loc->elf_ex))
+               goto out;
        if (!bprm->file->f_op->mmap)
                goto out;
 
@@ -816,7 +824,8 @@ static int load_elf_binary(struct linux_binprm *bprm)
                if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
                        goto out_free_dentry;
                /* Verify the interpreter has a valid arch */
-               if (!elf_check_arch(&loc->interp_elf_ex))
+               if (!elf_check_arch(&loc->interp_elf_ex) ||
+                   elf_check_fdpic(&loc->interp_elf_ex))
                        goto out_free_dentry;
 
                /* Load the interpreter program headers */
@@ -1188,6 +1197,8 @@ static int load_elf_library(struct file *file)
        if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
            !elf_check_arch(&elf_ex) || !file->f_op->mmap)
                goto out;
+       if (elf_check_fdpic(&elf_ex))
+               goto out;
 
        /* Now read in all of the header information */