https://sourceware.org/bugzilla/show_bug.cgi?id=21720
Bug ID: 21720 Summary: Malicious ELF32 with invalid program table entry count can cause memory exhaustion Product: binutils Version: 2.29 Status: UNCONFIRMED Severity: normal Priority: P2 Component: binutils Assignee: unassigned at sourceware dot org Reporter: jgj212 at gmail dot com Target Milestone: --- Created attachment 10248 --> https://sourceware.org/bugzilla/attachment.cgi?id=10248&action=edit poc version: objdump 2.29.51 ----------------------- $objdump -x $FILE ----------------------- critical code in fcuntion 'elf_object_p' in file 'elfcode.h' : ``` amt = i_ehdrp->e_phnum * sizeof (*i_phdr); elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt); ``` 'i_ehdrp->e_phnum' is initialized in fcuntion 'elf_object_p' as follow: ``` i_ehdrp = elf_elfheader (abfd); elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); ``` And elf32 header as follow: ``` /* 32-bit ELF file header. */ typedef struct { unsigned char e_ident[16]; /* ELF "magic number" */ unsigned char e_type[2]; /* Identifies object file type */ unsigned char e_machine[2]; /* Specifies required architecture */ unsigned char e_version[4]; /* Identifies object file version */ unsigned char e_entry[4]; /* Entry point virtual address */ unsigned char e_phoff[4]; /* Program header table file offset */ unsigned char e_shoff[4]; /* Section header table file offset */ unsigned char e_flags[4]; /* Processor-specific flags */ unsigned char e_ehsize[2]; /* ELF header size in bytes */ unsigned char e_phentsize[2]; /* Program header table entry size */ unsigned char e_phnum[2]; /* Program header table entry count */ unsigned char e_shentsize[2]; /* Section header table entry size */ unsigned char e_shnum[2]; /* Section header table entry count */ unsigned char e_shstrndx[2]; /* Section header string table index */ } Elf32_External_Ehdr; ``` So normally, 'i_ehdrp->e_phnum' must smaller than 0xffff But there is code in fcuntion 'elf_object_p' as follow: ``` /* And program headers. */ if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0) { i_ehdrp->e_phnum = i_shdr.sh_info; if (i_ehdrp->e_phnum != i_shdr.sh_info) goto got_wrong_format_error; } ``` It means that if (i_ehdrp->e_phnum==0xffff) is true, i_ehdrp->e_phnum will be computed user another way: 1)read the first section header 2)use the field named 'sh_info' of the fist section header to replace the i_ehdrp->e_phnum Because sh_info of sectionHeader32 is a unsigned int from file, so i_ehdrp->e_phnum can be controlled from 0 to 0xffffffff. ``` /* Section header */ typedef struct elf_internal_shdr { unsigned int sh_name; /* Section name, index in string tbl */ unsigned int sh_type; /* Type of section */ bfd_vma sh_flags; /* Miscellaneous section attributes */ bfd_vma sh_addr; /* Section virtual addr at execution */ file_ptr sh_offset; /* Section file offset */ bfd_size_type sh_size; /* Size of section in bytes */ unsigned int sh_link; /* Index of another section */ unsigned int sh_info; /* Additional section information */ bfd_vma sh_addralign; /* Section alignment */ bfd_size_type sh_entsize; /* Entry size if section holds table */ /* The internal rep also has some cached info associated with it. */ asection * bfd_section; /* Associated BFD section. */ unsigned char *contents; /* Section contents. */ } Elf_Internal_Shdr; /* Section header */ typedef struct { unsigned char sh_name[4]; /* Section name, index in string tbl */ unsigned char sh_type[4]; /* Type of section */ unsigned char sh_flags[4]; /* Miscellaneous section attributes */ unsigned char sh_addr[4]; /* Section virtual addr at execution */ unsigned char sh_offset[4]; /* Section file offset */ unsigned char sh_size[4]; /* Size of section in bytes */ unsigned char sh_link[4]; /* Index of another section */ unsigned char sh_info[4]; /* Additional section information */ unsigned char sh_addralign[4]; /* Section alignment */ unsigned char sh_entsize[4]; /* Entry size if section holds table */ } Elf32_External_Shdr; ``` 'i_ehdrp->e_phnum' is a unsigned int, it can be controlled as 0xffffffff. This could cause memory exhaustion to DOS. Credit:The bug was discovered by ADLab of Venustech -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils