Fix self extracting binaries under qemu linux-user (qemu-$ARCH-static)

The problem was that the decompressor uses realpath(/proc/self/exe)
instead of readlink(/proc/self/exe), while realpath() does lots of
trickerly [1] which leads to bypassing qemu linux-user override [2] of
/proc/self/exe to the executable with with it had been called -- and
the reason for this is that the getpid() after unshare returns 1, while
reading /proc/self returns the pid that was before unshare (from the
chroot) [3].

  [1]: 4290aed051/stdlib/canonicalize.c (L223)
  [2]: ed8ad9728a/linux-user/syscall.c (L8634)
  [3]: https://gist.github.com/azat/fcbd8b6c26afd505ae5f3387fc15f0e2

But note, that even after this patch qemu without binfmt will not work,
due to internally the code calls execv() while qemu does not handle it
(see [4]).

  [4]: https://patchwork.kernel.org/project/qemu-devel/patch/1453091602-21843-1-git-send-email-petrosagg@gmail.com/

Signed-off-by: Azat Khuzhin <a.khuzhin@semrush.com>
This commit is contained in:
Azat Khuzhin 2023-07-17 12:09:11 +02:00
parent 16165d9498
commit 1fb7605fb4

View File

@ -362,11 +362,12 @@ int decompressFiles(int input_fd, char * path, char * name, bool & have_compress
#else
int read_exe_path(char *exe, size_t/* buf_sz*/)
int read_exe_path(char *exe, size_t buf_sz)
{
if (realpath("/proc/self/exe", exe) == nullptr)
return 1;
return 0;
ssize_t n = readlink("/proc/self/exe", exe, buf_sz - 1);
if (n > 0)
exe[n] = '\0';
return n > 0 && n < static_cast<ssize_t>(buf_sz);
}
#endif