From: Helge Deller <deller@kernel.org>
To: qemu-devel@nongnu.org
Cc: deller@gmx.de, Laurent Vivier <laurent@vivier.eu>,
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Subject: [PULL 1/4] linux-user: Fix AT_EXECFN in AUXV for symlinked programs
Date: Tue, 19 May 2026 16:05:28 +0200 [thread overview]
Message-ID: <20260519140531.11931-2-deller@kernel.org> (raw)
In-Reply-To: <20260519140531.11931-1-deller@kernel.org>
From: Helge Deller <deller@gmx.de>
The AT_EXECFN entry in AUXV needs to keep the value which was used when
the program was started. Especially for symlinked programs qemu should
not try to resolve the realpath.
Here is a reproducer:
(arm64-chroot)root@p100:/# cd /usr/bin
(arm64-chroot)root@p100:/usr/bin# ln -s echo testprog
(arm64-chroot)root@p100:/usr/bin# LD_SHOW_AUXV=1 ./testprog | grep AT_EXECFN
AT_EXECFN: ./testprog
In this example, "./testprog" is the correct output, and not "/usr/bin/echo".
This patch fixes parts of commit 258bec39 ("linux-user: Fix access to
/proc/self/exe").
Fixes: 258bec39 ("linux-user: Fix access to /proc/self/exe")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3379
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/main.c | 6 ++++--
linux-user/syscall.c | 14 +++++++-------
linux-user/user-internals.h | 1 +
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 86d04cca3c..c08c73fd80 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -772,8 +772,10 @@ int main(int argc, char **argv, char **envp)
}
/* Resolve executable file name to full path name */
- if (realpath(exec_path, real_exec_path)) {
- exec_path = real_exec_path;
+ /* Keep how we started the program in exec_path, e.g. "./my_program" */
+ /* Store real path in real_exec_path, e.g. "/usr/local/bin/my_program" */
+ if (!realpath(exec_path, real_exec_path)) {
+ printf("Could not resolve %s\n", exec_path);
}
/*
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d3d9fffb54..65bbeb8551 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8790,9 +8790,9 @@ static int maybe_do_fake_open(CPUArchState *cpu_env, int dirfd,
return -1;
}
if (safe) {
- return safe_openat(dirfd, exec_path, flags, mode);
+ return safe_openat(dirfd, real_exec_path, flags, mode);
} else {
- return openat(dirfd, exec_path, flags, mode);
+ return openat(dirfd, real_exec_path, flags, mode);
}
}
@@ -8929,9 +8929,9 @@ ssize_t do_guest_readlink(const char *pathname, char *buf, size_t bufsiz)
* Don't worry about sign mismatch as earlier mapping
* logic would have thrown a bad address error.
*/
- ret = MIN(strlen(exec_path), bufsiz);
+ ret = MIN(strlen(real_exec_path), bufsiz);
/* We cannot NUL terminate the string. */
- memcpy(buf, exec_path, ret);
+ memcpy(buf, real_exec_path, ret);
} else {
ret = readlink(path(pathname), buf, bufsiz);
}
@@ -9022,7 +9022,7 @@ static int do_execv(CPUArchState *cpu_env, int dirfd,
const char *exe = p;
if (is_proc_myself(p, "exe")) {
- exe = exec_path;
+ exe = real_exec_path;
}
ret = is_execveat
? safe_execveat(dirfd, exe, argp, envp, flags)
@@ -11033,9 +11033,9 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
* Don't worry about sign mismatch as earlier mapping
* logic would have thrown a bad address error.
*/
- ret = MIN(strlen(exec_path), arg4);
+ ret = MIN(strlen(real_exec_path), arg4);
/* We cannot NUL terminate the string. */
- memcpy(p2, exec_path, ret);
+ memcpy(p2, real_exec_path, ret);
} else {
ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
}
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index e65373b204..21daf422b7 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -24,6 +24,7 @@
#include "exec/translation-block.h"
extern char *exec_path;
+extern char real_exec_path[PATH_MAX];
void init_task_state(TaskState *ts);
void task_settid(TaskState *);
void stop_all_tasks(void);
--
2.54.0
next prev parent reply other threads:[~2026-05-19 14:06 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-19 14:05 [PULL 0/4] Linux user next patches Helge Deller
2026-05-19 14:05 ` Helge Deller [this message]
2026-05-19 14:05 ` [PULL 2/4] linux-user/sh4: Fix target_ucontext tuc_link field type Helge Deller
2026-05-19 14:05 ` [PULL 3/4] linux-user/sh4: Fix setup_sigtramp to match Linux kernel trampoline pattern Helge Deller
2026-05-19 14:05 ` [PULL 4/4] linux-user: Fix a memory leak when pthread_create fails Helge Deller
2026-05-19 20:51 ` [PULL 0/4] Linux user next patches Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260519140531.11931-2-deller@kernel.org \
--to=deller@kernel.org \
--cc=deller@gmx.de \
--cc=laurent@vivier.eu \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.