aboutsummaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorJameson Nash <vtjnash@gmail.com>2022-08-08 15:07:27 -0400
committerLaurent Vivier <laurent@vivier.eu>2022-09-23 23:43:45 +0200
commit65d4830dac7d88059ba77f1d31ec0c2f8f65ae28 (patch)
treeb2915eabfad82a00d976c5e89615a1a2232c4616 /linux-user/syscall.c
parentd135f781405f7c78153aa65e0327b05a4aa72e50 (diff)
downloadqemu-65d4830dac7d88059ba77f1d31ec0c2f8f65ae28.zip
qemu-65d4830dac7d88059ba77f1d31ec0c2f8f65ae28.tar.gz
qemu-65d4830dac7d88059ba77f1d31ec0c2f8f65ae28.tar.bz2
linux-user: fix readlinkat handling with magic exe symlink
Exactly the same as f17f4989fa193fa8279474c5462289a3cfe69aea before was for readlink. I suppose this was simply missed at the time. Signed-off-by: Jameson Nash <vtjnash@gmail.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220808190727.875155-1-vtjnash@gmail.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f409121..abf82ba 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9912,11 +9912,22 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
if (!p || !p2) {
ret = -TARGET_EFAULT;
+ } else if (!arg4) {
+ /* Short circuit this for the magic exe check. */
+ ret = -TARGET_EINVAL;
} else if (is_proc_myself((const char *)p, "exe")) {
char real[PATH_MAX], *temp;
temp = realpath(exec_path, real);
- ret = temp == NULL ? get_errno(-1) : strlen(real) ;
- snprintf((char *)p2, arg4, "%s", real);
+ /* Return value is # of bytes that we wrote to the buffer. */
+ if (temp == NULL) {
+ ret = get_errno(-1);
+ } else {
+ /* Don't worry about sign mismatch as earlier mapping
+ * logic would have thrown a bad address error. */
+ ret = MIN(strlen(real), arg4);
+ /* We cannot NUL terminate the string. */
+ memcpy(p2, real, ret);
+ }
} else {
ret = get_errno(readlinkat(arg1, path(p), p2, arg4));
}