From 76b1051b648aeb872303209ba3b81f04aa31e45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C5=8Dshin?= Date: Mon, 6 May 2024 20:40:00 -0700 Subject: [PATCH] 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`.) --- ape/ape-m1.c | 2 +- ape/loader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ape/ape-m1.c b/ape/ape-m1.c index 4eadb2eaa..9912adefc 100644 --- a/ape/ape-m1.c +++ b/ape/ape-m1.c @@ -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; } diff --git a/ape/loader.c b/ape/loader.c index 26ce3f94e..912db4ca2 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -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; }