--- /dev/null
+From b582ef5c53040c5feef4c96a8f9585b6831e2441 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@imgtec.com>
+Date: Mon, 26 Oct 2015 15:48:19 +0000
+Subject: binfmt_elf: Don't clobber passed executable's file header
+
+From: Maciej W. Rozycki <macro@imgtec.com>
+
+commit b582ef5c53040c5feef4c96a8f9585b6831e2441 upstream.
+
+Do not clobber the buffer space passed from `search_binary_handler' and
+originally preloaded by `prepare_binprm' with the executable's file
+header by overwriting it with its interpreter's file header. Instead
+keep the buffer space intact and directly use the data structure locally
+allocated for the interpreter's file header, fixing a bug introduced in
+2.1.14 with loadable module support (linux-mips.org commit beb11695
+[Import of Linux/MIPS 2.1.14], predating kernel.org repo's history).
+Adjust the amount of data read from the interpreter's file accordingly.
+
+This was not an issue before loadable module support, because back then
+`load_elf_binary' was executed only once for a given ELF executable,
+whether the function succeeded or failed.
+
+With loadable module support supported and enabled, upon a failure of
+`load_elf_binary' -- which may for example be caused by architecture
+code rejecting an executable due to a missing hardware feature requested
+in the file header -- a module load is attempted and then the function
+reexecuted by `search_binary_handler'. With the executable's file
+header replaced with its interpreter's file header the executable can
+then be erroneously accepted in this subsequent attempt.
+
+Signed-off-by: Maciej W. Rozycki <macro@imgtec.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/binfmt_elf.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -679,16 +679,16 @@ static int load_elf_binary(struct linux_
+ */
+ would_dump(bprm, interpreter);
+
+- retval = kernel_read(interpreter, 0, bprm->buf,
+- BINPRM_BUF_SIZE);
+- if (retval != BINPRM_BUF_SIZE) {
++ /* Get the exec headers */
++ retval = kernel_read(interpreter, 0,
++ (void *)&loc->interp_elf_ex,
++ sizeof(loc->interp_elf_ex));
++ if (retval != sizeof(loc->interp_elf_ex)) {
+ if (retval >= 0)
+ retval = -EIO;
+ goto out_free_dentry;
+ }
+
+- /* Get the exec headers */
+- loc->interp_elf_ex = *((struct elfhdr *)bprm->buf);
+ break;
+ }
+ elf_ppnt++;