From e1aa6d671c6e81172f7924b812ff8c8669e1a9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Mon, 1 Aug 2022 10:13:00 +0200 Subject: [PATCH] add more explicit pointer checks when clearing .gnu.version --- src/patchelf.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index ca20730..5ea8259 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1716,7 +1716,8 @@ void ElfFile::cleanDependencySymbolVersions() auto shdrVersym = findSectionHeader(".gnu.version"); auto shdrVersymR = findSectionHeader(".gnu.version_r"); - auto versyms = (Elf_Versym *)(fileContents->data() + rdi(shdrVersym.sh_offset)); + auto versyms = reinterpret_cast(fileContents->data() + rdi(shdrVersym.sh_offset)); + checkPointer(fileContents, versyms, sizeof(Elf_Versym)); size_t count = rdi(shdrVersym.sh_size) / sizeof(Elf_Versym); /* Set of versions actually used. */ @@ -1728,17 +1729,24 @@ void ElfFile::cleanDependencySymbolVersions() /* Strings associated with .gnu_version_r section: used for debug only. */ Elf_Shdr & shdrVersionRStrings = shdrs.at(rdi(shdrVersymR.sh_link)); - char * verStrTab = (char *) fileContents->data() + rdi(shdrVersionRStrings.sh_offset); + char * verStrTab = reinterpret_cast(fileContents->data() + rdi(shdrVersionRStrings.sh_offset)); + auto ver_r = reinterpret_cast(fileContents->data() + rdi(shdrVersymR.sh_offset)); + checkPointer(fileContents, ver_r, sizeof(Elf_Verneed)); - auto ver_r = (Elf_Verneed *)(fileContents->data() + rdi(shdrVersymR.sh_offset)); while (true) { auto prev = (Elf_Vernaux *)nullptr; - auto vern_aux = (Elf_Vernaux *)((char *)ver_r + rdi(ver_r->vn_aux)); + auto vern_aux = reinterpret_cast((char *)ver_r + rdi(ver_r->vn_aux)); + checkPointer(fileContents, vern_aux, sizeof(Elf_Vernaux)); + char * file = verStrTab + rdi(ver_r->vn_file); for (size_t j = 0; j < ver_r->vn_cnt ; j++) { char * ver_name = verStrTab + rdi(vern_aux->vna_name); - auto next = (Elf_Vernaux *)((char *)vern_aux + rdi(vern_aux->vna_next)); + // FIXME: add proper check for null-terminated string + checkPointer(fileContents, ver_name, sizeof(char)); + + auto next = reinterpret_cast((char *)vern_aux + rdi(vern_aux->vna_next)); + checkPointer(fileContents, next, sizeof(Elf_Vernaux)); if (!allVersions.count(rdi(vern_aux->vna_other) & ~0x8000)) { debug("Removing version identifier %d %s@%s\n", rdi(vern_aux->vna_other), file, ver_name); @@ -1769,7 +1777,8 @@ void ElfFile::cleanDependencySymbolVersions() break; } - ver_r = (Elf_Verneed *) (((char *) ver_r) + rdi(ver_r->vn_next)); + ver_r = reinterpret_cast(((char *) ver_r) + rdi(ver_r->vn_next)); + checkPointer(fileContents, ver_r, sizeof(Elf_Verneed)); } changed = true;