@@ -58,18 +58,25 @@ static int check_scatter_format(const unsigned char* ehdr, int is_elf32);
5858/* Loader for elf32 or elf64 format program headers
5959 * Returns the entry point function
6060 */
61- int elf_load_image_mmu (uint8_t * image , uintptr_t * pentry , elf_mmu_map_cb mmu_cb )
61+ int elf_load_image_mmu (uint8_t * image , uint32_t image_sz , uintptr_t * pentry ,
62+ elf_mmu_map_cb mmu_cb )
6263{
6364 elf32_header * h32 = (elf32_header * )image ;
6465 elf64_header * h64 = (elf64_header * )image ;
6566 uint16_t entry_count , entry_size ;
6667 uint8_t * entry_off ;
68+ uint32_t ph_offset ;
6769 int is_elf32 , is_le , i ;
6870
6971#ifdef DEBUG_ELF
7072 wolfBoot_printf ("Loading elf at %p\r\n" , (void * )image );
7173#endif
7274
75+ /* Verify image is large enough for the smallest ELF header */
76+ if (image_sz < sizeof (elf32_header )) {
77+ return -1 ; /* image too small */
78+ }
79+
7380 /* Verify ELF header */
7481 if (memcmp (h32 -> ident , ELF_IDENT_STR , 4 ) != 0 ) {
7582 return -1 ; /* not valid header identifier */
@@ -80,6 +87,11 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb)
8087 is_le = (h32 -> ident [5 ] == ELF_ENDIAN_LITTLE );
8188 (void )is_le ;
8289
90+ /* Verify image is large enough for the actual ELF header type */
91+ if (!is_elf32 && image_sz < sizeof (elf64_header )) {
92+ return -1 ; /* image too small for elf64 header */
93+ }
94+
8395 /* Verify this is an executable */
8496 if (GET_H16 (type ) != ELF_HET_EXEC ) {
8597 return -2 ; /* not executable */
@@ -94,9 +106,19 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb)
94106 * pentry = GET_H64 (entry );
95107
96108 /* programs */
97- entry_off = image + GET_H32 (ph_offset );
109+ ph_offset = GET_H32 (ph_offset );
98110 entry_size = GET_H16 (ph_entry_size );
99111 entry_count = GET_H16 (ph_entry_count );
112+
113+ /* Validate program header table is within image bounds */
114+ if (ph_offset >= image_sz ||
115+ entry_size == 0 ||
116+ entry_count > (image_sz / entry_size ) ||
117+ ph_offset + ((uint32_t )entry_count * entry_size ) > image_sz ) {
118+ return -3 ; /* program header table out of bounds */
119+ }
120+ entry_off = image + ph_offset ;
121+
100122#ifdef DEBUG_ELF
101123 wolfBoot_printf ("Program Headers %d (size %d)\r\n" , entry_count , entry_size );
102124#endif
@@ -115,6 +137,12 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb)
115137 continue ;
116138 }
117139
140+ /* Validate segment data is within image bounds */
141+ if (file_size > 0 &&
142+ (offset >= image_sz || file_size > image_sz - offset )) {
143+ return -4 ; /* segment offset/size out of bounds */
144+ }
145+
118146#ifdef DEBUG_ELF
119147 if (file_size > 0 ) {
120148 wolfBoot_printf (
0 commit comments