Skip to content

Commit e1aa6d6

Browse files
committed
add more explicit pointer checks when clearing .gnu.version
1 parent 7ff7a80 commit e1aa6d6

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

src/patchelf.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,8 @@ void ElfFile<ElfFileParamNames>::cleanDependencySymbolVersions()
17161716
auto shdrVersym = findSectionHeader(".gnu.version");
17171717
auto shdrVersymR = findSectionHeader(".gnu.version_r");
17181718

1719-
auto versyms = (Elf_Versym *)(fileContents->data() + rdi(shdrVersym.sh_offset));
1719+
auto versyms = reinterpret_cast<Elf_Versym *>(fileContents->data() + rdi(shdrVersym.sh_offset));
1720+
checkPointer(fileContents, versyms, sizeof(Elf_Versym));
17201721
size_t count = rdi(shdrVersym.sh_size) / sizeof(Elf_Versym);
17211722

17221723
/* Set of versions actually used. */
@@ -1728,17 +1729,24 @@ void ElfFile<ElfFileParamNames>::cleanDependencySymbolVersions()
17281729

17291730
/* Strings associated with .gnu_version_r section: used for debug only. */
17301731
Elf_Shdr & shdrVersionRStrings = shdrs.at(rdi(shdrVersymR.sh_link));
1731-
char * verStrTab = (char *) fileContents->data() + rdi(shdrVersionRStrings.sh_offset);
1732+
char * verStrTab = reinterpret_cast<char *>(fileContents->data() + rdi(shdrVersionRStrings.sh_offset));
17321733

1734+
auto ver_r = reinterpret_cast<Elf_Verneed *>(fileContents->data() + rdi(shdrVersymR.sh_offset));
1735+
checkPointer(fileContents, ver_r, sizeof(Elf_Verneed));
17331736

1734-
auto ver_r = (Elf_Verneed *)(fileContents->data() + rdi(shdrVersymR.sh_offset));
17351737
while (true) {
17361738
auto prev = (Elf_Vernaux *)nullptr;
1737-
auto vern_aux = (Elf_Vernaux *)((char *)ver_r + rdi(ver_r->vn_aux));
1739+
auto vern_aux = reinterpret_cast<Elf_Vernaux *>((char *)ver_r + rdi(ver_r->vn_aux));
1740+
checkPointer(fileContents, vern_aux, sizeof(Elf_Vernaux));
1741+
17381742
char * file = verStrTab + rdi(ver_r->vn_file);
17391743
for (size_t j = 0; j < ver_r->vn_cnt ; j++) {
17401744
char * ver_name = verStrTab + rdi(vern_aux->vna_name);
1741-
auto next = (Elf_Vernaux *)((char *)vern_aux + rdi(vern_aux->vna_next));
1745+
// FIXME: add proper check for null-terminated string
1746+
checkPointer(fileContents, ver_name, sizeof(char));
1747+
1748+
auto next = reinterpret_cast<Elf_Vernaux *>((char *)vern_aux + rdi(vern_aux->vna_next));
1749+
checkPointer(fileContents, next, sizeof(Elf_Vernaux));
17421750

17431751
if (!allVersions.count(rdi(vern_aux->vna_other) & ~0x8000)) {
17441752
debug("Removing version identifier %d %s@%s\n", rdi(vern_aux->vna_other), file, ver_name);
@@ -1769,7 +1777,8 @@ void ElfFile<ElfFileParamNames>::cleanDependencySymbolVersions()
17691777
break;
17701778
}
17711779

1772-
ver_r = (Elf_Verneed *) (((char *) ver_r) + rdi(ver_r->vn_next));
1780+
ver_r = reinterpret_cast<Elf_Verneed *>(((char *) ver_r) + rdi(ver_r->vn_next));
1781+
checkPointer(fileContents, ver_r, sizeof(Elf_Verneed));
17731782
}
17741783

17751784
changed = true;

0 commit comments

Comments
 (0)