Skip to content

Commit 90f8f31

Browse files
maurermcgrof
authored andcommitted
module: Factor out elf_validity_ehdr
Factor out verification of the ELF header and document what is checked. Signed-off-by: Matthew Maurer <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Signed-off-by: Luis Chamberlain <[email protected]>
1 parent f439221 commit 90f8f31

File tree

1 file changed

+47
-23
lines changed

1 file changed

+47
-23
lines changed

kernel/module/main.c

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,50 @@ static int validate_section_offset(const struct load_info *info, Elf_Shdr *shdr)
16641664
return 0;
16651665
}
16661666

1667+
/**
1668+
* elf_validity_ehdr() - Checks an ELF header for module validity
1669+
* @info: Load info containing the ELF header to check
1670+
*
1671+
* Checks whether an ELF header could belong to a valid module. Checks:
1672+
*
1673+
* * ELF header is within the data the user provided
1674+
* * ELF magic is present
1675+
* * It is relocatable (not final linked, not core file, etc.)
1676+
* * The header's machine type matches what the architecture expects.
1677+
* * Optional arch-specific hook for other properties
1678+
* - module_elf_check_arch() is currently only used by PPC to check
1679+
* ELF ABI version, but may be used by others in the future.
1680+
*
1681+
* Return: %0 if valid, %-ENOEXEC on failure.
1682+
*/
1683+
static int elf_validity_ehdr(const struct load_info *info)
1684+
{
1685+
if (info->len < sizeof(*(info->hdr))) {
1686+
pr_err("Invalid ELF header len %lu\n", info->len);
1687+
return -ENOEXEC;
1688+
}
1689+
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
1690+
pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
1691+
return -ENOEXEC;
1692+
}
1693+
if (info->hdr->e_type != ET_REL) {
1694+
pr_err("Invalid ELF header type: %u != %u\n",
1695+
info->hdr->e_type, ET_REL);
1696+
return -ENOEXEC;
1697+
}
1698+
if (!elf_check_arch(info->hdr)) {
1699+
pr_err("Invalid architecture in ELF header: %u\n",
1700+
info->hdr->e_machine);
1701+
return -ENOEXEC;
1702+
}
1703+
if (!module_elf_check_arch(info->hdr)) {
1704+
pr_err("Invalid module architecture in ELF header: %u\n",
1705+
info->hdr->e_machine);
1706+
return -ENOEXEC;
1707+
}
1708+
return 0;
1709+
}
1710+
16671711
/*
16681712
* Check userspace passed ELF module against our expectations, and cache
16691713
* useful variables for further processing as we go.
@@ -1693,30 +1737,10 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
16931737
unsigned int num_info_secs = 0, info_idx;
16941738
unsigned int num_sym_secs = 0, sym_idx;
16951739

1696-
if (info->len < sizeof(*(info->hdr))) {
1697-
pr_err("Invalid ELF header len %lu\n", info->len);
1698-
goto no_exec;
1699-
}
1740+
err = elf_validity_ehdr(info);
1741+
if (err < 0)
1742+
return err;
17001743

1701-
if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
1702-
pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
1703-
goto no_exec;
1704-
}
1705-
if (info->hdr->e_type != ET_REL) {
1706-
pr_err("Invalid ELF header type: %u != %u\n",
1707-
info->hdr->e_type, ET_REL);
1708-
goto no_exec;
1709-
}
1710-
if (!elf_check_arch(info->hdr)) {
1711-
pr_err("Invalid architecture in ELF header: %u\n",
1712-
info->hdr->e_machine);
1713-
goto no_exec;
1714-
}
1715-
if (!module_elf_check_arch(info->hdr)) {
1716-
pr_err("Invalid module architecture in ELF header: %u\n",
1717-
info->hdr->e_machine);
1718-
goto no_exec;
1719-
}
17201744
if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) {
17211745
pr_err("Invalid ELF section header size\n");
17221746
goto no_exec;

0 commit comments

Comments
 (0)