From eabd8746e14fd1250b6d8afc3db5f106de6aee78 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 11 Mar 2026 04:25:17 -0500 Subject: Patch RPATH to absolute paths when applying cap_sys_admin glibc's ld.so ignores $ORIGIN in RPATH for capability binaries (AT_SECURE mode), causing "cannot open shared object" errors. Now patchelf rewrites RPATH to absolute paths before setcap runs, both in the settings dialog and the auto-apply at mount time. Co-Authored-By: Claude Opus 4.6 --- src/src/organizercore.cpp | 25 ++++++++++++++++++------- src/src/settingsdialogproton.cpp | 14 +++++++++++--- 2 files changed, 29 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/src/organizercore.cpp b/src/src/organizercore.cpp index b42c3ed..c6bd678 100644 --- a/src/src/organizercore.cpp +++ b/src/src/organizercore.cpp @@ -684,13 +684,24 @@ void OrganizerCore::prepareVFS() std::fprintf(stderr, "[VFS] passthrough enabled but binary lacks cap_sys_admin " "— requesting via pkexec...\n"); - QProcess setcap; - setcap.setProgram("pkexec"); - setcap.setArguments({"setcap", "cap_sys_admin+ep", binary}); - setcap.start(); - setcap.waitForFinished(60000); - if (setcap.exitCode() != 0) { + // When cap_sys_admin is set on a binary, glibc's ld.so enters + // AT_SECURE mode and ignores $ORIGIN in RPATH. Patch RPATH to + // absolute paths before applying the capability. + const QFileInfo fi(binary); + const QString binDir = fi.absolutePath(); + const QString absRpath = binDir + "/lib:" + binDir + "/python/lib"; + + QProcess patchelf; + patchelf.setProgram("pkexec"); + patchelf.setArguments({"bash", "-c", + QString("patchelf --force-rpath --set-rpath '%1' '%2' && " + "setcap cap_sys_admin+ep '%2'") + .arg(absRpath, binary)}); + patchelf.start(); + patchelf.waitForFinished(60000); + + if (patchelf.exitCode() != 0) { std::fprintf(stderr, "[VFS] failed to set cap_sys_admin — disabling passthrough\n"); passthrough = false; @@ -699,7 +710,7 @@ void OrganizerCore::prepareVFS() // have it until next exec. Disable passthrough for this session — // it will work automatically on next launch. std::fprintf(stderr, - "[VFS] cap_sys_admin applied to binary — passthrough " + "[VFS] cap_sys_admin + absolute RPATH applied — passthrough " "will activate on next launch\n"); passthrough = false; } diff --git a/src/src/settingsdialogproton.cpp b/src/src/settingsdialogproton.cpp index 36838c4..4bab341 100644 --- a/src/src/settingsdialogproton.cpp +++ b/src/src/settingsdialogproton.cpp @@ -71,11 +71,19 @@ ProtonSettingsTab::ProtonSettingsTab(Settings& s, SettingsDialog& d) ui->passthroughStatusLabel->setText( tr("Granting FUSE passthrough capability... (sudo prompt)")); - // Use pkexec (graphical sudo) to set the file capability. - // This is a one-time operation — the capability persists across runs. + // Use pkexec to patch RPATH to absolute paths and set + // the file capability. $ORIGIN in RPATH is ignored by + // glibc for capability binaries (AT_SECURE mode). + const QFileInfo fi(binary); + const QString binDir = fi.absolutePath(); + const QString absRpath = binDir + "/lib:" + binDir + "/python/lib"; + QProcess proc; proc.setProgram("pkexec"); - proc.setArguments({"setcap", "cap_sys_admin+ep", binary}); + proc.setArguments({"bash", "-c", + QString("patchelf --force-rpath --set-rpath '%1' '%2' && " + "setcap cap_sys_admin+ep '%2'") + .arg(absRpath, binary)}); proc.start(); proc.waitForFinished(60000); // 60s timeout for user to auth -- cgit v1.3.1