@@ -1708,6 +1708,87 @@ static int elf_validity_ehdr(const struct load_info *info)
17081708 return 0 ;
17091709}
17101710
1711+ /**
1712+ * elf_validity_cache_sechdrs() - Cache section headers if valid
1713+ * @info: Load info to compute section headers from
1714+ *
1715+ * Checks:
1716+ *
1717+ * * ELF header is valid (see elf_validity_ehdr())
1718+ * * Section headers are the size we expect
1719+ * * Section array fits in the user provided data
1720+ * * Section index 0 is NULL
1721+ * * Section contents are inbounds
1722+ *
1723+ * Then updates @info with a &load_info->sechdrs pointer if valid.
1724+ *
1725+ * Return: %0 if valid, negative error code if validation failed.
1726+ */
1727+ static int elf_validity_cache_sechdrs (struct load_info * info )
1728+ {
1729+ Elf_Shdr * sechdrs ;
1730+ Elf_Shdr * shdr ;
1731+ int i ;
1732+ int err ;
1733+
1734+ err = elf_validity_ehdr (info );
1735+ if (err < 0 )
1736+ return err ;
1737+
1738+ if (info -> hdr -> e_shentsize != sizeof (Elf_Shdr )) {
1739+ pr_err ("Invalid ELF section header size\n" );
1740+ return - ENOEXEC ;
1741+ }
1742+
1743+ /*
1744+ * e_shnum is 16 bits, and sizeof(Elf_Shdr) is
1745+ * known and small. So e_shnum * sizeof(Elf_Shdr)
1746+ * will not overflow unsigned long on any platform.
1747+ */
1748+ if (info -> hdr -> e_shoff >= info -> len
1749+ || (info -> hdr -> e_shnum * sizeof (Elf_Shdr ) >
1750+ info -> len - info -> hdr -> e_shoff )) {
1751+ pr_err ("Invalid ELF section header overflow\n" );
1752+ return - ENOEXEC ;
1753+ }
1754+
1755+ sechdrs = (void * )info -> hdr + info -> hdr -> e_shoff ;
1756+
1757+ /*
1758+ * The code assumes that section 0 has a length of zero and
1759+ * an addr of zero, so check for it.
1760+ */
1761+ if (sechdrs [0 ].sh_type != SHT_NULL
1762+ || sechdrs [0 ].sh_size != 0
1763+ || sechdrs [0 ].sh_addr != 0 ) {
1764+ pr_err ("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n" ,
1765+ sechdrs [0 ].sh_type );
1766+ return - ENOEXEC ;
1767+ }
1768+
1769+ /* Validate contents are inbounds */
1770+ for (i = 1 ; i < info -> hdr -> e_shnum ; i ++ ) {
1771+ shdr = & sechdrs [i ];
1772+ switch (shdr -> sh_type ) {
1773+ case SHT_NULL :
1774+ case SHT_NOBITS :
1775+ /* No contents, offset/size don't mean anything */
1776+ continue ;
1777+ default :
1778+ err = validate_section_offset (info , shdr );
1779+ if (err < 0 ) {
1780+ pr_err ("Invalid ELF section in module (section %u type %u)\n" ,
1781+ i , shdr -> sh_type );
1782+ return err ;
1783+ }
1784+ }
1785+ }
1786+
1787+ info -> sechdrs = sechdrs ;
1788+
1789+ return 0 ;
1790+ }
1791+
17111792/*
17121793 * Check userspace passed ELF module against our expectations, and cache
17131794 * useful variables for further processing as we go.
@@ -1737,29 +1818,10 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
17371818 unsigned int num_info_secs = 0 , info_idx ;
17381819 unsigned int num_sym_secs = 0 , sym_idx ;
17391820
1740- err = elf_validity_ehdr (info );
1821+ err = elf_validity_cache_sechdrs (info );
17411822 if (err < 0 )
17421823 return err ;
17431824
1744- if (info -> hdr -> e_shentsize != sizeof (Elf_Shdr )) {
1745- pr_err ("Invalid ELF section header size\n" );
1746- goto no_exec ;
1747- }
1748-
1749- /*
1750- * e_shnum is 16 bits, and sizeof(Elf_Shdr) is
1751- * known and small. So e_shnum * sizeof(Elf_Shdr)
1752- * will not overflow unsigned long on any platform.
1753- */
1754- if (info -> hdr -> e_shoff >= info -> len
1755- || (info -> hdr -> e_shnum * sizeof (Elf_Shdr ) >
1756- info -> len - info -> hdr -> e_shoff )) {
1757- pr_err ("Invalid ELF section header overflow\n" );
1758- goto no_exec ;
1759- }
1760-
1761- info -> sechdrs = (void * )info -> hdr + info -> hdr -> e_shoff ;
1762-
17631825 /*
17641826 * Verify if the section name table index is valid.
17651827 */
@@ -1772,11 +1834,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
17721834 }
17731835
17741836 strhdr = & info -> sechdrs [info -> hdr -> e_shstrndx ];
1775- err = validate_section_offset (info , strhdr );
1776- if (err < 0 ) {
1777- pr_err ("Invalid ELF section hdr(type %u)\n" , strhdr -> sh_type );
1778- return err ;
1779- }
17801837
17811838 /*
17821839 * The section name table must be NUL-terminated, as required
@@ -1793,18 +1850,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
17931850 goto no_exec ;
17941851 }
17951852
1796- /*
1797- * The code assumes that section 0 has a length of zero and
1798- * an addr of zero, so check for it.
1799- */
1800- if (info -> sechdrs [0 ].sh_type != SHT_NULL
1801- || info -> sechdrs [0 ].sh_size != 0
1802- || info -> sechdrs [0 ].sh_addr != 0 ) {
1803- pr_err ("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n" ,
1804- info -> sechdrs [0 ].sh_type );
1805- goto no_exec ;
1806- }
1807-
18081853 for (i = 1 ; i < info -> hdr -> e_shnum ; i ++ ) {
18091854 shdr = & info -> sechdrs [i ];
18101855 switch (shdr -> sh_type ) {
@@ -1823,12 +1868,6 @@ static int elf_validity_cache_copy(struct load_info *info, int flags)
18231868 sym_idx = i ;
18241869 fallthrough ;
18251870 default :
1826- err = validate_section_offset (info , shdr );
1827- if (err < 0 ) {
1828- pr_err ("Invalid ELF section in module (section %u type %u)\n" ,
1829- i , shdr -> sh_type );
1830- return err ;
1831- }
18321871 if (strcmp (info -> secstrings + shdr -> sh_name ,
18331872 ".gnu.linkonce.this_module" ) == 0 ) {
18341873 num_mod_secs ++ ;
0 commit comments