@@ -195,6 +195,38 @@ static unsigned int find_sec(const struct load_info *info, const char *name)
195195 return 0 ;
196196}
197197
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+
198230/* Find a module section, or NULL. */
199231static void * section_addr (const struct load_info * info , const char * name )
200232{
@@ -1854,6 +1886,39 @@ static int elf_validity_cache_secstrings(struct load_info *info)
18541886 return 0 ;
18551887}
18561888
1889+ /**
1890+ * elf_validity_cache_index_info() - Validate and cache modinfo section
1891+ * @info: Load info to populate the modinfo index on.
1892+ * Must have &load_info->sechdrs and &load_info->secstrings populated
1893+ *
1894+ * Checks that if there is a .modinfo section, it is unique.
1895+ * Then, it caches its index in &load_info->index.info.
1896+ * Finally, it tries to populate the name to improve error messages.
1897+ *
1898+ * Return: %0 if valid, %-ENOEXEC if multiple modinfo sections were found.
1899+ */
1900+ static int elf_validity_cache_index_info (struct load_info * info )
1901+ {
1902+ int info_idx ;
1903+
1904+ info_idx = find_any_unique_sec (info , ".modinfo" );
1905+
1906+ if (info_idx == 0 )
1907+ /* Early return, no .modinfo */
1908+ return 0 ;
1909+
1910+ if (info_idx < 0 ) {
1911+ pr_err ("Only one .modinfo section must exist.\n" );
1912+ return - ENOEXEC ;
1913+ }
1914+
1915+ info -> index .info = info_idx ;
1916+ /* Try to find a name early so we can log errors with a module name */
1917+ info -> name = get_modinfo (info , "name" );
1918+
1919+ return 0 ;
1920+ }
1921+
18571922/*
18581923 * Check userspace passed ELF module against our expectations, and cache
18591924 * useful variables for further processing as we go.
@@ -1880,13 +1945,15 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
18801945 Elf_Shdr * shdr ;
18811946 int err ;
18821947 unsigned int num_mod_secs = 0 , mod_idx ;
1883- unsigned int num_info_secs = 0 , info_idx ;
18841948 unsigned int num_sym_secs = 0 , sym_idx ;
18851949
18861950 err = elf_validity_cache_sechdrs (info );
18871951 if (err < 0 )
18881952 return err ;
18891953 err = elf_validity_cache_secstrings (info );
1954+ if (err < 0 )
1955+ return err ;
1956+ err = elf_validity_cache_index_info (info );
18901957 if (err < 0 )
18911958 return err ;
18921959
@@ -1912,24 +1979,11 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
19121979 ".gnu.linkonce.this_module" ) == 0 ) {
19131980 num_mod_secs ++ ;
19141981 mod_idx = i ;
1915- } else if (strcmp (info -> secstrings + shdr -> sh_name ,
1916- ".modinfo" ) == 0 ) {
1917- num_info_secs ++ ;
1918- info_idx = i ;
19191982 }
19201983 break ;
19211984 }
19221985 }
19231986
1924- if (num_info_secs > 1 ) {
1925- pr_err ("Only one .modinfo section must exist.\n" );
1926- goto no_exec ;
1927- } else if (num_info_secs == 1 ) {
1928- /* Try to find a name early so we can log errors with a module name */
1929- info -> index .info = info_idx ;
1930- info -> name = get_modinfo (info , "name" );
1931- }
1932-
19331987 if (num_sym_secs != 1 ) {
19341988 pr_warn ("%s: module has no symbols (stripped?)\n" ,
19351989 info -> name ?: "(missing .modinfo section or name field)" );
0 commit comments