klange / toaruos

A completely-from-scratch hobby operating system: bootloader, kernel, drivers, C library, and userspace including a composited graphical UI, dynamic linker, syntax-highlighting text editor, network stack, etc.
https://toaruos.org/
University of Illinois/NCSA Open Source License
6.03k stars 475 forks source link

Some arbitrary address read vulnerabilities in readelf #244

Closed liyansong2018 closed 1 year ago

liyansong2018 commented 2 years ago

Hi,

there are many out-of-bounds read leading to possible temporary denial of service in readelf.

PoC

poc_elf_out_of_bounds.zip

./readelf -a poc_elf_out_of_bounds
ELF Header:
...
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
...

Relocation section '' at offset 0x200000007 contains 159629617834 entries.
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
zsh: segmentation fault  ./readelf -a poc_elf_out_of_bounds

In fact, when printing external data in%s format, readelf need to judge the legitimacy of the address, which cannot exceed the range of the ELF file.

git diff             
diff --git a/apps/readelf.c b/apps/readelf.c
index ce25d5e1..5832f88f 100644
--- a/apps/readelf.c
+++ b/apps/readelf.c
@@ -670,9 +670,11 @@ int main(int argc, char * argv[]) {
                                        break;
                                case SHT_RELA:
                                        if (show_bits & SHOW_RELOCATIONS) {
-                                               printf("\nRelocation section '%s' at offset 0x%lx contains %ld entries.\n",
+                                               if (is_valid(stringTable + sectionHeader.sh_name)) {
+                                                       printf("\nRelocation section '%s' at offset 0x%lx contains %ld entries.\n",
                                                        stringTable + sectionHeader.sh_name, sectionHeader.sh_offset,
                                                        sectionHeader.sh_size / sizeof(Elf64_Rela));
+                                               }
                                                printf("  Offset          Info           Type           Sym. Value    Sym. Name + Addend\n");

                                                /* Section this relocation is in */