mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-18 13:04:18 +00:00
module: change to print useful messages from elf_validity_check()
elf_validity_check() checks ELF headers for errors and ELF Spec. compliance and if any of them fail it returns -ENOEXEC from all of these error paths. Almost all of them don't print any messages. When elf_validity_check() returns an error, load_module() prints an error message without error code. It is hard to determine why the module ELF structure is invalid, even if load_module() prints the error code which is -ENOEXEC in all of these cases. Change to print useful error messages from elf_validity_check() to clearly say what went wrong and why the ELF validity checks failed. Remove the load_module() error message which is no longer needed. This patch includes changes to fix build warns on 32-bit platforms: warning: format '%llu' expects argument of type 'long long unsigned int', but argument 3 has type 'Elf32_Off' {aka 'unsigned int'} Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
This commit is contained in:
parent
d83d42d071
commit
7fd982f394
1 changed files with 54 additions and 21 deletions
|
@ -2971,14 +2971,29 @@ static int elf_validity_check(struct load_info *info)
|
|||
Elf_Shdr *shdr, *strhdr;
|
||||
int err;
|
||||
|
||||
if (info->len < sizeof(*(info->hdr)))
|
||||
return -ENOEXEC;
|
||||
if (info->len < sizeof(*(info->hdr))) {
|
||||
pr_err("Invalid ELF header len %lu\n", info->len);
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
|
||||
|| info->hdr->e_type != ET_REL
|
||||
|| !elf_check_arch(info->hdr)
|
||||
|| info->hdr->e_shentsize != sizeof(Elf_Shdr))
|
||||
return -ENOEXEC;
|
||||
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
||||
pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
|
||||
goto no_exec;
|
||||
}
|
||||
if (info->hdr->e_type != ET_REL) {
|
||||
pr_err("Invalid ELF header type: %u != %u\n",
|
||||
info->hdr->e_type, ET_REL);
|
||||
goto no_exec;
|
||||
}
|
||||
if (!elf_check_arch(info->hdr)) {
|
||||
pr_err("Invalid architecture in ELF header: %u\n",
|
||||
info->hdr->e_machine);
|
||||
goto no_exec;
|
||||
}
|
||||
if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) {
|
||||
pr_err("Invalid ELF section header size\n");
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
/*
|
||||
* e_shnum is 16 bits, and sizeof(Elf_Shdr) is
|
||||
|
@ -2987,8 +3002,10 @@ static int elf_validity_check(struct load_info *info)
|
|||
*/
|
||||
if (info->hdr->e_shoff >= info->len
|
||||
|| (info->hdr->e_shnum * sizeof(Elf_Shdr) >
|
||||
info->len - info->hdr->e_shoff))
|
||||
return -ENOEXEC;
|
||||
info->len - info->hdr->e_shoff)) {
|
||||
pr_err("Invalid ELF section header overflow\n");
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
|
||||
|
||||
|
@ -2996,13 +3013,19 @@ static int elf_validity_check(struct load_info *info)
|
|||
* Verify if the section name table index is valid.
|
||||
*/
|
||||
if (info->hdr->e_shstrndx == SHN_UNDEF
|
||||
|| info->hdr->e_shstrndx >= info->hdr->e_shnum)
|
||||
return -ENOEXEC;
|
||||
|| info->hdr->e_shstrndx >= info->hdr->e_shnum) {
|
||||
pr_err("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n",
|
||||
info->hdr->e_shstrndx, info->hdr->e_shstrndx,
|
||||
info->hdr->e_shnum);
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
strhdr = &info->sechdrs[info->hdr->e_shstrndx];
|
||||
err = validate_section_offset(info, strhdr);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
pr_err("Invalid ELF section hdr(type %u)\n", strhdr->sh_type);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The section name table must be NUL-terminated, as required
|
||||
|
@ -3010,8 +3033,10 @@ static int elf_validity_check(struct load_info *info)
|
|||
* strings in the section safe.
|
||||
*/
|
||||
info->secstrings = (void *)info->hdr + strhdr->sh_offset;
|
||||
if (info->secstrings[strhdr->sh_size - 1] != '\0')
|
||||
return -ENOEXEC;
|
||||
if (info->secstrings[strhdr->sh_size - 1] != '\0') {
|
||||
pr_err("ELF Spec violation: section name table isn't null terminated\n");
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
/*
|
||||
* The code assumes that section 0 has a length of zero and
|
||||
|
@ -3019,8 +3044,11 @@ static int elf_validity_check(struct load_info *info)
|
|||
*/
|
||||
if (info->sechdrs[0].sh_type != SHT_NULL
|
||||
|| info->sechdrs[0].sh_size != 0
|
||||
|| info->sechdrs[0].sh_addr != 0)
|
||||
return -ENOEXEC;
|
||||
|| info->sechdrs[0].sh_addr != 0) {
|
||||
pr_err("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n",
|
||||
info->sechdrs[0].sh_type);
|
||||
goto no_exec;
|
||||
}
|
||||
|
||||
for (i = 1; i < info->hdr->e_shnum; i++) {
|
||||
shdr = &info->sechdrs[i];
|
||||
|
@ -3030,8 +3058,12 @@ static int elf_validity_check(struct load_info *info)
|
|||
continue;
|
||||
case SHT_SYMTAB:
|
||||
if (shdr->sh_link == SHN_UNDEF
|
||||
|| shdr->sh_link >= info->hdr->e_shnum)
|
||||
return -ENOEXEC;
|
||||
|| shdr->sh_link >= info->hdr->e_shnum) {
|
||||
pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n",
|
||||
shdr->sh_link, shdr->sh_link,
|
||||
info->hdr->e_shnum);
|
||||
goto no_exec;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
err = validate_section_offset(info, shdr);
|
||||
|
@ -3053,6 +3085,9 @@ static int elf_validity_check(struct load_info *info)
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
no_exec:
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
#define COPY_CHUNK_SIZE (16*PAGE_SIZE)
|
||||
|
@ -3944,10 +3979,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||
* sections.
|
||||
*/
|
||||
err = elf_validity_check(info);
|
||||
if (err) {
|
||||
pr_err("Module has invalid ELF structures\n");
|
||||
if (err)
|
||||
goto free_copy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Everything checks out, so set up the section info
|
||||
|
|
Loading…
Add table
Reference in a new issue