mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-30 08:04:13 +08:00
kexec_elf: remove parsing of section headers
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>
This commit is contained in:
parent
d34e0ad3ea
commit
5f71d97720
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user