aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorWANG Xuerui <xen0n@gentoo.org>2022-10-09 14:08:13 +0800
committerLaurent Vivier <laurent@vivier.eu>2022-10-21 17:46:19 +0200
commit35a2c85f7d691db7aa2c47181902ac87478eef7a (patch)
tree8cf02bc95d6d1b5cbc01f1701fe33bd275e739e3 /linux-user
parented98cdecf8dabce137f693641777503112d884b3 (diff)
linux-user: Implement faccessat2
User space has been preferring this syscall for a while, due to its closer match with C semantics, and newer platforms such as LoongArch apparently have libc implementations that don't fallback to faccessat so normal access checks are failing without the emulation in place. Tested by successfully emerging several packages within a Gentoo loong stage3 chroot, emulated on amd64 with help of static qemu-loongarch64. Reported-by: Andreas K. Hüttel <dilfridge@gentoo.org> Signed-off-by: WANG Xuerui <xen0n@gentoo.org> Message-Id: <20221009060813.2289077-1-xen0n@gentoo.org> [lv: removing defined(__NR_faccessat2) in syscall.c, adding defined(TARGET_NR_faccessat2) on print_faccessat()] Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/strace.c2
-rw-r--r--linux-user/strace.list3
-rw-r--r--linux-user/syscall.c9
3 files changed, 13 insertions, 1 deletions
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 86c081c83f..9ae5a812cd 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -1969,7 +1969,7 @@ print_execv(CPUArchState *cpu_env, const struct syscallname *name,
}
#endif
-#ifdef TARGET_NR_faccessat
+#if defined(TARGET_NR_faccessat) || defined(TARGET_NR_faccessat2)
static void
print_faccessat(CPUArchState *cpu_env, const struct syscallname *name,
abi_long arg0, abi_long arg1, abi_long arg2,
diff --git a/linux-user/strace.list b/linux-user/strace.list
index a87415bf3d..3df2184580 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -178,6 +178,9 @@
#ifdef TARGET_NR_faccessat
{ TARGET_NR_faccessat, "faccessat" , NULL, print_faccessat, NULL },
#endif
+#ifdef TARGET_NR_faccessat2
+{ TARGET_NR_faccessat2, "faccessat2" , NULL, print_faccessat, NULL },
+#endif
#ifdef TARGET_NR_fadvise64
{ TARGET_NR_fadvise64, "fadvise64" , NULL, NULL, NULL },
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d499cac1d5..e985ad167f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -9143,6 +9143,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0);
return ret;
#endif
+#if defined(TARGET_NR_faccessat2)
+ case TARGET_NR_faccessat2:
+ if (!(p = lock_user_string(arg2))) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(faccessat(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
+ return ret;
+#endif
#ifdef TARGET_NR_nice /* not on alpha */
case TARGET_NR_nice:
return get_errno(nice(arg1));