@@ -1789,6 +1789,71 @@ static int elf_validity_cache_sechdrs(struct load_info *info)
17891789 return 0 ;
17901790}
17911791
1792+ /**
1793+ * elf_validity_cache_secstrings() - Caches section names if valid
1794+ * @info: Load info to cache section names from. Must have valid sechdrs.
1795+ *
1796+ * Specifically checks:
1797+ *
1798+ * * Section name table index is inbounds of section headers
1799+ * * Section name table is not empty
1800+ * * Section name table is NUL terminated
1801+ * * All section name offsets are inbounds of the section
1802+ *
1803+ * Then updates @info with a &load_info->secstrings pointer if valid.
1804+ *
1805+ * Return: %0 if valid, negative error code if validation failed.
1806+ */
1807+ static int elf_validity_cache_secstrings (struct load_info * info )
1808+ {
1809+ Elf_Shdr * strhdr , * shdr ;
1810+ char * secstrings ;
1811+ int i ;
1812+
1813+ /*
1814+ * Verify if the section name table index is valid.
1815+ */
1816+ if (info -> hdr -> e_shstrndx == SHN_UNDEF
1817+ || info -> hdr -> e_shstrndx >= info -> hdr -> e_shnum ) {
1818+ pr_err ("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n" ,
1819+ info -> hdr -> e_shstrndx , info -> hdr -> e_shstrndx ,
1820+ info -> hdr -> e_shnum );
1821+ return - ENOEXEC ;
1822+ }
1823+
1824+ strhdr = & info -> sechdrs [info -> hdr -> e_shstrndx ];
1825+
1826+ /*
1827+ * The section name table must be NUL-terminated, as required
1828+ * by the spec. This makes strcmp and pr_* calls that access
1829+ * strings in the section safe.
1830+ */
1831+ secstrings = (void * )info -> hdr + strhdr -> sh_offset ;
1832+ if (strhdr -> sh_size == 0 ) {
1833+ pr_err ("empty section name table\n" );
1834+ return - ENOEXEC ;
1835+ }
1836+ if (secstrings [strhdr -> sh_size - 1 ] != '\0' ) {
1837+ pr_err ("ELF Spec violation: section name table isn't null terminated\n" );
1838+ return - ENOEXEC ;
1839+ }
1840+
1841+ for (i = 0 ; i < info -> hdr -> e_shnum ; i ++ ) {
1842+ shdr = & info -> sechdrs [i ];
1843+ /* SHT_NULL means sh_name has an undefined value */
1844+ if (shdr -> sh_type == SHT_NULL )
1845+ continue ;
1846+ if (shdr -> sh_name >= strhdr -> sh_size ) {
1847+ pr_err ("Invalid ELF section name in module (section %u type %u)\n" ,
1848+ i , shdr -> sh_type );
1849+ return - ENOEXEC ;
1850+ }
1851+ }
1852+
1853+ info -> secstrings = secstrings ;
1854+ return 0 ;
1855+ }
1856+
17921857/*
17931858 * Check userspace passed ELF module against our expectations, and cache
17941859 * useful variables for further processing as we go.
@@ -1812,7 +1877,7 @@ static int elf_validity_cache_sechdrs(struct load_info *info)
18121877static int elf_validity_cache_copy (struct load_info * info , int flags )
18131878{
18141879 unsigned int i ;
1815- Elf_Shdr * shdr , * strhdr ;
1880+ Elf_Shdr * shdr ;
18161881 int err ;
18171882 unsigned int num_mod_secs = 0 , mod_idx ;
18181883 unsigned int num_info_secs = 0 , info_idx ;
@@ -1821,34 +1886,9 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
18211886 err = elf_validity_cache_sechdrs (info );
18221887 if (err < 0 )
18231888 return err ;
1824-
1825- /*
1826- * Verify if the section name table index is valid.
1827- */
1828- if (info -> hdr -> e_shstrndx == SHN_UNDEF
1829- || info -> hdr -> e_shstrndx >= info -> hdr -> e_shnum ) {
1830- pr_err ("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n" ,
1831- info -> hdr -> e_shstrndx , info -> hdr -> e_shstrndx ,
1832- info -> hdr -> e_shnum );
1833- goto no_exec ;
1834- }
1835-
1836- strhdr = & info -> sechdrs [info -> hdr -> e_shstrndx ];
1837-
1838- /*
1839- * The section name table must be NUL-terminated, as required
1840- * by the spec. This makes strcmp and pr_* calls that access
1841- * strings in the section safe.
1842- */
1843- info -> secstrings = (void * )info -> hdr + strhdr -> sh_offset ;
1844- if (strhdr -> sh_size == 0 ) {
1845- pr_err ("empty section name table\n" );
1846- goto no_exec ;
1847- }
1848- if (info -> secstrings [strhdr -> sh_size - 1 ] != '\0' ) {
1849- pr_err ("ELF Spec violation: section name table isn't null terminated\n" );
1850- goto no_exec ;
1851- }
1889+ err = elf_validity_cache_secstrings (info );
1890+ if (err < 0 )
1891+ return err ;
18521892
18531893 for (i = 1 ; i < info -> hdr -> e_shnum ; i ++ ) {
18541894 shdr = & info -> sechdrs [i ];
@@ -1877,14 +1917,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
18771917 num_info_secs ++ ;
18781918 info_idx = i ;
18791919 }
1880-
1881- if (shdr -> sh_flags & SHF_ALLOC ) {
1882- if (shdr -> sh_name >= strhdr -> sh_size ) {
1883- pr_err ("Invalid ELF section name in module (section %u type %u)\n" ,
1884- i , shdr -> sh_type );
1885- return - ENOEXEC ;
1886- }
1887- }
18881920 break ;
18891921 }
18901922 }
0 commit comments