binfmt_elf: Use elf_load() for library
authorKees Cook <keescook@chromium.org>
Fri, 29 Sep 2023 03:24:32 +0000 (20:24 -0700)
committerKees Cook <keescook@chromium.org>
Wed, 4 Oct 2023 02:48:43 +0000 (19:48 -0700)
While load_elf_library() is a libc5-ism, we can still replace most of
its contents with elf_load() as well, further simplifying the code.

Some historical context:
- libc4 was a.out and used uselib (a.out support has been removed)
- libc5 was ELF and used uselib (there may still be users)
- libc6 is ELF and has never used uselib

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
Suggested-by: Eric Biederman <ebiederm@xmission.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-4-keescook@chromium.org
Signed-off-by: Kees Cook <keescook@chromium.org>
fs/binfmt_elf.c

index db47cb8..f7012c1 100644 (file)
@@ -1306,7 +1306,6 @@ static int load_elf_library(struct file *file)
 {
        struct elf_phdr *elf_phdata;
        struct elf_phdr *eppnt;
-       unsigned long elf_bss, bss, len;
        int retval, error, i, j;
        struct elfhdr elf_ex;
 
@@ -1351,30 +1350,15 @@ static int load_elf_library(struct file *file)
                eppnt++;
 
        /* Now use mmap to map the library into memory. */
-       error = vm_mmap(file,
-                       ELF_PAGESTART(eppnt->p_vaddr),
-                       (eppnt->p_filesz +
-                        ELF_PAGEOFFSET(eppnt->p_vaddr)),
+       error = elf_load(file, ELF_PAGESTART(eppnt->p_vaddr),
+                       eppnt,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_FIXED_NOREPLACE | MAP_PRIVATE,
-                       (eppnt->p_offset -
-                        ELF_PAGEOFFSET(eppnt->p_vaddr)));
-       if (error != ELF_PAGESTART(eppnt->p_vaddr))
-               goto out_free_ph;
+                       0);
 
-       elf_bss = eppnt->p_vaddr + eppnt->p_filesz;
-       if (padzero(elf_bss)) {
-               error = -EFAULT;
+       if (error != ELF_PAGESTART(eppnt->p_vaddr))
                goto out_free_ph;
-       }
 
-       len = ELF_PAGEALIGN(eppnt->p_filesz + eppnt->p_vaddr);
-       bss = ELF_PAGEALIGN(eppnt->p_memsz + eppnt->p_vaddr);
-       if (bss > len) {
-               error = vm_brk(len, bss - len);
-               if (error)
-                       goto out_free_ph;
-       }
        error = 0;
 
 out_free_ph: