Merge pull request #2605 from elsi06/fix/relinker-self-guest-modules
fix(relinker): reject guest modules in SELF containers
This commit is contained in:
commit
69e9a2685a
|
|
@ -70,7 +70,11 @@ std::vector<GuestArtifact> GuestModuleBuilder::Build(const std::filesystem::path
|
|||
char magic[4]{};
|
||||
stream.read(magic, 4);
|
||||
if (stream.bad()) throw Domain::RelinkerException("Cannot read guest candidate magic: " + path.string());
|
||||
return stream.gcount() == 4 && static_cast<unsigned char>(magic[0]) == 0x7f && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F';
|
||||
if (stream.gcount() != 4) return false;
|
||||
const auto byte = [&](const std::size_t index) { return static_cast<unsigned char>(magic[index]); };
|
||||
const bool self = (byte(0) == 0x4f && byte(1) == 0x15 && byte(2) == 0x3d && byte(3) == 0x1d) || (byte(0) == 0x54 && byte(1) == 0x14 && byte(2) == 0xf5 && byte(3) == 0xee);
|
||||
if (self) throw Domain::RelinkerException("Guest module is a SELF container, not an ELF: " + path.string());
|
||||
return byte(0) == 0x7f && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F';
|
||||
};
|
||||
for (const auto& directory : directories) {
|
||||
if (!std::filesystem::is_directory(directory)) throw Domain::RelinkerException("Guest module path is not a directory: " + directory.string());
|
||||
|
|
|
|||
|
|
@ -110,6 +110,20 @@ def main():
|
|||
assert result.returncode == 2 and "not a directory" in result.stderr, result.stderr
|
||||
assert not output.exists(), output
|
||||
|
||||
for magic in (b"\x4f\x15\x3d\x1d", b"\x54\x14\xf5\xee"):
|
||||
case = work / f"{windows}-self-{magic.hex()}"
|
||||
for name in ("sce_module", "prx"):
|
||||
(case / name).mkdir(parents=True)
|
||||
(case / "sce_module" / "libc.prx").write_bytes(magic + bytes(0x1000))
|
||||
(case / "prx" / "provider.prx").write_bytes(module_with_symbol(True))
|
||||
result, output = convert(case, windows)
|
||||
assert result.returncode == 2 and "Guest module is a SELF container, not an ELF" in result.stderr, result.stderr
|
||||
assert str(case / "sce_module" / "libc.prx") in result.stderr, result.stderr
|
||||
assert not output.exists() and not (case / "app0").exists(), output
|
||||
result, output = convert(case, windows, ["--exclude-sce-module", "libc.prx"])
|
||||
assert result.returncode == 0 and output.exists(), result.stderr
|
||||
assert {path.name for path in (case / "app0").rglob("*.guest.prx")} == {"provider.prx.guest.prx"}
|
||||
|
||||
case = work / f"{windows}-ambiguous"
|
||||
for name in ("sce_module", "sce_modules", "prx"):
|
||||
(case / name).mkdir(parents=True)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Input and conversion
|
||||
|
||||
Use a clean ELF executable. Place its bundled ELF modules in `sce_module/`, `sce_modules/`, or `prx/` beside the input executable. `prx/` can coexist with either `sce_module/` or `sce_modules/`. Both `sce_module/` and `sce_modules/` present, or all three absent, is an error.
|
||||
Use a clean ELF executable. Place its bundled ELF modules in `sce_module/`, `sce_modules/`, or `prx/` beside the input executable. A bundled module in a SELF container is an error, as the executable is. `prx/` can coexist with either `sce_module/` or `sce_modules/`. Both `sce_module/` and `sce_modules/` present, or all three absent, is an error.
|
||||
|
||||
```text
|
||||
source/
|
||||
|
|
|
|||
Loading…
Reference in New Issue