Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'modules-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux

Pull modules updates from Luis Chamberlain:

- The whole caching of module code into huge pages by Mike Rapoport is
going in through Andrew Morton's tree due to some other code
dependencies. That's really the biggest highlight for Linux kernel
modules in this release. With it we share huge pages for modules,
starting off with x86. Expect to see that soon through Andrew!

- Helge Deller addressed some lingering low hanging fruit alignment
enhancements by. It is worth pointing out that from his old patch
series I dropped his vmlinux.lds.h change at Masahiro's request as he
would prefer this to be specified in asm code [0].

[0] https://lore.kernel.org/all/20240129192644.3359978-5-mcgrof@kernel.org/T/#m9efef5e700fbecd28b7afb462c15eed8ba78ef5a

- Matthew Maurer and Sami Tolvanen have been tag teaming to help get us
closer to a modversions for Rust. In this cycle we take in quite a
lot of the refactoring for ELF validation. I expect modversions for
Rust will be merged by v6.14 as that code is mostly ready now.

- Adds a new modules selftests: kallsyms which helps us tests
find_symbol() and the limits of kallsyms on Linux today.

- We have a realtime mailing list to kernel-ci testing for modules now
which relies and combines patchwork, kpd and kdevops:

https://patchwork.kernel.org/project/linux-modules/list/
https://github.com/linux-kdevops/kdevops/blob/main/docs/kernel-ci/README.md
https://github.com/linux-kdevops/kdevops/blob/main/docs/kernel-ci/kernel-ci-kpd.md
https://github.com/linux-kdevops/kdevops/blob/main/docs/kernel-ci/linux-modules-kdevops-ci.md

If you want to help avoid Linux kernel modules regressions, now its
simple, just add a new Linux modules sefltests under
tools/testing/selftests/module/ That is it. All new selftests will be
used and leveraged automatically by the CI.

* tag 'modules-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux:
tests/module/gen_test_kallsyms.sh: use 0 value for variables
scripts: Remove export_report.pl
selftests: kallsyms: add MODULE_DESCRIPTION
selftests: add new kallsyms selftests
module: Reformat struct for code style
module: Additional validation in elf_validity_cache_strtab
module: Factor out elf_validity_cache_strtab
module: Group section index calculations together
module: Factor out elf_validity_cache_index_str
module: Factor out elf_validity_cache_index_sym
module: Factor out elf_validity_cache_index_mod
module: Factor out elf_validity_cache_index_info
module: Factor out elf_validity_cache_secstrings
module: Factor out elf_validity_cache_sechdrs
module: Factor out elf_validity_ehdr
module: Take const arg in validate_section_offset
modules: Add missing entry for __ex_table
modules: Ensure 64-bit alignment on __ksymtab_* sections

+854 -412
+1 -5
Makefile
··· 1610 1610 @echo ' with a stack size larger than MINSTACKSIZE (default: 100)' 1611 1611 @echo ' versioncheck - Sanity check on version.h usage' 1612 1612 @echo ' includecheck - Check for duplicate included header files' 1613 - @echo ' export_report - List the usages of all exported symbols' 1614 1613 @echo ' headerdep - Detect inclusion cycles in headers' 1615 1614 @echo ' coccicheck - Check with Coccinelle' 1616 1615 @echo ' clang-analyzer - Check with clang static analyzer' ··· 2022 2023 # Scripts to check various things for consistency 2023 2024 # --------------------------------------------------------------------------- 2024 2025 2025 - PHONY += includecheck versioncheck coccicheck export_report 2026 + PHONY += includecheck versioncheck coccicheck 2026 2027 2027 2028 includecheck: 2028 2029 find $(srctree)/* $(RCS_FIND_IGNORE) \ ··· 2036 2037 2037 2038 coccicheck: 2038 2039 $(Q)$(BASH) $(srctree)/scripts/$@ 2039 - 2040 - export_report: 2041 - $(PERL) $(srctree)/scripts/export_report.pl 2042 2040 2043 2041 PHONY += checkstack kernelrelease kernelversion image_name 2044 2042
+6 -1
kernel/module/internal.h
··· 80 80 unsigned int used_pages; 81 81 #endif 82 82 struct { 83 - unsigned int sym, str, mod, vers, info, pcpu; 83 + unsigned int sym; 84 + unsigned int str; 85 + unsigned int mod; 86 + unsigned int vers; 87 + unsigned int info; 88 + unsigned int pcpu; 84 89 } index; 85 90 }; 86 91
+491 -216
kernel/module/main.c
··· 195 195 return 0; 196 196 } 197 197 198 + /** 199 + * find_any_unique_sec() - Find a unique section index by name 200 + * @info: Load info for the module to scan 201 + * @name: Name of the section we're looking for 202 + * 203 + * Locates a unique section by name. Ignores SHF_ALLOC. 204 + * 205 + * Return: Section index if found uniquely, zero if absent, negative count 206 + * of total instances if multiple were found. 207 + */ 208 + static int find_any_unique_sec(const struct load_info *info, const char *name) 209 + { 210 + unsigned int idx; 211 + unsigned int count = 0; 212 + int i; 213 + 214 + for (i = 1; i < info->hdr->e_shnum; i++) { 215 + if (strcmp(info->secstrings + info->sechdrs[i].sh_name, 216 + name) == 0) { 217 + count++; 218 + idx = i; 219 + } 220 + } 221 + if (count == 1) { 222 + return idx; 223 + } else if (count == 0) { 224 + return 0; 225 + } else { 226 + return -count; 227 + } 228 + } 229 + 198 230 /* Find a module section, or NULL. */ 199 231 static void *section_addr(const struct load_info *info, const char *name) 200 232 { ··· 1711 1679 return strstarts(name, ".exit"); 1712 1680 } 1713 1681 1714 - static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) 1682 + static int validate_section_offset(const struct load_info *info, Elf_Shdr *shdr) 1715 1683 { 1716 1684 #if defined(CONFIG_64BIT) 1717 1685 unsigned long long secend; ··· 1727 1695 if (secend < shdr->sh_offset || secend > info->len) 1728 1696 return -ENOEXEC; 1729 1697 1698 + return 0; 1699 + } 1700 + 1701 + /** 1702 + * elf_validity_ehdr() - Checks an ELF header for module validity 1703 + * @info: Load info containing the ELF header to check 1704 + * 1705 + * Checks whether an ELF header could belong to a valid module. Checks: 1706 + * 1707 + * * ELF header is within the data the user provided 1708 + * * ELF magic is present 1709 + * * It is relocatable (not final linked, not core file, etc.) 1710 + * * The header's machine type matches what the architecture expects. 1711 + * * Optional arch-specific hook for other properties 1712 + * - module_elf_check_arch() is currently only used by PPC to check 1713 + * ELF ABI version, but may be used by others in the future. 1714 + * 1715 + * Return: %0 if valid, %-ENOEXEC on failure. 1716 + */ 1717 + static int elf_validity_ehdr(const struct load_info *info) 1718 + { 1719 + if (info->len < sizeof(*(info->hdr))) { 1720 + pr_err("Invalid ELF header len %lu\n", info->len); 1721 + return -ENOEXEC; 1722 + } 1723 + if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) { 1724 + pr_err("Invalid ELF header magic: != %s\n", ELFMAG); 1725 + return -ENOEXEC; 1726 + } 1727 + if (info->hdr->e_type != ET_REL) { 1728 + pr_err("Invalid ELF header type: %u != %u\n", 1729 + info->hdr->e_type, ET_REL); 1730 + return -ENOEXEC; 1731 + } 1732 + if (!elf_check_arch(info->hdr)) { 1733 + pr_err("Invalid architecture in ELF header: %u\n", 1734 + info->hdr->e_machine); 1735 + return -ENOEXEC; 1736 + } 1737 + if (!module_elf_check_arch(info->hdr)) { 1738 + pr_err("Invalid module architecture in ELF header: %u\n", 1739 + info->hdr->e_machine); 1740 + return -ENOEXEC; 1741 + } 1742 + return 0; 1743 + } 1744 + 1745 + /** 1746 + * elf_validity_cache_sechdrs() - Cache section headers if valid 1747 + * @info: Load info to compute section headers from 1748 + * 1749 + * Checks: 1750 + * 1751 + * * ELF header is valid (see elf_validity_ehdr()) 1752 + * * Section headers are the size we expect 1753 + * * Section array fits in the user provided data 1754 + * * Section index 0 is NULL 1755 + * * Section contents are inbounds 1756 + * 1757 + * Then updates @info with a &load_info->sechdrs pointer if valid. 1758 + * 1759 + * Return: %0 if valid, negative error code if validation failed. 1760 + */ 1761 + static int elf_validity_cache_sechdrs(struct load_info *info) 1762 + { 1763 + Elf_Shdr *sechdrs; 1764 + Elf_Shdr *shdr; 1765 + int i; 1766 + int err; 1767 + 1768 + err = elf_validity_ehdr(info); 1769 + if (err < 0) 1770 + return err; 1771 + 1772 + if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) { 1773 + pr_err("Invalid ELF section header size\n"); 1774 + return -ENOEXEC; 1775 + } 1776 + 1777 + /* 1778 + * e_shnum is 16 bits, and sizeof(Elf_Shdr) is 1779 + * known and small. So e_shnum * sizeof(Elf_Shdr) 1780 + * will not overflow unsigned long on any platform. 1781 + */ 1782 + if (info->hdr->e_shoff >= info->len 1783 + || (info->hdr->e_shnum * sizeof(Elf_Shdr) > 1784 + info->len - info->hdr->e_shoff)) { 1785 + pr_err("Invalid ELF section header overflow\n"); 1786 + return -ENOEXEC; 1787 + } 1788 + 1789 + sechdrs = (void *)info->hdr + info->hdr->e_shoff; 1790 + 1791 + /* 1792 + * The code assumes that section 0 has a length of zero and 1793 + * an addr of zero, so check for it. 1794 + */ 1795 + if (sechdrs[0].sh_type != SHT_NULL 1796 + || sechdrs[0].sh_size != 0 1797 + || sechdrs[0].sh_addr != 0) { 1798 + pr_err("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n", 1799 + sechdrs[0].sh_type); 1800 + return -ENOEXEC; 1801 + } 1802 + 1803 + /* Validate contents are inbounds */ 1804 + for (i = 1; i < info->hdr->e_shnum; i++) { 1805 + shdr = &sechdrs[i]; 1806 + switch (shdr->sh_type) { 1807 + case SHT_NULL: 1808 + case SHT_NOBITS: 1809 + /* No contents, offset/size don't mean anything */ 1810 + continue; 1811 + default: 1812 + err = validate_section_offset(info, shdr); 1813 + if (err < 0) { 1814 + pr_err("Invalid ELF section in module (section %u type %u)\n", 1815 + i, shdr->sh_type); 1816 + return err; 1817 + } 1818 + } 1819 + } 1820 + 1821 + info->sechdrs = sechdrs; 1822 + 1823 + return 0; 1824 + } 1825 + 1826 + /** 1827 + * elf_validity_cache_secstrings() - Caches section names if valid 1828 + * @info: Load info to cache section names from. Must have valid sechdrs. 1829 + * 1830 + * Specifically checks: 1831 + * 1832 + * * Section name table index is inbounds of section headers 1833 + * * Section name table is not empty 1834 + * * Section name table is NUL terminated 1835 + * * All section name offsets are inbounds of the section 1836 + * 1837 + * Then updates @info with a &load_info->secstrings pointer if valid. 1838 + * 1839 + * Return: %0 if valid, negative error code if validation failed. 1840 + */ 1841 + static int elf_validity_cache_secstrings(struct load_info *info) 1842 + { 1843 + Elf_Shdr *strhdr, *shdr; 1844 + char *secstrings; 1845 + int i; 1846 + 1847 + /* 1848 + * Verify if the section name table index is valid. 1849 + */ 1850 + if (info->hdr->e_shstrndx == SHN_UNDEF 1851 + || info->hdr->e_shstrndx >= info->hdr->e_shnum) { 1852 + pr_err("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n", 1853 + info->hdr->e_shstrndx, info->hdr->e_shstrndx, 1854 + info->hdr->e_shnum); 1855 + return -ENOEXEC; 1856 + } 1857 + 1858 + strhdr = &info->sechdrs[info->hdr->e_shstrndx]; 1859 + 1860 + /* 1861 + * The section name table must be NUL-terminated, as required 1862 + * by the spec. This makes strcmp and pr_* calls that access 1863 + * strings in the section safe. 1864 + */ 1865 + secstrings = (void *)info->hdr + strhdr->sh_offset; 1866 + if (strhdr->sh_size == 0) { 1867 + pr_err("empty section name table\n"); 1868 + return -ENOEXEC; 1869 + } 1870 + if (secstrings[strhdr->sh_size - 1] != '\0') { 1871 + pr_err("ELF Spec violation: section name table isn't null terminated\n"); 1872 + return -ENOEXEC; 1873 + } 1874 + 1875 + for (i = 0; i < info->hdr->e_shnum; i++) { 1876 + shdr = &info->sechdrs[i]; 1877 + /* SHT_NULL means sh_name has an undefined value */ 1878 + if (shdr->sh_type == SHT_NULL) 1879 + continue; 1880 + if (shdr->sh_name >= strhdr->sh_size) { 1881 + pr_err("Invalid ELF section name in module (section %u type %u)\n", 1882 + i, shdr->sh_type); 1883 + return -ENOEXEC; 1884 + } 1885 + } 1886 + 1887 + info->secstrings = secstrings; 1888 + return 0; 1889 + } 1890 + 1891 + /** 1892 + * elf_validity_cache_index_info() - Validate and cache modinfo section 1893 + * @info: Load info to populate the modinfo index on. 1894 + * Must have &load_info->sechdrs and &load_info->secstrings populated 1895 + * 1896 + * Checks that if there is a .modinfo section, it is unique. 1897 + * Then, it caches its index in &load_info->index.info. 1898 + * Finally, it tries to populate the name to improve error messages. 1899 + * 1900 + * Return: %0 if valid, %-ENOEXEC if multiple modinfo sections were found. 1901 + */ 1902 + static int elf_validity_cache_index_info(struct load_info *info) 1903 + { 1904 + int info_idx; 1905 + 1906 + info_idx = find_any_unique_sec(info, ".modinfo"); 1907 + 1908 + if (info_idx == 0) 1909 + /* Early return, no .modinfo */ 1910 + return 0; 1911 + 1912 + if (info_idx < 0) { 1913 + pr_err("Only one .modinfo section must exist.\n"); 1914 + return -ENOEXEC; 1915 + } 1916 + 1917 + info->index.info = info_idx; 1918 + /* Try to find a name early so we can log errors with a module name */ 1919 + info->name = get_modinfo(info, "name"); 1920 + 1921 + return 0; 1922 + } 1923 + 1924 + /** 1925 + * elf_validity_cache_index_mod() - Validates and caches this_module section 1926 + * @info: Load info to cache this_module on. 1927 + * Must have &load_info->sechdrs and &load_info->secstrings populated 1928 + * 1929 + * The ".gnu.linkonce.this_module" ELF section is special. It is what modpost 1930 + * uses to refer to __this_module and let's use rely on THIS_MODULE to point 1931 + * to &__this_module properly. The kernel's modpost declares it on each 1932 + * modules's *.mod.c file. If the struct module of the kernel changes a full 1933 + * kernel rebuild is required. 1934 + * 1935 + * We have a few expectations for this special section, this function 1936 + * validates all this for us: 1937 + * 1938 + * * The section has contents 1939 + * * The section is unique 1940 + * * We expect the kernel to always have to allocate it: SHF_ALLOC 1941 + * * The section size must match the kernel's run time's struct module 1942 + * size 1943 + * 1944 + * If all checks pass, the index will be cached in &load_info->index.mod 1945 + * 1946 + * Return: %0 on validation success, %-ENOEXEC on failure 1947 + */ 1948 + static int elf_validity_cache_index_mod(struct load_info *info) 1949 + { 1950 + Elf_Shdr *shdr; 1951 + int mod_idx; 1952 + 1953 + mod_idx = find_any_unique_sec(info, ".gnu.linkonce.this_module"); 1954 + if (mod_idx <= 0) { 1955 + pr_err("module %s: Exactly one .gnu.linkonce.this_module section must exist.\n", 1956 + info->name ?: "(missing .modinfo section or name field)"); 1957 + return -ENOEXEC; 1958 + } 1959 + 1960 + shdr = &info->sechdrs[mod_idx]; 1961 + 1962 + if (shdr->sh_type == SHT_NOBITS) { 1963 + pr_err("module %s: .gnu.linkonce.this_module section must have a size set\n", 1964 + info->name ?: "(missing .modinfo section or name field)"); 1965 + return -ENOEXEC; 1966 + } 1967 + 1968 + if (!(shdr->sh_flags & SHF_ALLOC)) { 1969 + pr_err("module %s: .gnu.linkonce.this_module must occupy memory during process execution\n", 1970 + info->name ?: "(missing .modinfo section or name field)"); 1971 + return -ENOEXEC; 1972 + } 1973 + 1974 + if (shdr->sh_size != sizeof(struct module)) { 1975 + pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n", 1976 + info->name ?: "(missing .modinfo section or name field)"); 1977 + return -ENOEXEC; 1978 + } 1979 + 1980 + info->index.mod = mod_idx; 1981 + 1982 + return 0; 1983 + } 1984 + 1985 + /** 1986 + * elf_validity_cache_index_sym() - Validate and cache symtab index 1987 + * @info: Load info to cache symtab index in. 1988 + * Must have &load_info->sechdrs and &load_info->secstrings populated. 1989 + * 1990 + * Checks that there is exactly one symbol table, then caches its index in 1991 + * &load_info->index.sym. 1992 + * 1993 + * Return: %0 if valid, %-ENOEXEC on failure. 1994 + */ 1995 + static int elf_validity_cache_index_sym(struct load_info *info) 1996 + { 1997 + unsigned int sym_idx; 1998 + unsigned int num_sym_secs = 0; 1999 + int i; 2000 + 2001 + for (i = 1; i < info->hdr->e_shnum; i++) { 2002 + if (info->sechdrs[i].sh_type == SHT_SYMTAB) { 2003 + num_sym_secs++; 2004 + sym_idx = i; 2005 + } 2006 + } 2007 + 2008 + if (num_sym_secs != 1) { 2009 + pr_warn("%s: module has no symbols (stripped?)\n", 2010 + info->name ?: "(missing .modinfo section or name field)"); 2011 + return -ENOEXEC; 2012 + } 2013 + 2014 + info->index.sym = sym_idx; 2015 + 2016 + return 0; 2017 + } 2018 + 2019 + /** 2020 + * elf_validity_cache_index_str() - Validate and cache strtab index 2021 + * @info: Load info to cache strtab index in. 2022 + * Must have &load_info->sechdrs and &load_info->secstrings populated. 2023 + * Must have &load_info->index.sym populated. 2024 + * 2025 + * Looks at the symbol table's associated string table, makes sure it is 2026 + * in-bounds, and caches it. 2027 + * 2028 + * Return: %0 if valid, %-ENOEXEC on failure. 2029 + */ 2030 + static int elf_validity_cache_index_str(struct load_info *info) 2031 + { 2032 + unsigned int str_idx = info->sechdrs[info->index.sym].sh_link; 2033 + 2034 + if (str_idx == SHN_UNDEF || str_idx >= info->hdr->e_shnum) { 2035 + pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n", 2036 + str_idx, str_idx, info->hdr->e_shnum); 2037 + return -ENOEXEC; 2038 + } 2039 + 2040 + info->index.str = str_idx; 2041 + return 0; 2042 + } 2043 + 2044 + /** 2045 + * elf_validity_cache_index() - Resolve, validate, cache section indices 2046 + * @info: Load info to read from and update. 2047 + * &load_info->sechdrs and &load_info->secstrings must be populated. 2048 + * @flags: Load flags, relevant to suppress version loading, see 2049 + * uapi/linux/module.h 2050 + * 2051 + * Populates &load_info->index, validating as it goes. 2052 + * See child functions for per-field validation: 2053 + * 2054 + * * elf_validity_cache_index_info() 2055 + * * elf_validity_cache_index_mod() 2056 + * * elf_validity_cache_index_sym() 2057 + * * elf_validity_cache_index_str() 2058 + * 2059 + * If versioning is not suppressed via flags, load the version index from 2060 + * a section called "__versions" with no validation. 2061 + * 2062 + * If CONFIG_SMP is enabled, load the percpu section by name with no 2063 + * validation. 2064 + * 2065 + * Return: 0 on success, negative error code if an index failed validation. 2066 + */ 2067 + static int elf_validity_cache_index(struct load_info *info, int flags) 2068 + { 2069 + int err; 2070 + 2071 + err = elf_validity_cache_index_info(info); 2072 + if (err < 0) 2073 + return err; 2074 + err = elf_validity_cache_index_mod(info); 2075 + if (err < 0) 2076 + return err; 2077 + err = elf_validity_cache_index_sym(info); 2078 + if (err < 0) 2079 + return err; 2080 + err = elf_validity_cache_index_str(info); 2081 + if (err < 0) 2082 + return err; 2083 + 2084 + if (flags & MODULE_INIT_IGNORE_MODVERSIONS) 2085 + info->index.vers = 0; /* Pretend no __versions section! */ 2086 + else 2087 + info->index.vers = find_sec(info, "__versions"); 2088 + 2089 + info->index.pcpu = find_pcpusec(info); 2090 + 2091 + return 0; 2092 + } 2093 + 2094 + /** 2095 + * elf_validity_cache_strtab() - Validate and cache symbol string table 2096 + * @info: Load info to read from and update. 2097 + * Must have &load_info->sechdrs and &load_info->secstrings populated. 2098 + * Must have &load_info->index populated. 2099 + * 2100 + * Checks: 2101 + * 2102 + * * The string table is not empty. 2103 + * * The string table starts and ends with NUL (required by ELF spec). 2104 + * * Every &Elf_Sym->st_name offset in the symbol table is inbounds of the 2105 + * string table. 2106 + * 2107 + * And caches the pointer as &load_info->strtab in @info. 2108 + * 2109 + * Return: 0 on success, negative error code if a check failed. 2110 + */ 2111 + static int elf_validity_cache_strtab(struct load_info *info) 2112 + { 2113 + Elf_Shdr *str_shdr = &info->sechdrs[info->index.str]; 2114 + Elf_Shdr *sym_shdr = &info->sechdrs[info->index.sym]; 2115 + char *strtab = (char *)info->hdr + str_shdr->sh_offset; 2116 + Elf_Sym *syms = (void *)info->hdr + sym_shdr->sh_offset; 2117 + int i; 2118 + 2119 + if (str_shdr->sh_size == 0) { 2120 + pr_err("empty symbol string table\n"); 2121 + return -ENOEXEC; 2122 + } 2123 + if (strtab[0] != '\0') { 2124 + pr_err("symbol string table missing leading NUL\n"); 2125 + return -ENOEXEC; 2126 + } 2127 + if (strtab[str_shdr->sh_size - 1] != '\0') { 2128 + pr_err("symbol string table isn't NUL terminated\n"); 2129 + return -ENOEXEC; 2130 + } 2131 + 2132 + /* 2133 + * Now that we know strtab is correctly structured, check symbol 2134 + * starts are inbounds before they're used later. 2135 + */ 2136 + for (i = 0; i < sym_shdr->sh_size / sizeof(*syms); i++) { 2137 + if (syms[i].st_name >= str_shdr->sh_size) { 2138 + pr_err("symbol name out of bounds in string table"); 2139 + return -ENOEXEC; 2140 + } 2141 + } 2142 + 2143 + info->strtab = strtab; 1730 2144 return 0; 1731 2145 } 1732 2146 ··· 2198 1720 */ 2199 1721 static int elf_validity_cache_copy(struct load_info *info, int flags) 2200 1722 { 2201 - unsigned int i; 2202 - Elf_Shdr *shdr, *strhdr; 2203 1723 int err; 2204 - unsigned int num_mod_secs = 0, mod_idx; 2205 - unsigned int num_info_secs = 0, info_idx; 2206 - unsigned int num_sym_secs = 0, sym_idx; 2207 1724 2208 - if (info->len < sizeof(*(info->hdr))) { 2209 - pr_err("Invalid ELF header len %lu\n", info->len); 2210 - goto no_exec; 2211 - } 2212 - 2213 - if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) { 2214 - pr_err("Invalid ELF header magic: != %s\n", ELFMAG); 2215 - goto no_exec; 2216 - } 2217 - if (info->hdr->e_type != ET_REL) { 2218 - pr_err("Invalid ELF header type: %u != %u\n", 2219 - info->hdr->e_type, ET_REL); 2220 - goto no_exec; 2221 - } 2222 - if (!elf_check_arch(info->hdr)) { 2223 - pr_err("Invalid architecture in ELF header: %u\n", 2224 - info->hdr->e_machine); 2225 - goto no_exec; 2226 - } 2227 - if (!module_elf_check_arch(info->hdr)) { 2228 - pr_err("Invalid module architecture in ELF header: %u\n", 2229 - info->hdr->e_machine); 2230 - goto no_exec; 2231 - } 2232 - if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) { 2233 - pr_err("Invalid ELF section header size\n"); 2234 - goto no_exec; 2235 - } 2236 - 2237 - /* 2238 - * e_shnum is 16 bits, and sizeof(Elf_Shdr) is 2239 - * known and small. So e_shnum * sizeof(Elf_Shdr) 2240 - * will not overflow unsigned long on any platform. 2241 - */ 2242 - if (info->hdr->e_shoff >= info->len 2243 - || (info->hdr->e_shnum * sizeof(Elf_Shdr) > 2244 - info->len - info->hdr->e_shoff)) { 2245 - pr_err("Invalid ELF section header overflow\n"); 2246 - goto no_exec; 2247 - } 2248 - 2249 - info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; 2250 - 2251 - /* 2252 - * Verify if the section name table index is valid. 2253 - */ 2254 - if (info->hdr->e_shstrndx == SHN_UNDEF 2255 - || info->hdr->e_shstrndx >= info->hdr->e_shnum) { 2256 - pr_err("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n", 2257 - info->hdr->e_shstrndx, info->hdr->e_shstrndx, 2258 - info->hdr->e_shnum); 2259 - goto no_exec; 2260 - } 2261 - 2262 - strhdr = &info->sechdrs[info->hdr->e_shstrndx]; 2263 - err = validate_section_offset(info, strhdr); 2264 - if (err < 0) { 2265 - pr_err("Invalid ELF section hdr(type %u)\n", strhdr->sh_type); 1725 + err = elf_validity_cache_sechdrs(info); 1726 + if (err < 0) 2266 1727 return err; 2267 - } 2268 - 2269 - /* 2270 - * The section name table must be NUL-terminated, as required 2271 - * by the spec. This makes strcmp and pr_* calls that access 2272 - * strings in the section safe. 2273 - */ 2274 - info->secstrings = (void *)info->hdr + strhdr->sh_offset; 2275 - if (strhdr->sh_size == 0) { 2276 - pr_err("empty section name table\n"); 2277 - goto no_exec; 2278 - } 2279 - if (info->secstrings[strhdr->sh_size - 1] != '\0') { 2280 - pr_err("ELF Spec violation: section name table isn't null terminated\n"); 2281 - goto no_exec; 2282 - } 2283 - 2284 - /* 2285 - * The code assumes that section 0 has a length of zero and 2286 - * an addr of zero, so check for it. 2287 - */ 2288 - if (info->sechdrs[0].sh_type != SHT_NULL 2289 - || info->sechdrs[0].sh_size != 0 2290 - || info->sechdrs[0].sh_addr != 0) { 2291 - pr_err("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n", 2292 - info->sechdrs[0].sh_type); 2293 - goto no_exec; 2294 - } 2295 - 2296 - for (i = 1; i < info->hdr->e_shnum; i++) { 2297 - shdr = &info->sechdrs[i]; 2298 - switch (shdr->sh_type) { 2299 - case SHT_NULL: 2300 - case SHT_NOBITS: 2301 - continue; 2302 - case SHT_SYMTAB: 2303 - if (shdr->sh_link == SHN_UNDEF 2304 - || shdr->sh_link >= info->hdr->e_shnum) { 2305 - pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n", 2306 - shdr->sh_link, shdr->sh_link, 2307 - info->hdr->e_shnum); 2308 - goto no_exec; 2309 - } 2310 - num_sym_secs++; 2311 - sym_idx = i; 2312 - fallthrough; 2313 - default: 2314 - err = validate_section_offset(info, shdr); 2315 - if (err < 0) { 2316 - pr_err("Invalid ELF section in module (section %u type %u)\n", 2317 - i, shdr->sh_type); 2318 - return err; 2319 - } 2320 - if (strcmp(info->secstrings + shdr->sh_name, 2321 - ".gnu.linkonce.this_module") == 0) { 2322 - num_mod_secs++; 2323 - mod_idx = i; 2324 - } else if (strcmp(info->secstrings + shdr->sh_name, 2325 - ".modinfo") == 0) { 2326 - num_info_secs++; 2327 - info_idx = i; 2328 - } 2329 - 2330 - if (shdr->sh_flags & SHF_ALLOC) { 2331 - if (shdr->sh_name >= strhdr->sh_size) { 2332 - pr_err("Invalid ELF section name in module (section %u type %u)\n", 2333 - i, shdr->sh_type); 2334 - return -ENOEXEC; 2335 - } 2336 - } 2337 - break; 2338 - } 2339 - } 2340 - 2341 - if (num_info_secs > 1) { 2342 - pr_err("Only one .modinfo section must exist.\n"); 2343 - goto no_exec; 2344 - } else if (num_info_secs == 1) { 2345 - /* Try to find a name early so we can log errors with a module name */ 2346 - info->index.info = info_idx; 2347 - info->name = get_modinfo(info, "name"); 2348 - } 2349 - 2350 - if (num_sym_secs != 1) { 2351 - pr_warn("%s: module has no symbols (stripped?)\n", 2352 - info->name ?: "(missing .modinfo section or name field)"); 2353 - goto no_exec; 2354 - } 2355 - 2356 - /* Sets internal symbols and strings. */ 2357 - info->index.sym = sym_idx; 2358 - shdr = &info->sechdrs[sym_idx]; 2359 - info->index.str = shdr->sh_link; 2360 - info->strtab = (char *)info->hdr + info->sechdrs[info->index.str].sh_offset; 2361 - 2362 - /* 2363 - * The ".gnu.linkonce.this_module" ELF section is special. It is 2364 - * what modpost uses to refer to __this_module and let's use rely 2365 - * on THIS_MODULE to point to &__this_module properly. The kernel's 2366 - * modpost declares it on each modules's *.mod.c file. If the struct 2367 - * module of the kernel changes a full kernel rebuild is required. 2368 - * 2369 - * We have a few expectaions for this special section, the following 2370 - * code validates all this for us: 2371 - * 2372 - * o Only one section must exist 2373 - * o We expect the kernel to always have to allocate it: SHF_ALLOC 2374 - * o The section size must match the kernel's run time's struct module 2375 - * size 2376 - */ 2377 - if (num_mod_secs != 1) { 2378 - pr_err("module %s: Only one .gnu.linkonce.this_module section must exist.\n", 2379 - info->name ?: "(missing .modinfo section or name field)"); 2380 - goto no_exec; 2381 - } 2382 - 2383 - shdr = &info->sechdrs[mod_idx]; 2384 - 2385 - /* 2386 - * This is already implied on the switch above, however let's be 2387 - * pedantic about it. 2388 - */ 2389 - if (shdr->sh_type == SHT_NOBITS) { 2390 - pr_err("module %s: .gnu.linkonce.this_module section must have a size set\n", 2391 - info->name ?: "(missing .modinfo section or name field)"); 2392 - goto no_exec; 2393 - } 2394 - 2395 - if (!(shdr->sh_flags & SHF_ALLOC)) { 2396 - pr_err("module %s: .gnu.linkonce.this_module must occupy memory during process execution\n", 2397 - info->name ?: "(missing .modinfo section or name field)"); 2398 - goto no_exec; 2399 - } 2400 - 2401 - if (shdr->sh_size != sizeof(struct module)) { 2402 - pr_err("module %s: .gnu.linkonce.this_module section size must match the kernel's built struct module size at run time\n", 2403 - info->name ?: "(missing .modinfo section or name field)"); 2404 - goto no_exec; 2405 - } 2406 - 2407 - info->index.mod = mod_idx; 1728 + err = elf_validity_cache_secstrings(info); 1729 + if (err < 0) 1730 + return err; 1731 + err = elf_validity_cache_index(info, flags); 1732 + if (err < 0) 1733 + return err; 1734 + err = elf_validity_cache_strtab(info); 1735 + if (err < 0) 1736 + return err; 2408 1737 2409 1738 /* This is temporary: point mod into copy of data. */ 2410 - info->mod = (void *)info->hdr + shdr->sh_offset; 1739 + info->mod = (void *)info->hdr + info->sechdrs[info->index.mod].sh_offset; 2411 1740 2412 1741 /* 2413 1742 * If we didn't load the .modinfo 'name' field earlier, fall back to ··· 2223 1938 if (!info->name) 2224 1939 info->name = info->mod->name; 2225 1940 2226 - if (flags & MODULE_INIT_IGNORE_MODVERSIONS) 2227 - info->index.vers = 0; /* Pretend no __versions section! */ 2228 - else 2229 - info->index.vers = find_sec(info, "__versions"); 2230 - 2231 - info->index.pcpu = find_pcpusec(info); 2232 - 2233 1941 return 0; 2234 - 2235 - no_exec: 2236 - return -ENOEXEC; 2237 1942 } 2238 1943 2239 1944 #define COPY_CHUNK_SIZE (16*PAGE_SIZE)
+105
lib/Kconfig.debug
··· 2920 2920 2921 2921 If unsure, say N. 2922 2922 2923 + config TEST_RUNTIME 2924 + bool 2925 + 2926 + config TEST_RUNTIME_MODULE 2927 + bool 2928 + 2929 + config TEST_KALLSYMS 2930 + tristate "module kallsyms find_symbol() test" 2931 + depends on m 2932 + select TEST_RUNTIME 2933 + select TEST_RUNTIME_MODULE 2934 + select TEST_KALLSYMS_A 2935 + select TEST_KALLSYMS_B 2936 + select TEST_KALLSYMS_C 2937 + select TEST_KALLSYMS_D 2938 + help 2939 + This allows us to stress test find_symbol() through the kallsyms 2940 + used to place symbols on the kernel ELF kallsyms and modules kallsyms 2941 + where we place kernel symbols such as exported symbols. 2942 + 2943 + We have four test modules: 2944 + 2945 + A: has KALLSYSMS_NUMSYMS exported symbols 2946 + B: uses one of A's symbols 2947 + C: adds KALLSYMS_SCALE_FACTOR * KALLSYSMS_NUMSYMS exported 2948 + D: adds 2 * the symbols than C 2949 + 2950 + We stress test find_symbol() through two means: 2951 + 2952 + 1) Upon load of B it will trigger simplify_symbols() to look for the 2953 + one symbol it uses from the module A with tons of symbols. This is an 2954 + indirect way for us to have B call resolve_symbol_wait() upon module 2955 + load. This will eventually call find_symbol() which will eventually 2956 + try to find the symbols used with find_exported_symbol_in_section(). 2957 + find_exported_symbol_in_section() uses bsearch() so a binary search 2958 + for each symbol. Binary search will at worst be O(log(n)) so the 2959 + larger TEST_MODULE_KALLSYSMS the worse the search. 2960 + 2961 + 2) The selftests should load C first, before B. Upon B's load towards 2962 + the end right before we call module B's init routine we get 2963 + complete_formation() called on the module. That will first check 2964 + for duplicate symbols with the call to verify_exported_symbols(). 2965 + That is when we'll force iteration on module C's insane symbol list. 2966 + Since it has 10 * KALLSYMS_NUMSYMS it means we can first test 2967 + just loading B without C. The amount of time it takes to load C Vs 2968 + B can give us an idea of the impact growth of the symbol space and 2969 + give us projection. Module A only uses one symbol from B so to allow 2970 + this scaling in module C to be proportional, if it used more symbols 2971 + then the first test would be doing more and increasing just the 2972 + search space would be slightly different. The last module, module D 2973 + will just increase the search space by twice the number of symbols in 2974 + C so to allow for full projects. 2975 + 2976 + tools/testing/selftests/module/find_symbol.sh 2977 + 2978 + The current defaults will incur a build delay of about 7 minutes 2979 + on an x86_64 with only 8 cores. Enable this only if you want to 2980 + stress test find_symbol() with thousands of symbols. At the same 2981 + time this is also useful to test building modules with thousands of 2982 + symbols, and if BTF is enabled this also stress tests adding BTF 2983 + information for each module. Currently enabling many more symbols 2984 + will segfault the build system. 2985 + 2986 + If unsure, say N. 2987 + 2988 + if TEST_KALLSYMS 2989 + 2990 + config TEST_KALLSYMS_A 2991 + tristate 2992 + depends on m 2993 + 2994 + config TEST_KALLSYMS_B 2995 + tristate 2996 + depends on m 2997 + 2998 + config TEST_KALLSYMS_C 2999 + tristate 3000 + depends on m 3001 + 3002 + config TEST_KALLSYMS_D 3003 + tristate 3004 + depends on m 3005 + 3006 + config TEST_KALLSYMS_NUMSYMS 3007 + int "test kallsyms number of symbols" 3008 + default 100 3009 + help 3010 + The number of symbols to create on TEST_KALLSYMS_A, only one of which 3011 + module TEST_KALLSYMS_B will use. This also will be used 3012 + for how many symbols TEST_KALLSYMS_C will have, scaled up by 3013 + TEST_KALLSYMS_SCALE_FACTOR. Note that setting this to 10,000 will 3014 + trigger a segfault today, don't use anything close to it unless 3015 + you are aware that this should not be used for automated build tests. 3016 + 3017 + config TEST_KALLSYMS_SCALE_FACTOR 3018 + int "test kallsyms scale factor" 3019 + default 8 3020 + help 3021 + How many more unusued symbols will TEST_KALLSYSMS_C have than 3022 + TEST_KALLSYMS_A. If 8, then module C will have 8 * syms 3023 + than module A. Then TEST_KALLSYMS_D will have double the amount 3024 + of symbols than C so to allow projections. 3025 + 3026 + endif # TEST_KALLSYMS 3027 + 2923 3028 config TEST_DEBUG_VIRTUAL 2924 3029 tristate "Test CONFIG_DEBUG_VIRTUAL feature" 2925 3030 depends on DEBUG_VIRTUAL
+1
lib/Makefile
··· 98 98 obj-$(CONFIG_TEST_MAPLE_TREE) += test_maple_tree.o 99 99 obj-$(CONFIG_TEST_PARMAN) += test_parman.o 100 100 obj-$(CONFIG_TEST_KMOD) += test_kmod.o 101 + obj-$(CONFIG_TEST_RUNTIME) += tests/ 101 102 obj-$(CONFIG_TEST_DEBUG_VIRTUAL) += test_debug_virtual.o 102 103 obj-$(CONFIG_TEST_MEMCAT_P) += test_memcat_p.o 103 104 obj-$(CONFIG_TEST_OBJAGG) += test_objagg.o
+1
lib/tests/Makefile
··· 1 + obj-$(CONFIG_TEST_RUNTIME_MODULE) += module/
+4
lib/tests/module/.gitignore
··· 1 + test_kallsyms_a.c 2 + test_kallsyms_b.c 3 + test_kallsyms_c.c 4 + test_kallsyms_d.c
+15
lib/tests/module/Makefile
··· 1 + obj-$(CONFIG_TEST_KALLSYMS_A) += test_kallsyms_a.o 2 + obj-$(CONFIG_TEST_KALLSYMS_B) += test_kallsyms_b.o 3 + obj-$(CONFIG_TEST_KALLSYMS_C) += test_kallsyms_c.o 4 + obj-$(CONFIG_TEST_KALLSYMS_D) += test_kallsyms_d.o 5 + 6 + $(obj)/%.c: FORCE 7 + @$(kecho) " GEN $@" 8 + $(Q)$(srctree)/lib/tests/module/gen_test_kallsyms.sh $@\ 9 + $(CONFIG_TEST_KALLSYMS_NUMSYMS) \ 10 + $(CONFIG_TEST_KALLSYMS_SCALE_FACTOR) 11 + 12 + clean-files += test_kallsyms_a.c 13 + clean-files += test_kallsyms_b.c 14 + clean-files += test_kallsyms_c.c 15 + clean-files += test_kallsyms_d.c
+129
lib/tests/module/gen_test_kallsyms.sh
··· 1 + #!/bin/bash 2 + 3 + TARGET=$(basename $1) 4 + DIR=lib/tests/module 5 + TARGET="$DIR/$TARGET" 6 + NUM_SYMS=$2 7 + SCALE_FACTOR=$3 8 + TEST_TYPE=$(echo $TARGET | sed -e 's|lib/tests/module/test_kallsyms_||g') 9 + TEST_TYPE=$(echo $TEST_TYPE | sed -e 's|.c||g') 10 + 11 + gen_template_module_header() 12 + { 13 + cat <<____END_MODULE 14 + // SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1 15 + /* 16 + * Copyright (C) 2023 Luis Chamberlain <mcgrof@kernel.org> 17 + * 18 + * Automatically generated code for testing, do not edit manually. 19 + */ 20 + 21 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 22 + 23 + #include <linux/init.h> 24 + #include <linux/module.h> 25 + #include <linux/printk.h> 26 + 27 + ____END_MODULE 28 + } 29 + 30 + gen_num_syms() 31 + { 32 + PREFIX=$1 33 + NUM=$2 34 + for i in $(seq 1 $NUM); do 35 + printf "int auto_test_%s_%010d = 0;\n" $PREFIX $i 36 + printf "EXPORT_SYMBOL_GPL(auto_test_%s_%010d);\n" $PREFIX $i 37 + done 38 + echo 39 + } 40 + 41 + gen_template_module_data_a() 42 + { 43 + gen_num_syms a $1 44 + cat <<____END_MODULE 45 + static int auto_runtime_test(void) 46 + { 47 + return 0; 48 + } 49 + 50 + ____END_MODULE 51 + } 52 + 53 + gen_template_module_data_b() 54 + { 55 + printf "\nextern int auto_test_a_%010d;\n\n" 28 56 + echo "static int auto_runtime_test(void)" 57 + echo "{" 58 + printf "\nreturn auto_test_a_%010d;\n" 28 59 + echo "}" 60 + } 61 + 62 + gen_template_module_data_c() 63 + { 64 + gen_num_syms c $1 65 + cat <<____END_MODULE 66 + static int auto_runtime_test(void) 67 + { 68 + return 0; 69 + } 70 + 71 + ____END_MODULE 72 + } 73 + 74 + gen_template_module_data_d() 75 + { 76 + gen_num_syms d $1 77 + cat <<____END_MODULE 78 + static int auto_runtime_test(void) 79 + { 80 + return 0; 81 + } 82 + 83 + ____END_MODULE 84 + } 85 + 86 + gen_template_module_exit() 87 + { 88 + cat <<____END_MODULE 89 + static int __init auto_test_module_init(void) 90 + { 91 + return auto_runtime_test(); 92 + } 93 + module_init(auto_test_module_init); 94 + 95 + static void __exit auto_test_module_exit(void) 96 + { 97 + } 98 + module_exit(auto_test_module_exit); 99 + 100 + MODULE_AUTHOR("Luis Chamberlain <mcgrof@kernel.org>"); 101 + MODULE_LICENSE("GPL"); 102 + MODULE_DESCRIPTION("Test module for kallsyms"); 103 + ____END_MODULE 104 + } 105 + 106 + case $TEST_TYPE in 107 + a) 108 + gen_template_module_header > $TARGET 109 + gen_template_module_data_a $NUM_SYMS >> $TARGET 110 + gen_template_module_exit >> $TARGET 111 + ;; 112 + b) 113 + gen_template_module_header > $TARGET 114 + gen_template_module_data_b >> $TARGET 115 + gen_template_module_exit >> $TARGET 116 + ;; 117 + c) 118 + gen_template_module_header > $TARGET 119 + gen_template_module_data_c $((NUM_SYMS * SCALE_FACTOR)) >> $TARGET 120 + gen_template_module_exit >> $TARGET 121 + ;; 122 + d) 123 + gen_template_module_header > $TARGET 124 + gen_template_module_data_d $((NUM_SYMS * SCALE_FACTOR * 2)) >> $TARGET 125 + gen_template_module_exit >> $TARGET 126 + ;; 127 + *) 128 + ;; 129 + esac
-186
scripts/export_report.pl
··· 1 - #!/usr/bin/env perl 2 - # SPDX-License-Identifier: GPL-2.0-only 3 - # 4 - # (C) Copyright IBM Corporation 2006. 5 - # Author : Ram Pai (linuxram@us.ibm.com) 6 - # 7 - # Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c 8 - # 9 - 10 - use warnings; 11 - use Getopt::Std; 12 - use strict; 13 - 14 - sub numerically { 15 - my $no1 = (split /\s+/, $a)[1]; 16 - my $no2 = (split /\s+/, $b)[1]; 17 - return $no1 <=> $no2; 18 - } 19 - 20 - sub alphabetically { 21 - my ($module1, $value1) = @{$a}; 22 - my ($module2, $value2) = @{$b}; 23 - return $value1 <=> $value2 || $module2 cmp $module1; 24 - } 25 - 26 - sub print_depends_on { 27 - my ($href) = @_; 28 - print "\n"; 29 - for my $mod (sort keys %$href) { 30 - my $list = $href->{$mod}; 31 - print "\t$mod:\n"; 32 - foreach my $sym (sort numerically @{$list}) { 33 - my ($symbol, $no) = split /\s+/, $sym; 34 - printf("\t\t%-25s\n", $symbol); 35 - } 36 - print "\n"; 37 - } 38 - print "\n"; 39 - print "~"x80 , "\n"; 40 - } 41 - 42 - sub usage { 43 - print "Usage: @_ -h -k Module.symvers [ -o outputfile ] \n", 44 - "\t-f: treat all the non-option argument as .mod.c files. ", 45 - "Recommend using this as the last option\n", 46 - "\t-h: print detailed help\n", 47 - "\t-k: the path to Module.symvers file. By default uses ", 48 - "the file from the current directory\n", 49 - "\t-o outputfile: output the report to outputfile\n"; 50 - exit 0; 51 - } 52 - 53 - sub collectcfiles { 54 - my @file; 55 - open my $fh, '< modules.order' or die "cannot open modules.order: $!\n"; 56 - while (<$fh>) { 57 - s/\.ko$/.mod.c/; 58 - push (@file, $_) 59 - } 60 - close($fh); 61 - chomp @file; 62 - return @file; 63 - } 64 - 65 - my (%SYMBOL, %MODULE, %opt, @allcfiles); 66 - 67 - if (not getopts('hk:o:f',\%opt) or defined $opt{'h'}) { 68 - usage($0); 69 - } 70 - 71 - if (defined $opt{'f'}) { 72 - @allcfiles = @ARGV; 73 - } else { 74 - @allcfiles = collectcfiles(); 75 - } 76 - 77 - if (not defined $opt{'k'}) { 78 - $opt{'k'} = "Module.symvers"; 79 - } 80 - 81 - open (my $module_symvers, '<', $opt{'k'}) 82 - or die "Sorry, cannot open $opt{'k'}: $!\n"; 83 - 84 - if (defined $opt{'o'}) { 85 - open (my $out, '>', $opt{'o'}) 86 - or die "Sorry, cannot open $opt{'o'} $!\n"; 87 - 88 - select $out; 89 - } 90 - 91 - # 92 - # collect all the symbols and their attributes from the 93 - # Module.symvers file 94 - # 95 - while ( <$module_symvers> ) { 96 - chomp; 97 - my (undef, $symbol, $module, $gpl, $namespace) = split('\t'); 98 - $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; 99 - } 100 - close($module_symvers); 101 - 102 - # 103 - # collect the usage count of each symbol. 104 - # 105 - my $modversion_warnings = 0; 106 - 107 - foreach my $thismod (@allcfiles) { 108 - my $module; 109 - 110 - unless (open ($module, '<', $thismod)) { 111 - warn "Sorry, cannot open $thismod: $!\n"; 112 - next; 113 - } 114 - 115 - my $state=0; 116 - while ( <$module> ) { 117 - chomp; 118 - if ($state == 0) { 119 - $state = 1 if ($_ =~ /static const struct modversion_info/); 120 - next; 121 - } 122 - if ($state == 1) { 123 - $state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/); 124 - next; 125 - } 126 - if ($state == 2) { 127 - if ( $_ !~ /0x[0-9a-f]+,/ ) { 128 - next; 129 - } 130 - my $sym = (split /([,"])/,)[4]; 131 - my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}}; 132 - $SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl]; 133 - push(@{$MODULE{$thismod}} , $sym); 134 - } 135 - } 136 - if ($state != 2) { 137 - warn "WARNING:$thismod is not built with CONFIG_MODVERSIONS enabled\n"; 138 - $modversion_warnings++; 139 - } 140 - close($module); 141 - } 142 - 143 - print "\tThis file reports the exported symbols usage patterns by in-tree\n", 144 - "\t\t\t\tmodules\n"; 145 - printf("%s\n\n\n","x"x80); 146 - printf("\t\t\t\tINDEX\n\n\n"); 147 - printf("SECTION 1: Usage counts of all exported symbols\n"); 148 - printf("SECTION 2: List of modules and the exported symbols they use\n"); 149 - printf("%s\n\n\n","x"x80); 150 - printf("SECTION 1:\tThe exported symbols and their usage count\n\n"); 151 - printf("%-25s\t%-25s\t%-5s\t%-25s\n", "Symbol", "Module", "Usage count", 152 - "export type"); 153 - 154 - # 155 - # print the list of unused exported symbols 156 - # 157 - foreach my $list (sort alphabetically values(%SYMBOL)) { 158 - my ($module, $value, $symbol, $gpl) = @{$list}; 159 - printf("%-25s\t%-25s\t%-10s\t", $symbol, $module, $value); 160 - if (defined $gpl) { 161 - printf("%-25s\n",$gpl); 162 - } else { 163 - printf("\n"); 164 - } 165 - } 166 - printf("%s\n\n\n","x"x80); 167 - 168 - printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel 169 - modules. Each module lists the modules, and the symbols from that module that 170 - it uses. Each listed symbol reports the number of modules using it\n"); 171 - 172 - print "\nNOTE: Got $modversion_warnings CONFIG_MODVERSIONS warnings\n\n" 173 - if $modversion_warnings; 174 - 175 - print "~"x80 , "\n"; 176 - for my $thismod (sort keys %MODULE) { 177 - my $list = $MODULE{$thismod}; 178 - my %depends; 179 - $thismod =~ s/\.mod\.c/.ko/; 180 - print "\t\t\t$thismod\n"; 181 - foreach my $symbol (@{$list}) { 182 - my ($module, $value, undef, $gpl) = @{$SYMBOL{$symbol}}; 183 - push (@{$depends{"$module"}}, "$symbol $value"); 184 - } 185 - print_depends_on(\%depends); 186 - }
+5 -4
scripts/module.lds.S
··· 18 18 *(.export_symbol) 19 19 } 20 20 21 - __ksymtab 0 : { *(SORT(___ksymtab+*)) } 22 - __ksymtab_gpl 0 : { *(SORT(___ksymtab_gpl+*)) } 23 - __kcrctab 0 : { *(SORT(___kcrctab+*)) } 24 - __kcrctab_gpl 0 : { *(SORT(___kcrctab_gpl+*)) } 21 + __ksymtab 0 : ALIGN(8) { *(SORT(___ksymtab+*)) } 22 + __ksymtab_gpl 0 : ALIGN(8) { *(SORT(___ksymtab_gpl+*)) } 23 + __kcrctab 0 : ALIGN(4) { *(SORT(___kcrctab+*)) } 24 + __kcrctab_gpl 0 : ALIGN(4) { *(SORT(___kcrctab_gpl+*)) } 25 25 26 26 .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } 27 27 .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } ··· 29 29 .altinstructions 0 : ALIGN(8) { KEEP(*(.altinstructions)) } 30 30 __bug_table 0 : ALIGN(8) { KEEP(*(__bug_table)) } 31 31 __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } 32 + __ex_table 0 : ALIGN(4) { KEEP(*(__ex_table)) } 32 33 33 34 __patchable_function_entries : { *(__patchable_function_entries) } 34 35
+12
tools/testing/selftests/module/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # Makefile for module loading selftests 3 + 4 + # No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 5 + all: 6 + 7 + TEST_PROGS := find_symbol.sh 8 + 9 + include ../lib.mk 10 + 11 + # Nothing to clean up. 12 + clean:
+3
tools/testing/selftests/module/config
··· 1 + CONFIG_TEST_RUNTIME=y 2 + CONFIG_TEST_RUNTIME_MODULE=y 3 + CONFIG_TEST_KALLSYMS=m
+81
tools/testing/selftests/module/find_symbol.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1 3 + # Copyright (C) 2023 Luis Chamberlain <mcgrof@kernel.org> 4 + # 5 + # This is a stress test script for kallsyms through find_symbol() 6 + 7 + set -e 8 + 9 + # Kselftest framework requirement - SKIP code is 4. 10 + ksft_skip=4 11 + 12 + test_reqs() 13 + { 14 + if ! which modprobe 2> /dev/null > /dev/null; then 15 + echo "$0: You need modprobe installed" >&2 16 + exit $ksft_skip 17 + fi 18 + 19 + if ! which kmod 2> /dev/null > /dev/null; then 20 + echo "$0: You need kmod installed" >&2 21 + exit $ksft_skip 22 + fi 23 + 24 + if ! which perf 2> /dev/null > /dev/null; then 25 + echo "$0: You need perf installed" >&2 26 + exit $ksft_skip 27 + fi 28 + 29 + uid=$(id -u) 30 + if [ $uid -ne 0 ]; then 31 + echo $msg must be run as root >&2 32 + exit $ksft_skip 33 + fi 34 + } 35 + 36 + load_mod() 37 + { 38 + local STATS="-e duration_time" 39 + STATS="$STATS -e user_time" 40 + STATS="$STATS -e system_time" 41 + STATS="$STATS -e page-faults" 42 + local MOD=$1 43 + 44 + local ARCH="$(uname -m)" 45 + case "${ARCH}" in 46 + x86_64) 47 + perf stat $STATS $MODPROBE test_kallsyms_b 48 + ;; 49 + *) 50 + time $MODPROBE test_kallsyms_b 51 + exit 1 52 + ;; 53 + esac 54 + } 55 + 56 + remove_all() 57 + { 58 + $MODPROBE -r test_kallsyms_b 59 + for i in a b c d; do 60 + $MODPROBE -r test_kallsyms_$i 61 + done 62 + } 63 + test_reqs 64 + 65 + MODPROBE=$(</proc/sys/kernel/modprobe) 66 + 67 + remove_all 68 + load_mod test_kallsyms_b 69 + remove_all 70 + 71 + # Now pollute the namespace 72 + $MODPROBE test_kallsyms_c 73 + load_mod test_kallsyms_b 74 + 75 + # Now pollute the namespace with twice the number of symbols than the last time 76 + remove_all 77 + $MODPROBE test_kallsyms_c 78 + $MODPROBE test_kallsyms_d 79 + load_mod test_kallsyms_b 80 + 81 + exit 0