diff options
author | Jameson Nash <vtjnash@gmail.com> | 2022-08-08 15:07:27 -0400 |
---|---|---|
committer | Laurent Vivier <laurent@vivier.eu> | 2022-09-23 23:43:45 +0200 |
commit | 65d4830dac7d88059ba77f1d31ec0c2f8f65ae28 (patch) | |
tree | b2915eabfad82a00d976c5e89615a1a2232c4616 /linux-user/syscall.c | |
parent | d135f781405f7c78153aa65e0327b05a4aa72e50 (diff) | |
download | qemu-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.c | 15 |
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)); } |