Skip to content

Commit 67b7e1f

Browse files
committed
Merge tag 'modules-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux
Pull module updates from Luis Chamberlain: "As requested by Jessica I'm stepping in to help with modules maintenance. This is my first pull request to you. I've collected only two patches for modules for the 5.16-rc1 merge window. These patches are from Shuah Khan as she debugged some corner case error with modules. The error messages are improved for elf_validity_check(). While doing this work a corner case fix was spotted on validate_section_offset() due to a possible overflow bug on 64-bit. The impact of this fix is low given this just limits module section headers placed within the 32-bit boundary, and we obviously don't have insane module sizes. Even if a specially crafted module is constructed later checks would invalidate the module right away. I've let this sit through 0-day testing since October 15th with no issues found" * tag 'modules-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux: module: change to print useful messages from elf_validity_check() module: fix validate_section_offset() overflow bug on 64-bit
2 parents c107fb9 + 7fd982f commit 67b7e1f

File tree

1 file changed

+58
-21
lines changed

1 file changed

+58
-21
lines changed

kernel/module.c

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,7 +2942,11 @@ static int module_sig_check(struct load_info *info, int flags)
29422942

29432943
static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr)
29442944
{
2945+
#if defined(CONFIG_64BIT)
2946+
unsigned long long secend;
2947+
#else
29452948
unsigned long secend;
2949+
#endif
29462950

29472951
/*
29482952
* Check for both overflow and offset/size being
@@ -2967,14 +2971,29 @@ static int elf_validity_check(struct load_info *info)
29672971
Elf_Shdr *shdr, *strhdr;
29682972
int err;
29692973

2970-
if (info->len < sizeof(*(info->hdr)))
2971-
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+
}
29722978

2973-
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
2974-
|| info->hdr->e_type != ET_REL
2975-
|| !elf_check_arch(info->hdr)
2976-
|| info->hdr->e_shentsize != sizeof(Elf_Shdr))
2977-
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+
}
29782997

29792998
/*
29802999
* e_shnum is 16 bits, and sizeof(Elf_Shdr) is
@@ -2983,40 +3002,53 @@ static int elf_validity_check(struct load_info *info)
29833002
*/
29843003
if (info->hdr->e_shoff >= info->len
29853004
|| (info->hdr->e_shnum * sizeof(Elf_Shdr) >
2986-
info->len - info->hdr->e_shoff))
2987-
return -ENOEXEC;
3005+
info->len - info->hdr->e_shoff)) {
3006+
pr_err("Invalid ELF section header overflow\n");
3007+
goto no_exec;
3008+
}
29883009

29893010
info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
29903011

29913012
/*
29923013
* Verify if the section name table index is valid.
29933014
*/
29943015
if (info->hdr->e_shstrndx == SHN_UNDEF
2995-
|| info->hdr->e_shstrndx >= info->hdr->e_shnum)
2996-
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+
}
29973022

29983023
strhdr = &info->sechdrs[info->hdr->e_shstrndx];
29993024
err = validate_section_offset(info, strhdr);
3000-
if (err < 0)
3025+
if (err < 0) {
3026+
pr_err("Invalid ELF section hdr(type %u)\n", strhdr->sh_type);
30013027
return err;
3028+
}
30023029

30033030
/*
30043031
* The section name table must be NUL-terminated, as required
30053032
* by the spec. This makes strcmp and pr_* calls that access
30063033
* strings in the section safe.
30073034
*/
30083035
info->secstrings = (void *)info->hdr + strhdr->sh_offset;
3009-
if (info->secstrings[strhdr->sh_size - 1] != '\0')
3010-
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+
}
30113040

30123041
/*
30133042
* The code assumes that section 0 has a length of zero and
30143043
* an addr of zero, so check for it.
30153044
*/
30163045
if (info->sechdrs[0].sh_type != SHT_NULL
30173046
|| info->sechdrs[0].sh_size != 0
3018-
|| info->sechdrs[0].sh_addr != 0)
3019-
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+
}
30203052

30213053
for (i = 1; i < info->hdr->e_shnum; i++) {
30223054
shdr = &info->sechdrs[i];
@@ -3026,8 +3058,12 @@ static int elf_validity_check(struct load_info *info)
30263058
continue;
30273059
case SHT_SYMTAB:
30283060
if (shdr->sh_link == SHN_UNDEF
3029-
|| shdr->sh_link >= info->hdr->e_shnum)
3030-
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+
}
30313067
fallthrough;
30323068
default:
30333069
err = validate_section_offset(info, shdr);
@@ -3049,6 +3085,9 @@ static int elf_validity_check(struct load_info *info)
30493085
}
30503086

30513087
return 0;
3088+
3089+
no_exec:
3090+
return -ENOEXEC;
30523091
}
30533092

30543093
#define COPY_CHUNK_SIZE (16*PAGE_SIZE)
@@ -3940,10 +3979,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
39403979
* sections.
39413980
*/
39423981
err = elf_validity_check(info);
3943-
if (err) {
3944-
pr_err("Module has invalid ELF structures\n");
3982+
if (err)
39453983
goto free_copy;
3946-
}
39473984

39483985
/*
39493986
* Everything checks out, so set up the section info

0 commit comments

Comments
 (0)