Do not modify argv[0] if argc is 0

The `ape -` variant with no arguments provides no way to shim in argv[0]
so the loader had no way to tell the binary what its path was. This is a
long-standing bug that looks like it has existed for as long as `ape -`,
and old loaders would, I guess, just overwrite the sentinel NULL that is
by convention the beginning and the end of a zero-length argv.

From the vantage point of TryElf I can't see a really good solution so I
just check for argc of 0 and let things be weird if a binary is run like
that.

This is only relevant with older binaries (as of #1170, those that don't
set `EF_APE_MODERN`.)
This commit is contained in:
Jōshin 2024-05-06 20:40:00 -07:00
parent 736fc75965
commit 76b1051b64
No known key found for this signature in database
2 changed files with 2 additions and 2 deletions

View file

@ -821,7 +821,7 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
if (e->e_machine != EM_AARCH64) {
return "couldn't find ELF header with ARM64 machine type";
}
if (!(e->e_flags & EF_APE_MODERN)) {
if (!(e->e_flags & EF_APE_MODERN) && sp[0]) {
/* change argv[0] to resolved path for older binaries */
((char **)(sp + 1))[0] = exe;
}

View file

@ -835,7 +835,7 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf,
return "couldn't find ELF header with x86-64 machine type";
}
#endif
if (!(e->e_flags & EF_APE_MODERN)) {
if (!(e->e_flags & EF_APE_MODERN) && sp[0]) {
/* change argv[0] to resolved path for older binaries */
((char **)(sp + 1))[0] = exe;
}