Skip to content

Commit

Permalink
binfmt_elf: don't attempt to load FDPIC binaries
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Mickael GUENE <[email protected]>
Tested-by: Vincent Abriou <[email protected]>
Tested-by: Andras Szemzo <[email protected]>
  • Loading branch information
Nicolas Pitre committed Sep 10, 2017
1 parent 382e67a commit 4755200
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
#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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */

Expand Down

0 comments on commit 4755200

Please sign in to comment.