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 <ebiederm@xmission.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: linux-fsdevel@vger.kernel.org Cc: linux-mm@kvack.org Reported-by: Pedro Falcato <pedro.falcato@gmail.com> Closes: https://lore.kernel.org/lkml/20221106021657.1145519-1-pedro.falcato@gmail.com/ Tested-by: Pedro Falcato <pedro.falcato@gmail.com> Signed-off-by: Sebastian Ott <sebott@redhat.com> Link: https://lore.kernel.org/r/20230929032435.2391507-3-keescook@chromium.org Signed-off-by: Kees Cook <keescook@chromium.org>
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)