Skip to content

Commit 7fd982f

Browse files
shuahkhmcgrof
authored andcommitted
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 <[email protected]> Signed-off-by: Shuah Khan <[email protected]> Signed-off-by: Luis Chamberlain <[email protected]>
1 parent d83d42d commit 7fd982f

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

kernel/module.c

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2971,14 +2971,29 @@ static int elf_validity_check(struct load_info *info)
29712971
Elf_Shdr *shdr, *strhdr;
29722972
int err;
29732973

2974-
if (info->len < sizeof(*(info->hdr)))
2975-
return -ENOEXEC;
2974+
if (info->len < sizeof(*(info->hdr))) {
2975+
pr_err("Invalid ELF header len %lu\n", info->len);
2976+
goto no_exec;
2977+
}
29762978

2977-
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
2978-
|| info->hdr->e_type != ET_REL
2979-
|| !elf_check_arch(info->hdr)
2980-
|| info->hdr->e_shentsize != sizeof(Elf_Shdr))
2981-
return -ENOEXEC;
2979+
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
2980+
pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
2981+
goto no_exec;
2982+
}
2983+
if (info->hdr->e_type != ET_REL) {
2984+
pr_err("Invalid ELF header type: %u != %u\n",
2985+
info->hdr->e_type, ET_REL);
2986+
goto no_exec;
2987+
}
2988+
if (!elf_check_arch(info->hdr)) {
2989+
pr_err("Invalid architecture in ELF header: %u\n",
2990+
info->hdr->e_machine);
2991+
goto no_exec;
2992+
}
2993+
if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) {
2994+
pr_err("Invalid ELF section header size\n");
2995+
goto no_exec;
2996+
}
29822997

29832998
/*
29842999
* e_shnum is 16 bits, and sizeof(Elf_Shdr) is
@@ -2987,40 +3002,53 @@ static int elf_validity_check(struct load_info *info)
29873002
*/
29883003
if (info->hdr->e_shoff >= info->len
29893004
|| (info->hdr->e_shnum * sizeof(Elf_Shdr) >
2990-
info->len - info->hdr->e_shoff))
2991-
return -ENOEXEC;
3005+
info->len - info->hdr->e_shoff)) {
3006+
pr_err("Invalid ELF section header overflow\n");
3007+
goto no_exec;
3008+
}
29923009

29933010
info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
29943011

29953012
/*
29963013
* Verify if the section name table index is valid.
29973014
*/
29983015
if (info->hdr->e_shstrndx == SHN_UNDEF
2999-
|| info->hdr->e_shstrndx >= info->hdr->e_shnum)
3000-
return -ENOEXEC;
3016+
|| info->hdr->e_shstrndx >= info->hdr->e_shnum) {
3017+
pr_err("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n",
3018+
info->hdr->e_shstrndx, info->hdr->e_shstrndx,
3019+
info->hdr->e_shnum);
3020+
goto no_exec;
3021+
}
30013022

30023023
strhdr = &info->sechdrs[info->hdr->e_shstrndx];
30033024
err = validate_section_offset(info, strhdr);
3004-
if (err < 0)
3025+
if (err < 0) {
3026+
pr_err("Invalid ELF section hdr(type %u)\n", strhdr->sh_type);
30053027
return err;
3028+
}
30063029

30073030
/*
30083031
* The section name table must be NUL-terminated, as required
30093032
* by the spec. This makes strcmp and pr_* calls that access
30103033
* strings in the section safe.
30113034
*/
30123035
info->secstrings = (void *)info->hdr + strhdr->sh_offset;
3013-
if (info->secstrings[strhdr->sh_size - 1] != '\0')
3014-
return -ENOEXEC;
3036+
if (info->secstrings[strhdr->sh_size - 1] != '\0') {
3037+
pr_err("ELF Spec violation: section name table isn't null terminated\n");
3038+
goto no_exec;
3039+
}
30153040

30163041
/*
30173042
* The code assumes that section 0 has a length of zero and
30183043
* an addr of zero, so check for it.
30193044
*/
30203045
if (info->sechdrs[0].sh_type != SHT_NULL
30213046
|| info->sechdrs[0].sh_size != 0
3022-
|| info->sechdrs[0].sh_addr != 0)
3023-
return -ENOEXEC;
3047+
|| info->sechdrs[0].sh_addr != 0) {
3048+
pr_err("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n",
3049+
info->sechdrs[0].sh_type);
3050+
goto no_exec;
3051+
}
30243052

30253053
for (i = 1; i < info->hdr->e_shnum; i++) {
30263054
shdr = &info->sechdrs[i];
@@ -3030,8 +3058,12 @@ static int elf_validity_check(struct load_info *info)
30303058
continue;
30313059
case SHT_SYMTAB:
30323060
if (shdr->sh_link == SHN_UNDEF
3033-
|| shdr->sh_link >= info->hdr->e_shnum)
3034-
return -ENOEXEC;
3061+
|| shdr->sh_link >= info->hdr->e_shnum) {
3062+
pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n",
3063+
shdr->sh_link, shdr->sh_link,
3064+
info->hdr->e_shnum);
3065+
goto no_exec;
3066+
}
30353067
fallthrough;
30363068
default:
30373069
err = validate_section_offset(info, shdr);
@@ -3053,6 +3085,9 @@ static int elf_validity_check(struct load_info *info)
30533085
}
30543086

30553087
return 0;
3088+
3089+
no_exec:
3090+
return -ENOEXEC;
30563091
}
30573092

30583093
#define COPY_CHUNK_SIZE (16*PAGE_SIZE)
@@ -3944,10 +3979,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
39443979
* sections.
39453980
*/
39463981
err = elf_validity_check(info);
3947-
if (err) {
3948-
pr_err("Module has invalid ELF structures\n");
3982+
if (err)
39493983
goto free_copy;
3950-
}
39513984

39523985
/*
39533986
* Everything checks out, so set up the section info

0 commit comments

Comments
 (0)