diff --git a/core/relinker/relinker/src/guest/GuestModuleBuilder.cpp b/core/relinker/relinker/src/guest/GuestModuleBuilder.cpp index de2662f6a..1043171b6 100644 --- a/core/relinker/relinker/src/guest/GuestModuleBuilder.cpp +++ b/core/relinker/relinker/src/guest/GuestModuleBuilder.cpp @@ -285,7 +285,7 @@ std::vector GuestModuleBuilder::Build(const std::filesystem::path }; for (const auto index : order) if (!windows && !deferred(index)) addNeeded("$ORIGIN/" + appDirectory(images[index]) + "/" + images[index].OutputName); for (const auto& name : hostLibraries) addNeeded(name); - if (!windows && runPath != "$ORIGIN" && !runPath.starts_with("$ORIGIN/") && !runPath.starts_with("$ORIGIN:") && !std::filesystem::path(runPath).is_absolute()) throw Domain::RelinkerException("Guest Linux run path must be absolute or begin with $ORIGIN"); + if (!windows && runPath != "$ORIGIN" && !runPath.starts_with("$ORIGIN/") && !runPath.starts_with("$ORIGIN:") && !runPath.starts_with('/')) throw Domain::RelinkerException("Guest Linux run path must be absolute or begin with $ORIGIN"); const auto outputDirectory = outputPath.parent_path().lexically_normal(); std::vector artifacts; for (const auto index : order) { diff --git a/core/relinker/relinker/tests/test_guest_runpath.py b/core/relinker/relinker/tests/test_guest_runpath.py index 754fee90a..e5238ab66 100644 --- a/core/relinker/relinker/tests/test_guest_runpath.py +++ b/core/relinker/relinker/tests/test_guest_runpath.py @@ -17,7 +17,8 @@ def main(): checked = 0 for index, module_directory in enumerate(("sce_module", "prx")): for label, run_path in (("default", None), ("origin", "$ORIGIN"), - ("custom", "$ORIGIN/host libs"), ("absolute", str(work / "absolute libs")), + ("custom", "$ORIGIN/host libs"), ("absolute", "/opt/absolute libs"), + ("absolute-root", "/"), ("absolute-list", "/opt/libs:/usr/local/lib"), ("list", "$ORIGIN/first:$ORIGIN/second"), ("list-bare", "$ORIGIN:$ORIGIN/libs:$ORIGIN")): case = work / f"{index}-{label}" @@ -43,13 +44,21 @@ def main(): assert 0 <= offset < len(strings) and end >= 0, (tags, strings) actual = strings[offset:end].decode() configured = run_path if run_path is not None else "$ORIGIN/libs" - configured_paths = configured.split(":") if label.startswith("list") else [configured] - actual_paths = actual.split(":") if label.startswith("list") else [actual] + path_list = label.startswith("list") or label == "absolute-list" + configured_paths = configured.split(":") if path_list else [configured] + actual_paths = actual.split(":") if path_list else [actual] expected = [Path(path.replace("$ORIGIN", str(output.parent))).resolve() for path in configured_paths] resolved = [Path(path.replace("$ORIGIN", str(artifact.parent))).resolve() for path in actual_paths] - if resolved != expected or (label == "absolute" and actual != run_path): + if resolved != expected or (label.startswith("absolute") and actual != run_path): failures.append((str(relative), label, actual, str(resolved), str(expected))) checked += 1 + for index, run_path in enumerate(("relative/libs", "C:/host/libs", "C:\\host\\libs", "\\\\server\\share")): + output = work / f"invalid-{index}.elf" + result = subprocess.run([str(relinker), "--rpath", run_path, str(source), str(output)], + capture_output=True, text=True, timeout=20) + assert result.returncode == 2 and "run path must be absolute or begin with $ORIGIN" in result.stderr, ( + run_path, result.returncode, result.stdout, result.stderr) + assert not output.exists() assert not failures, failures print(f"Guest run path tests passed: {checked} module/path combinations")