Commit 658c0335 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds

fs/binfmt_elf.c: extract elf_read() function

ELF reads done by the kernel have very complicated error detection code
which better live in one place.

Link: http://lkml.kernel.org/r/20191005165215.GB26927@avx2Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 81696d5d
...@@ -404,6 +404,17 @@ static unsigned long total_mapping_size(const struct elf_phdr *cmds, int nr) ...@@ -404,6 +404,17 @@ static unsigned long total_mapping_size(const struct elf_phdr *cmds, int nr)
ELF_PAGESTART(cmds[first_idx].p_vaddr); ELF_PAGESTART(cmds[first_idx].p_vaddr);
} }
static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
{
ssize_t rv;
rv = kernel_read(file, buf, len, &pos);
if (unlikely(rv != len)) {
return (rv < 0) ? rv : -EIO;
}
return 0;
}
/** /**
* load_elf_phdrs() - load ELF program headers * load_elf_phdrs() - load ELF program headers
* @elf_ex: ELF header of the binary whose program headers should be loaded * @elf_ex: ELF header of the binary whose program headers should be loaded
...@@ -418,7 +429,6 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex, ...@@ -418,7 +429,6 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
{ {
struct elf_phdr *elf_phdata = NULL; struct elf_phdr *elf_phdata = NULL;
int retval, err = -1; int retval, err = -1;
loff_t pos = elf_ex->e_phoff;
unsigned int size; unsigned int size;
/* /*
...@@ -439,9 +449,9 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex, ...@@ -439,9 +449,9 @@ static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
goto out; goto out;
/* Read in the program headers */ /* Read in the program headers */
retval = kernel_read(elf_file, elf_phdata, size, &pos); retval = elf_read(elf_file, elf_phdata, size, elf_ex->e_phoff);
if (retval != size) { if (retval < 0) {
err = (retval < 0) ? retval : -EIO; err = retval;
goto out; goto out;
} }
...@@ -720,7 +730,6 @@ static int load_elf_binary(struct linux_binprm *bprm) ...@@ -720,7 +730,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
elf_ppnt = elf_phdata; elf_ppnt = elf_phdata;
for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
char *elf_interpreter; char *elf_interpreter;
loff_t pos;
if (elf_ppnt->p_type != PT_INTERP) if (elf_ppnt->p_type != PT_INTERP)
continue; continue;
...@@ -738,14 +747,10 @@ static int load_elf_binary(struct linux_binprm *bprm) ...@@ -738,14 +747,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
if (!elf_interpreter) if (!elf_interpreter)
goto out_free_ph; goto out_free_ph;
pos = elf_ppnt->p_offset; retval = elf_read(bprm->file, elf_interpreter, elf_ppnt->p_filesz,
retval = kernel_read(bprm->file, elf_interpreter, elf_ppnt->p_offset);
elf_ppnt->p_filesz, &pos); if (retval < 0)
if (retval != elf_ppnt->p_filesz) {
if (retval >= 0)
retval = -EIO;
goto out_free_interp; goto out_free_interp;
}
/* make sure path is NULL terminated */ /* make sure path is NULL terminated */
retval = -ENOEXEC; retval = -ENOEXEC;
if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
...@@ -764,14 +769,10 @@ static int load_elf_binary(struct linux_binprm *bprm) ...@@ -764,14 +769,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
would_dump(bprm, interpreter); would_dump(bprm, interpreter);
/* Get the exec headers */ /* Get the exec headers */
pos = 0; retval = elf_read(interpreter, &loc->interp_elf_ex,
retval = kernel_read(interpreter, &loc->interp_elf_ex, sizeof(loc->interp_elf_ex), 0);
sizeof(loc->interp_elf_ex), &pos); if (retval < 0)
if (retval != sizeof(loc->interp_elf_ex)) {
if (retval >= 0)
retval = -EIO;
goto out_free_dentry; goto out_free_dentry;
}
break; break;
...@@ -1174,11 +1175,10 @@ static int load_elf_library(struct file *file) ...@@ -1174,11 +1175,10 @@ static int load_elf_library(struct file *file)
unsigned long elf_bss, bss, len; unsigned long elf_bss, bss, len;
int retval, error, i, j; int retval, error, i, j;
struct elfhdr elf_ex; struct elfhdr elf_ex;
loff_t pos = 0;
error = -ENOEXEC; error = -ENOEXEC;
retval = kernel_read(file, &elf_ex, sizeof(elf_ex), &pos); retval = elf_read(file, &elf_ex, sizeof(elf_ex), 0);
if (retval != sizeof(elf_ex)) if (retval < 0)
goto out; goto out;
if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0) if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
...@@ -1203,9 +1203,8 @@ static int load_elf_library(struct file *file) ...@@ -1203,9 +1203,8 @@ static int load_elf_library(struct file *file)
eppnt = elf_phdata; eppnt = elf_phdata;
error = -ENOEXEC; error = -ENOEXEC;
pos = elf_ex.e_phoff; retval = elf_read(file, eppnt, j, elf_ex.e_phoff);
retval = kernel_read(file, eppnt, j, &pos); if (retval < 0)
if (retval != j)
goto out_free_ph; goto out_free_ph;
for (j = 0, i = 0; i<elf_ex.e_phnum; i++) for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment