@@ -1980,6 +1980,39 @@ static int elf_validity_cache_index_mod(struct load_info *info)
1980
1980
return 0 ;
1981
1981
}
1982
1982
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
+ }
1983
2016
1984
2017
/*
1985
2018
* 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)
2003
2036
*/
2004
2037
static int elf_validity_cache_copy (struct load_info * info , int flags )
2005
2038
{
2006
- unsigned int i ;
2007
- Elf_Shdr * shdr ;
2008
2039
int err ;
2009
- unsigned int num_sym_secs = 0 , sym_idx ;
2040
+ int str_idx ;
2010
2041
2011
2042
err = elf_validity_cache_sechdrs (info );
2012
2043
if (err < 0 )
@@ -2018,34 +2049,21 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
2018
2049
if (err < 0 )
2019
2050
return err ;
2020
2051
err = elf_validity_cache_index_mod (info );
2052
+ if (err < 0 )
2053
+ return err ;
2054
+ err = elf_validity_cache_index_sym (info );
2021
2055
if (err < 0 )
2022
2056
return err ;
2023
2057
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 ;
2043
2063
}
2044
2064
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 ;
2049
2067
info -> strtab = (char * )info -> hdr + info -> sechdrs [info -> index .str ].sh_offset ;
2050
2068
2051
2069
/* 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)
2066
2084
info -> index .pcpu = find_pcpusec (info );
2067
2085
2068
2086
return 0 ;
2069
-
2070
- no_exec :
2071
- return - ENOEXEC ;
2072
2087
}
2073
2088
2074
2089
#define COPY_CHUNK_SIZE (16*PAGE_SIZE)
0 commit comments