diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-11 04:25:17 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-03-11 04:25:17 -0500 |
| commit | eabd8746e14fd1250b6d8afc3db5f106de6aee78 (patch) | |
| tree | 5d5080ac2b595b10c549dfae30bf80f70dd8667e /src | |
| parent | 7b1a46ce3419795dedf86ea2b96b2c2e7b8f2d2e (diff) | |
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 <noreply@anthropic.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/src/organizercore.cpp | 25 | ||||
| -rw-r--r-- | src/src/settingsdialogproton.cpp | 14 |
2 files changed, 29 insertions, 10 deletions
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 |
