Skip to content

Commit 8b04d32

Browse files
committed
binfmt_elf: Use elf_load() for interpreter
Handle arbitrary memsz>filesz in interpreter ELF segments, instead of only supporting it in the last segment (which is expected to be the BSS). Cc: Eric Biederman <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Christian Brauner <[email protected]> Cc: [email protected] Cc: [email protected] Reported-by: Pedro Falcato <[email protected]> Closes: https://lore.kernel.org/lkml/[email protected]/ Tested-by: Pedro Falcato <[email protected]> Signed-off-by: Sebastian Ott <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Kees Cook <[email protected]>
1 parent 8ed2ef2 commit 8b04d32

File tree

1 file changed

+1
-45
lines changed

1 file changed

+1
-45
lines changed

fs/binfmt_elf.c

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
622622
struct elf_phdr *eppnt;
623623
unsigned long load_addr = 0;
624624
int load_addr_set = 0;
625-
unsigned long last_bss = 0, elf_bss = 0;
626-
int bss_prot = 0;
627625
unsigned long error = ~0UL;
628626
unsigned long total_size;
629627
int i;
@@ -660,7 +658,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
660658
else if (no_base && interp_elf_ex->e_type == ET_DYN)
661659
load_addr = -vaddr;
662660

663-
map_addr = elf_map(interpreter, load_addr + vaddr,
661+
map_addr = elf_load(interpreter, load_addr + vaddr,
664662
eppnt, elf_prot, elf_type, total_size);
665663
total_size = 0;
666664
error = map_addr;
@@ -686,51 +684,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
686684
error = -ENOMEM;
687685
goto out;
688686
}
689-
690-
/*
691-
* Find the end of the file mapping for this phdr, and
692-
* keep track of the largest address we see for this.
693-
*/
694-
k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
695-
if (k > elf_bss)
696-
elf_bss = k;
697-
698-
/*
699-
* Do the same thing for the memory mapping - between
700-
* elf_bss and last_bss is the bss section.
701-
*/
702-
k = load_addr + eppnt->p_vaddr + eppnt->p_memsz;
703-
if (k > last_bss) {
704-
last_bss = k;
705-
bss_prot = elf_prot;
706-
}
707687
}
708688
}
709689

710-
/*
711-
* Now fill out the bss section: first pad the last page from
712-
* the file up to the page boundary, and zero it from elf_bss
713-
* up to the end of the page.
714-
*/
715-
if (padzero(elf_bss)) {
716-
error = -EFAULT;
717-
goto out;
718-
}
719-
/*
720-
* Next, align both the file and mem bss up to the page size,
721-
* since this is where elf_bss was just zeroed up to, and where
722-
* last_bss will end after the vm_brk_flags() below.
723-
*/
724-
elf_bss = ELF_PAGEALIGN(elf_bss);
725-
last_bss = ELF_PAGEALIGN(last_bss);
726-
/* Finally, if there is still more bss to allocate, do it. */
727-
if (last_bss > elf_bss) {
728-
error = vm_brk_flags(elf_bss, last_bss - elf_bss,
729-
bss_prot & PROT_EXEC ? VM_EXEC : 0);
730-
if (error)
731-
goto out;
732-
}
733-
734690
error = load_addr;
735691
out:
736692
return error;

0 commit comments

Comments
 (0)