Skip to content

Commit 0be41a9

Browse files
maurermcgrof
authored andcommitted
module: Factor out elf_validity_cache_index_mod
Centralize .gnu.linkonce.this_module detection and property validation. Signed-off-by: Matthew Maurer <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Signed-off-by: Luis Chamberlain <[email protected]>
1 parent fbc0e4e commit 0be41a9

File tree

1 file changed

+67
-62
lines changed

1 file changed

+67
-62
lines changed

kernel/module/main.c

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,68 @@ static int elf_validity_cache_index_info(struct load_info *info)
19191919
return 0;
19201920
}
19211921

1922+
/**
1923+
* elf_validity_cache_index_mod() - Validates and caches this_module section
1924+
* @info: Load info to cache this_module on.
1925+
* Must have &load_info->sechdrs and &load_info->secstrings populated
1926+
*
1927+
* The ".gnu.linkonce.this_module" ELF section is special. It is what modpost
1928+
* uses to refer to __this_module and let's use rely on THIS_MODULE to point
1929+
* to &__this_module properly. The kernel's modpost declares it on each
1930+
* modules's *.mod.c file. If the struct module of the kernel changes a full
1931+
* kernel rebuild is required.
1932+
*
1933+
* We have a few expectations for this special section, this function
1934+
* validates all this for us:
1935+
*
1936+
* * The section has contents
1937+
* * The section is unique
1938+
* * We expect the kernel to always have to allocate it: SHF_ALLOC
1939+
* * The section size must match the kernel's run time's struct module
1940+
* size
1941+
*
1942+
* If all checks pass, the index will be cached in &load_info->index.mod
1943+
*
1944+
* Return: %0 on validation success, %-ENOEXEC on failure
1945+
*/
1946+
static int elf_validity_cache_index_mod(struct load_info *info)
1947+
{
1948+
Elf_Shdr *shdr;
1949+
int mod_idx;
1950+
1951+
mod_idx = find_any_unique_sec(info, ".gnu.linkonce.this_module");
1952+
if (mod_idx <= 0) {
1953+
pr_err("module %s: Exactly one .gnu.linkonce.this_module section must exist.\n",
1954+
info->name ?: "(missing .modinfo section or name field)");
1955+
return -ENOEXEC;
1956+
}
1957+
1958+
shdr = &info->sechdrs[mod_idx];
1959+
1960+
if (shdr->sh_type == SHT_NOBITS) {
1961+
pr_err("module %s: .gnu.linkonce.this_module section must have a size set\n",
1962+
info->name ?: "(missing .modinfo section or name field)");
1963+
return -ENOEXEC;
1964+
}
1965+
1966+
if (!(shdr->sh_flags & SHF_ALLOC)) {
1967+
pr_err("module %s: .gnu.linkonce.this_module must occupy memory during process execution\n",
1968+
info->name ?: "(missing .modinfo section or name field)");
1969+
return -ENOEXEC;
1970+
}
1971+
1972+
if (shdr->sh_size != sizeof(struct module)) {
1973+
pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n",
1974+
info->name ?: "(missing .modinfo section or name field)");
1975+
return -ENOEXEC;
1976+
}
1977+
1978+
info->index.mod = mod_idx;
1979+
1980+
return 0;
1981+
}
1982+
1983+
19221984
/*
19231985
* Check userspace passed ELF module against our expectations, and cache
19241986
* useful variables for further processing as we go.
@@ -1944,7 +2006,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
19442006
unsigned int i;
19452007
Elf_Shdr *shdr;
19462008
int err;
1947-
unsigned int num_mod_secs = 0, mod_idx;
19482009
unsigned int num_sym_secs = 0, sym_idx;
19492010

19502011
err = elf_validity_cache_sechdrs(info);
@@ -1954,16 +2015,15 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
19542015
if (err < 0)
19552016
return err;
19562017
err = elf_validity_cache_index_info(info);
2018+
if (err < 0)
2019+
return err;
2020+
err = elf_validity_cache_index_mod(info);
19572021
if (err < 0)
19582022
return err;
19592023

19602024
for (i = 1; i < info->hdr->e_shnum; i++) {
19612025
shdr = &info->sechdrs[i];
1962-
switch (shdr->sh_type) {
1963-
case SHT_NULL:
1964-
case SHT_NOBITS:
1965-
continue;
1966-
case SHT_SYMTAB:
2026+
if (shdr->sh_type == SHT_SYMTAB) {
19672027
if (shdr->sh_link == SHN_UNDEF
19682028
|| shdr->sh_link >= info->hdr->e_shnum) {
19692029
pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n",
@@ -1973,14 +2033,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
19732033
}
19742034
num_sym_secs++;
19752035
sym_idx = i;
1976-
fallthrough;
1977-
default:
1978-
if (strcmp(info->secstrings + shdr->sh_name,
1979-
".gnu.linkonce.this_module") == 0) {
1980-
num_mod_secs++;
1981-
mod_idx = i;
1982-
}
1983-
break;
19842036
}
19852037
}
19862038

@@ -1996,55 +2048,8 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
19962048
info->index.str = shdr->sh_link;
19972049
info->strtab = (char *)info->hdr + info->sechdrs[info->index.str].sh_offset;
19982050

1999-
/*
2000-
* The ".gnu.linkonce.this_module" ELF section is special. It is
2001-
* what modpost uses to refer to __this_module and let's use rely
2002-
* on THIS_MODULE to point to &__this_module properly. The kernel's
2003-
* modpost declares it on each modules's *.mod.c file. If the struct
2004-
* module of the kernel changes a full kernel rebuild is required.
2005-
*
2006-
* We have a few expectaions for this special section, the following
2007-
* code validates all this for us:
2008-
*
2009-
* o Only one section must exist
2010-
* o We expect the kernel to always have to allocate it: SHF_ALLOC
2011-
* o The section size must match the kernel's run time's struct module
2012-
* size
2013-
*/
2014-
if (num_mod_secs != 1) {
2015-
pr_err("module %s: Only one .gnu.linkonce.this_module section must exist.\n",
2016-
info->name ?: "(missing .modinfo section or name field)");
2017-
goto no_exec;
2018-
}
2019-
2020-
shdr = &info->sechdrs[mod_idx];
2021-
2022-
/*
2023-
* This is already implied on the switch above, however let's be
2024-
* pedantic about it.
2025-
*/
2026-
if (shdr->sh_type == SHT_NOBITS) {
2027-
pr_err("module %s: .gnu.linkonce.this_module section must have a size set\n",
2028-
info->name ?: "(missing .modinfo section or name field)");
2029-
goto no_exec;
2030-
}
2031-
2032-
if (!(shdr->sh_flags & SHF_ALLOC)) {
2033-
pr_err("module %s: .gnu.linkonce.this_module must occupy memory during process execution\n",
2034-
info->name ?: "(missing .modinfo section or name field)");
2035-
goto no_exec;
2036-
}
2037-
2038-
if (shdr->sh_size != sizeof(struct module)) {
2039-
pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n",
2040-
info->name ?: "(missing .modinfo section or name field)");
2041-
goto no_exec;
2042-
}
2043-
2044-
info->index.mod = mod_idx;
2045-
20462051
/* This is temporary: point mod into copy of data. */
2047-
info->mod = (void *)info->hdr + shdr->sh_offset;
2052+
info->mod = (void *)info->hdr + info->sechdrs[info->index.mod].sh_offset;
20482053

20492054
/*
20502055
* If we didn't load the .modinfo 'name' field earlier, fall back to

0 commit comments

Comments
 (0)