Commit 5f71d977 authored by Sven Schnelle's avatar Sven Schnelle Committed by Helge Deller

kexec_elf: remove parsing of section headers

We're not using them, so we can drop the parsing.
Signed-off-by: default avatarSven Schnelle <svens@stackframe.org>
Reviewed-by: default avatarThiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent d34e0ad3
...@@ -226,7 +226,6 @@ struct kexec_elf_info { ...@@ -226,7 +226,6 @@ struct kexec_elf_info {
const struct elfhdr *ehdr; const struct elfhdr *ehdr;
const struct elf_phdr *proghdrs; const struct elf_phdr *proghdrs;
struct elf_shdr *sechdrs;
}; };
int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr, int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
......
...@@ -257,134 +257,6 @@ static int elf_read_phdrs(const char *buf, size_t len, ...@@ -257,134 +257,6 @@ static int elf_read_phdrs(const char *buf, size_t len,
return 0; 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 * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
* @buf: Buffer to read ELF file from. * @buf: Buffer to read ELF file from.
...@@ -417,14 +289,6 @@ static int elf_read_from_buffer(const char *buf, size_t len, ...@@ -417,14 +289,6 @@ static int elf_read_from_buffer(const char *buf, size_t len,
if (ret) if (ret)
return 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; return 0;
} }
...@@ -434,7 +298,6 @@ static int elf_read_from_buffer(const char *buf, size_t len, ...@@ -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) void kexec_free_elf_info(struct kexec_elf_info *elf_info)
{ {
kfree(elf_info->proghdrs); kfree(elf_info->proghdrs);
kfree(elf_info->sechdrs);
memset(elf_info, 0, sizeof(*elf_info)); memset(elf_info, 0, sizeof(*elf_info));
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment