kexec_elf: remove parsing of section headers
authorSven Schnelle <svens@stackframe.org>
Fri, 23 Aug 2019 19:49:15 +0000 (21:49 +0200)
committerHelge Deller <deller@gmx.de>
Fri, 6 Sep 2019 21:58:43 +0000 (23:58 +0200)
We're not using them, so we can drop the parsing.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Helge Deller <deller@gmx.de>
include/linux/kexec.h
kernel/kexec_elf.c

index da2a6b1d69e71e1c9cc4df9639e8ec33756062a7..f0b809258ed3c686f96e6cbf4e53859bc13584d6 100644 (file)
@@ -226,7 +226,6 @@ struct kexec_elf_info {
 
        const struct elfhdr *ehdr;
        const struct elf_phdr *proghdrs;
-       struct elf_shdr *sechdrs;
 };
 
 int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
index 34376fbc55beee1e595c592edcead665bda3784e..137037603117ffdec37639e8d87bba17106d256c 100644 (file)
@@ -257,134 +257,6 @@ static int elf_read_phdrs(const char *buf, size_t len,
        return 0;
 }
 
-/**
- * elf_is_shdr_sane - check that it is safe to use the section header
- * @buf_len:   size of the buffer in which the ELF file is loaded.
- */
-static bool elf_is_shdr_sane(const struct elf_shdr *shdr, size_t buf_len)
-{
-       bool size_ok;
-
-       /* SHT_NULL headers have undefined values, so we can't check them. */
-       if (shdr->sh_type == SHT_NULL)
-               return true;
-
-       /* Now verify sh_entsize */
-       switch (shdr->sh_type) {
-       case SHT_SYMTAB:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Sym);
-               break;
-       case SHT_RELA:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Rela);
-               break;
-       case SHT_DYNAMIC:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Dyn);
-               break;
-       case SHT_REL:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Rel);
-               break;
-       case SHT_NOTE:
-       case SHT_PROGBITS:
-       case SHT_HASH:
-       case SHT_NOBITS:
-       default:
-               /*
-                * This is a section whose entsize requirements
-                * I don't care about.  If I don't know about
-                * the section I can't care about it's entsize
-                * requirements.
-                */
-               size_ok = true;
-               break;
-       }
-
-       if (!size_ok) {
-               pr_debug("ELF section with wrong entry size.\n");
-               return false;
-       } else if (shdr->sh_addr + shdr->sh_size < shdr->sh_addr) {
-               pr_debug("ELF section address wraps around.\n");
-               return false;
-       }
-
-       if (shdr->sh_type != SHT_NOBITS) {
-               if (shdr->sh_offset + shdr->sh_size < shdr->sh_offset) {
-                       pr_debug("ELF section location wraps around.\n");
-                       return false;
-               } else if (shdr->sh_offset + shdr->sh_size > buf_len) {
-                       pr_debug("ELF section not in file.\n");
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-static int elf_read_shdr(const char *buf, size_t len,
-                        struct kexec_elf_info *elf_info,
-                        int idx)
-{
-       struct elf_shdr *shdr = &elf_info->sechdrs[idx];
-       const struct elfhdr *ehdr = elf_info->ehdr;
-       const char *sbuf;
-       struct elf_shdr *buf_shdr;
-
-       sbuf = buf + ehdr->e_shoff + idx * sizeof(*buf_shdr);
-       buf_shdr = (struct elf_shdr *) sbuf;
-
-       shdr->sh_name      = elf32_to_cpu(ehdr, buf_shdr->sh_name);
-       shdr->sh_type      = elf32_to_cpu(ehdr, buf_shdr->sh_type);
-       shdr->sh_addr      = elf_addr_to_cpu(ehdr, buf_shdr->sh_addr);
-       shdr->sh_offset    = elf_addr_to_cpu(ehdr, buf_shdr->sh_offset);
-       shdr->sh_link      = elf32_to_cpu(ehdr, buf_shdr->sh_link);
-       shdr->sh_info      = elf32_to_cpu(ehdr, buf_shdr->sh_info);
-
-       /*
-        * The following fields have a type equivalent to Elf_Addr
-        * both in 32 bit and 64 bit ELF.
-        */
-       shdr->sh_flags     = elf_addr_to_cpu(ehdr, buf_shdr->sh_flags);
-       shdr->sh_size      = elf_addr_to_cpu(ehdr, buf_shdr->sh_size);
-       shdr->sh_addralign = elf_addr_to_cpu(ehdr, buf_shdr->sh_addralign);
-       shdr->sh_entsize   = elf_addr_to_cpu(ehdr, buf_shdr->sh_entsize);
-
-       return elf_is_shdr_sane(shdr, len) ? 0 : -ENOEXEC;
-}
-
-/**
- * elf_read_shdrs - read the section headers from the buffer
- *
- * This function assumes that the section header table was checked for sanity.
- * Use elf_is_ehdr_sane() if it wasn't.
- */
-static int elf_read_shdrs(const char *buf, size_t len,
-                         struct kexec_elf_info *elf_info)
-{
-       size_t shdr_size, i;
-
-       /*
-        * e_shnum is at most 65536 so calculating
-        * the size of the section header cannot overflow.
-        */
-       shdr_size = sizeof(struct elf_shdr) * elf_info->ehdr->e_shnum;
-
-       elf_info->sechdrs = kzalloc(shdr_size, GFP_KERNEL);
-       if (!elf_info->sechdrs)
-               return -ENOMEM;
-
-       for (i = 0; i < elf_info->ehdr->e_shnum; i++) {
-               int ret;
-
-               ret = elf_read_shdr(buf, len, elf_info, i);
-               if (ret) {
-                       kfree(elf_info->sechdrs);
-                       elf_info->sechdrs = NULL;
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
 /**
  * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
  * @buf:       Buffer to read ELF file from.
@@ -417,14 +289,6 @@ static int elf_read_from_buffer(const char *buf, size_t len,
                if (ret)
                        return ret;
        }
-       if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
-               ret = elf_read_shdrs(buf, len, elf_info);
-               if (ret) {
-                       kfree(elf_info->proghdrs);
-                       return ret;
-               }
-       }
-
        return 0;
 }
 
@@ -434,7 +298,6 @@ static int elf_read_from_buffer(const char *buf, size_t len,
 void kexec_free_elf_info(struct kexec_elf_info *elf_info)
 {
        kfree(elf_info->proghdrs);
-       kfree(elf_info->sechdrs);
        memset(elf_info, 0, sizeof(*elf_info));
 }
 /**