From a1352e52896ee9c70c36ae7674bc5a42cf4747f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 19 Sep 2021 20:25:06 +0200 Subject: [PATCH 1/2] remove raw pointer from findSection2 --- src/Makefile.am | 2 +- src/patchelf.cc | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 41c5885e..ed7a19b1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ -AM_CXXFLAGS = -Wall -std=c++11 -D_FILE_OFFSET_BITS=64 +AM_CXXFLAGS = -Wall -std=c++17 -D_FILE_OFFSET_BITS=64 if WITH_ASAN AM_CXXFLAGS += -fsanitize=address -fsanitize-address-use-after-scope diff --git a/src/patchelf.cc b/src/patchelf.cc index 8e4253c7..bf3a6ac3 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -160,7 +160,7 @@ class ElfFile Elf_Shdr & findSection(const SectionName & sectionName); - Elf_Shdr * findSection2(const SectionName & sectionName); + std::optional> findSection2(const SectionName & sectionName); unsigned int findSection3(const SectionName & sectionName); @@ -637,10 +637,12 @@ Elf_Shdr & ElfFile::findSection(const SectionName & sectionNa template -Elf_Shdr * ElfFile::findSection2(const SectionName & sectionName) +std::optional> ElfFile::findSection2(const SectionName & sectionName) { auto i = findSection3(sectionName); - return i ? &shdrs[i] : nullptr; + if (i) + return shdrs[i]; + return {}; } @@ -1121,7 +1123,7 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) (e.g., those produced by klibc's klcc). */ auto shdrDynamic = findSection2(".dynamic"); if (shdrDynamic) { - auto dyn_table = (Elf_Dyn *) (fileContents->data() + rdi(shdrDynamic->sh_offset)); + auto dyn_table = (Elf_Dyn *) (fileContents->data() + rdi((*shdrDynamic).get().sh_offset)); unsigned int d_tag; for (auto dyn = dyn_table; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) if (d_tag == DT_STRTAB) @@ -1136,13 +1138,14 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) auto shdr = findSection2(".gnu.hash"); // some binaries might this section stripped // in which case we just ignore the value. - if (shdr) dyn->d_un.d_ptr = shdr->sh_addr; + if (shdr) dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_JMPREL) { auto shdr = findSection2(".rel.plt"); - if (!shdr) shdr = findSection2(".rela.plt"); /* 64-bit Linux, x86-64 */ + if (!shdr) shdr = findSection2(".rela.plt"); + /* 64-bit Linux, x86-64 */ if (!shdr) shdr = findSection2(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ if (!shdr) error("cannot find section corresponding to DT_JMPREL"); - dyn->d_un.d_ptr = shdr->sh_addr; + dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_REL) { /* !!! hack! */ auto shdr = findSection2(".rel.dyn"); @@ -1152,14 +1155,14 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) /* some programs have neither section, but this doesn't seem to be a problem */ if (!shdr) continue; - dyn->d_un.d_ptr = shdr->sh_addr; + dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_RELA) { auto shdr = findSection2(".rela.dyn"); /* some programs lack this section, but it doesn't seem to be a problem */ if (!shdr) continue; - dyn->d_un.d_ptr = shdr->sh_addr; + dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_VERNEED) dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr; @@ -1172,7 +1175,7 @@ void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) if (shdr) { auto rld_map_addr = findSection(".rld_map").sh_addr; auto dyn_offset = ((char*)dyn) - ((char*)dyn_table); - dyn->d_un.d_ptr = rld_map_addr + dyn_offset - shdrDynamic->sh_addr; + dyn->d_un.d_ptr = rld_map_addr + dyn_offset - (*shdrDynamic).get().sh_addr; } else { /* ELF file with DT_MIPS_RLD_MAP_REL but without .rld_map is broken, and it's not our job to fix it; yet, we have From 4c73989205abda1259b21c601da09c1dfa61c7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 19 Sep 2021 20:34:15 +0200 Subject: [PATCH 2/2] use more memory-safe at() function --- src/patchelf.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index bf3a6ac3..2b7ec8b9 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -600,7 +600,7 @@ void ElfFile::shiftFile(unsigned int extraPages, Elf_Addr sta PT_INTERP segment into memory. Otherwise glibc will choke. */ phdrs.resize(rdi(hdr()->e_phnum) + 1); wri(hdr()->e_phnum, rdi(hdr()->e_phnum) + 1); - Elf_Phdr & phdr = phdrs[rdi(hdr()->e_phnum) - 1]; + Elf_Phdr & phdr = phdrs.at(rdi(hdr()->e_phnum) - 1); wri(phdr.p_type, PT_LOAD); wri(phdr.p_offset, 0); wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); @@ -641,7 +641,7 @@ std::optional> ElfFile::find { auto i = findSection3(sectionName); if (i) - return shdrs[i]; + return shdrs.at(i); return {}; } @@ -863,7 +863,7 @@ void ElfFile::rewriteSectionsLibrary() wri(hdr()->e_phoff, sizeof(Elf_Ehdr)); phdrs.resize(rdi(hdr()->e_phnum) + 1); wri(hdr()->e_phnum, rdi(hdr()->e_phnum) + 1); - Elf_Phdr & phdr = phdrs[rdi(hdr()->e_phnum) - 1]; + Elf_Phdr & phdr = phdrs.at(rdi(hdr()->e_phnum) - 1); wri(phdr.p_type, PT_LOAD); wri(phdr.p_offset, startOffset); wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); @@ -916,7 +916,7 @@ void ElfFile::rewriteSectionsExecutable() Elf_Addr startAddr = rdi(shdrs.at(lastReplaced + 1).sh_addr); std::string prevSection; for (unsigned int i = 1; i <= lastReplaced; ++i) { - Elf_Shdr & shdr(shdrs[i]); + Elf_Shdr & shdr(shdrs.at(i)); std::string sectionName = getSectionName(shdr); debug("looking at section '%s'\n", sectionName.c_str()); /* !!! Why do we stop after a .dynstr section? I can't @@ -957,7 +957,7 @@ void ElfFile::rewriteSectionsExecutable() assert(rdi(hdr()->e_shnum) == shdrs.size()); sortShdrs(); for (unsigned int i = 1; i < rdi(hdr()->e_shnum); ++i) - * ((Elf_Shdr *) (fileContents->data() + rdi(hdr()->e_shoff)) + i) = shdrs[i]; + * ((Elf_Shdr *) (fileContents->data() + rdi(hdr()->e_shoff)) + i) = shdrs.at(i); } @@ -1349,12 +1349,12 @@ std::string ElfFile::shrinkRPath(char* rpath, std::vectore_machine)) { - neededLibFound[j] = true; + neededLibFound.at(j) = true; libFound = true; } else debug("ignoring library '%s' because its machine type differs\n", libName.c_str());