Skip to content

Commit 8b32fae

Browse files
committed
Check for other references to the RPATH string
1 parent 75e4daa commit 8b32fae

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/patchelf.cc

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
15381538

15391539
/* !!! We assume that the virtual address in the DT_STRTAB entry
15401540
of the dynamic section corresponds to the .dynstr section. */
1541-
auto shdrDynStr = findSectionHeader(".dynstr");
1541+
auto& shdrDynStr = findSectionHeader(".dynstr");
15421542
char * strTab = (char *) fileContents->data() + rdi(shdrDynStr.sh_offset);
15431543

15441544

@@ -1621,24 +1621,39 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
16211621
}
16221622
changed = true;
16231623

1624-
/* Zero out the previous rpath to prevent retained dependencies in
1625-
Nix. */
1624+
bool rpathStrShared = false;
16261625
size_t rpathSize = 0;
16271626
if (rpath) {
1628-
rpathSize = strlen(rpath);
1627+
std::string_view rpathView {rpath};
1628+
rpathSize = rpathView.size();
1629+
1630+
size_t rpathStrReferences = 0;
1631+
forAllStringReferences(shdrDynStr, [&] (auto refIdx) {
1632+
if (rpathView.end() == std::string_view(strTab + rdi(refIdx)).end())
1633+
rpathStrReferences++;
1634+
});
1635+
assert(rpathStrReferences >= 1);
1636+
debug("Number of rpath references: %lu\n", rpathStrReferences);
1637+
rpathStrShared = rpathStrReferences > 1;
1638+
}
1639+
1640+
/* Zero out the previous rpath to prevent retained dependencies in
1641+
Nix. */
1642+
if (rpath && !rpathStrShared) {
1643+
debug("Tainting old rpath with Xs\n");
16291644
memset(rpath, 'X', rpathSize);
16301645
}
16311646

16321647
debug("new rpath is '%s'\n", newRPath.c_str());
16331648

16341649

1635-
if (newRPath.size() <= rpathSize) {
1650+
if (!rpathStrShared && newRPath.size() <= rpathSize) {
16361651
if (rpath) memcpy(rpath, newRPath.c_str(), newRPath.size() + 1);
16371652
return;
16381653
}
16391654

16401655
/* Grow the .dynstr section to make room for the new RPATH. */
1641-
debug("rpath is too long, resizing...\n");
1656+
debug("rpath is too long or shared, resizing...\n");
16421657

16431658
std::string & newDynStr = replaceSection(".dynstr",
16441659
rdi(shdrDynStr.sh_size) + newRPath.size() + 1);
@@ -2295,7 +2310,7 @@ void ElfFile<ElfFileParamNames>::modifyExecstack(ExecstackMode op)
22952310

22962311
template<ElfFileParams>
22972312
template<class StrIdxCallback>
2298-
void ElfFile<ElfFileParamNames>::forAllStringReferences(Elf_Shdr& strTabHdr, StrIdxCallback&& fn)
2313+
void ElfFile<ElfFileParamNames>::forAllStringReferences(const Elf_Shdr& strTabHdr, StrIdxCallback&& fn)
22992314
{
23002315
for (auto& sym : tryGetSectionSpan<Elf_Sym>(".dynsym"))
23012316
fn(sym.st_name);

0 commit comments

Comments
 (0)