@@ -1980,6 +1980,39 @@ static int elf_validity_cache_index_mod(struct load_info *info)
19801980 return 0 ;
19811981}
19821982
1983+ /**
1984+ * elf_validity_cache_index_sym() - Validate and cache symtab index
1985+ * @info: Load info to cache symtab index in.
1986+ * Must have &load_info->sechdrs and &load_info->secstrings populated.
1987+ *
1988+ * Checks that there is exactly one symbol table, then caches its index in
1989+ * &load_info->index.sym.
1990+ *
1991+ * Return: %0 if valid, %-ENOEXEC on failure.
1992+ */
1993+ static int elf_validity_cache_index_sym (struct load_info * info )
1994+ {
1995+ unsigned int sym_idx ;
1996+ unsigned int num_sym_secs = 0 ;
1997+ int i ;
1998+
1999+ for (i = 1 ; i < info -> hdr -> e_shnum ; i ++ ) {
2000+ if (info -> sechdrs [i ].sh_type == SHT_SYMTAB ) {
2001+ num_sym_secs ++ ;
2002+ sym_idx = i ;
2003+ }
2004+ }
2005+
2006+ if (num_sym_secs != 1 ) {
2007+ pr_warn ("%s: module has no symbols (stripped?)\n" ,
2008+ info -> name ?: "(missing .modinfo section or name field)" );
2009+ return - ENOEXEC ;
2010+ }
2011+
2012+ info -> index .sym = sym_idx ;
2013+
2014+ return 0 ;
2015+ }
19832016
19842017/*
19852018 * Check userspace passed ELF module against our expectations, and cache
@@ -2003,10 +2036,8 @@ static int elf_validity_cache_index_mod(struct load_info *info)
20032036 */
20042037static int elf_validity_cache_copy (struct load_info * info , int flags )
20052038{
2006- unsigned int i ;
2007- Elf_Shdr * shdr ;
20082039 int err ;
2009- unsigned int num_sym_secs = 0 , sym_idx ;
2040+ int str_idx ;
20102041
20112042 err = elf_validity_cache_sechdrs (info );
20122043 if (err < 0 )
@@ -2018,34 +2049,21 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
20182049 if (err < 0 )
20192050 return err ;
20202051 err = elf_validity_cache_index_mod (info );
2052+ if (err < 0 )
2053+ return err ;
2054+ err = elf_validity_cache_index_sym (info );
20212055 if (err < 0 )
20222056 return err ;
20232057
2024- for (i = 1 ; i < info -> hdr -> e_shnum ; i ++ ) {
2025- shdr = & info -> sechdrs [i ];
2026- if (shdr -> sh_type == SHT_SYMTAB ) {
2027- if (shdr -> sh_link == SHN_UNDEF
2028- || shdr -> sh_link >= info -> hdr -> e_shnum ) {
2029- pr_err ("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n" ,
2030- shdr -> sh_link , shdr -> sh_link ,
2031- info -> hdr -> e_shnum );
2032- goto no_exec ;
2033- }
2034- num_sym_secs ++ ;
2035- sym_idx = i ;
2036- }
2037- }
2038-
2039- if (num_sym_secs != 1 ) {
2040- pr_warn ("%s: module has no symbols (stripped?)\n" ,
2041- info -> name ?: "(missing .modinfo section or name field)" );
2042- goto no_exec ;
2058+ str_idx = info -> sechdrs [info -> index .sym ].sh_link ;
2059+ if (str_idx == SHN_UNDEF || str_idx >= info -> hdr -> e_shnum ) {
2060+ pr_err ("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n" ,
2061+ str_idx , str_idx , info -> hdr -> e_shnum );
2062+ return - ENOEXEC ;
20432063 }
20442064
2045- /* Sets internal symbols and strings. */
2046- info -> index .sym = sym_idx ;
2047- shdr = & info -> sechdrs [sym_idx ];
2048- info -> index .str = shdr -> sh_link ;
2065+ /* Sets internal strings. */
2066+ info -> index .str = str_idx ;
20492067 info -> strtab = (char * )info -> hdr + info -> sechdrs [info -> index .str ].sh_offset ;
20502068
20512069 /* This is temporary: point mod into copy of data. */
@@ -2066,9 +2084,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
20662084 info -> index .pcpu = find_pcpusec (info );
20672085
20682086 return 0 ;
2069-
2070- no_exec :
2071- return - ENOEXEC ;
20722087}
20732088
20742089#define COPY_CHUNK_SIZE (16*PAGE_SIZE)
0 commit comments