mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 13:41:51 +00:00
fs/binfmt_elf.c: free PT_INTERP filename ASAP
There is no reason for PT_INTERP filename to linger till the end of the whole loading process. Link: http://lkml.kernel.org/r/20190314204953.GD18143@avx2 Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Nikitas Angelinas <nikitas.angelinas@gmail.com> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Mukesh Ojha <mojha@codeaurora.org> [nikitas.angelinas@gmail.com: fix GPF when dereferencing invalid interpreter] Link: http://lkml.kernel.org/r/20190330140032.GA1527@vostro Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5cf4a36382
commit
cc338010a2
@ -687,7 +687,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
struct file *interpreter = NULL; /* to shut gcc up */
|
||||
unsigned long load_addr = 0, load_bias = 0;
|
||||
int load_addr_set = 0;
|
||||
char * elf_interpreter = NULL;
|
||||
unsigned long error;
|
||||
struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL;
|
||||
unsigned long elf_bss, elf_brk;
|
||||
@ -743,6 +742,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
|
||||
for (i = 0; i < loc->elf_ex.e_phnum; i++) {
|
||||
if (elf_ppnt->p_type == PT_INTERP) {
|
||||
char *elf_interpreter;
|
||||
loff_t pos;
|
||||
|
||||
/* This is the program interpreter used for
|
||||
@ -774,9 +774,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
goto out_free_interp;
|
||||
|
||||
interpreter = open_exec(elf_interpreter);
|
||||
kfree(elf_interpreter);
|
||||
retval = PTR_ERR(interpreter);
|
||||
if (IS_ERR(interpreter))
|
||||
goto out_free_interp;
|
||||
goto out_free_ph;
|
||||
|
||||
/*
|
||||
* If the binary is not readable then enforce
|
||||
@ -796,6 +797,10 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
out_free_interp:
|
||||
kfree(elf_interpreter);
|
||||
goto out_free_ph;
|
||||
}
|
||||
elf_ppnt++;
|
||||
}
|
||||
@ -820,7 +825,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
}
|
||||
|
||||
/* Some simple consistency checks for the interpreter */
|
||||
if (elf_interpreter) {
|
||||
if (interpreter) {
|
||||
retval = -ELIBBAD;
|
||||
/* Not an ELF interpreter */
|
||||
if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
|
||||
@ -977,7 +982,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
* independently randomized mmap region (0 load_bias
|
||||
* without MAP_FIXED).
|
||||
*/
|
||||
if (elf_interpreter) {
|
||||
if (interpreter) {
|
||||
load_bias = ELF_ET_DYN_BASE;
|
||||
if (current->flags & PF_RANDOMIZE)
|
||||
load_bias += arch_mmap_rnd();
|
||||
@ -1075,7 +1080,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
goto out_free_dentry;
|
||||
}
|
||||
|
||||
if (elf_interpreter) {
|
||||
if (interpreter) {
|
||||
unsigned long interp_map_addr = 0;
|
||||
|
||||
elf_entry = load_elf_interp(&loc->interp_elf_ex,
|
||||
@ -1099,7 +1104,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
|
||||
allow_write_access(interpreter);
|
||||
fput(interpreter);
|
||||
kfree(elf_interpreter);
|
||||
} else {
|
||||
elf_entry = loc->elf_ex.e_entry;
|
||||
if (BAD_ADDR(elf_entry)) {
|
||||
@ -1114,7 +1118,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
||||
set_binfmt(&elf_format);
|
||||
|
||||
#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
retval = arch_setup_additional_pages(bprm, !!elf_interpreter);
|
||||
retval = arch_setup_additional_pages(bprm, !!interpreter);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
|
||||
@ -1175,8 +1179,6 @@ out_free_dentry:
|
||||
allow_write_access(interpreter);
|
||||
if (interpreter)
|
||||
fput(interpreter);
|
||||
out_free_interp:
|
||||
kfree(elf_interpreter);
|
||||
out_free_ph:
|
||||
kfree(elf_phdata);
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user