strace/SOURCES/0144-tests-check-decoding-of-faccessat-syscall-in-P-y-and.patch
2021-09-22 09:09:53 +00:00

796 lines
24 KiB
Diff

From e244ae965b17280313d92baef71165efc00ac51b Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@altlinux.org>
Date: Sat, 4 Jul 2020 08:00:00 +0000
Subject: [PATCH 144/149] tests: check decoding of faccessat syscall in -P, -y,
and -yy modes
* tests/faccessat.c: Rewrite.
* tests/faccessat-P.c: New file.
* tests/faccessat-y.c: Likewise.
* tests/faccessat-yy.c: Likewise.
* tests/faccessat.test: New test.
* tests/Makefile.am (DECODER_TESTS): Add faccessat.test.
* tests/gen_tests.in (faccessat): Remove.
(faccessat-P, faccessat-y, faccessat-yy): New entries.
* tests/pure_executables.list: Add faccessat-P, faccessat-y,
and faccessat-yy.
* tests/.gitignore: Likewise.
---
tests/.gitignore | 3 ++
tests/Makefile.am | 1 +
tests/faccessat-P.c | 4 ++
tests/faccessat-y.c | 4 ++
tests/faccessat-yy.c | 4 ++
tests/faccessat.c | 127 ++++++++++++++++++++++++++++++++++++++++++--
tests/faccessat.test | 19 +++++++
tests/gen_tests.in | 4 +-
tests/pure_executables.list | 3 ++
9 files changed, 163 insertions(+), 6 deletions(-)
create mode 100644 tests/faccessat-P.c
create mode 100644 tests/faccessat-y.c
create mode 100644 tests/faccessat-yy.c
create mode 100755 tests/faccessat.test
Index: strace-5.7/tests/Makefile.am
===================================================================
--- strace-5.7.orig/tests/Makefile.am 2021-08-24 19:42:16.041519983 +0200
+++ strace-5.7/tests/Makefile.am 2021-08-24 19:46:08.275554370 +0200
@@ -346,6 +346,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \
Index: strace-5.7/tests/faccessat-P.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests/faccessat-P.c 2021-08-24 19:46:08.275554370 +0200
@@ -0,0 +1,4 @@
+#define PATH_TRACING
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests/faccessat-y.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests/faccessat-y.c 2021-08-24 19:46:08.276554362 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests/faccessat-yy.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests/faccessat-yy.c 2021-08-24 19:46:08.276554362 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full<char 1:7>>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests/faccessat.c
===================================================================
--- strace-5.7.orig/tests/faccessat.c 2021-08-24 17:01:53.365934740 +0200
+++ strace-5.7/tests/faccessat.c 2021-08-24 19:46:08.277554353 +0200
@@ -1,4 +1,6 @@
/*
+ * Check decoding of faccessat syscall.
+ *
* Copyright (c) 2016-2019 The strace developers.
* All rights reserved.
*
@@ -10,18 +12,133 @@
#ifdef __NR_faccessat
+# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
+# ifndef FD_PATH
+# define FD_PATH ""
+# endif
+# ifndef SKIP_IF_PROC_IS_UNAVAILABLE
+# define SKIP_IF_PROC_IS_UNAVAILABLE
+# endif
+
+static const char *errstr;
+
+static long
+k_faccessat(const unsigned int dirfd,
+ const void *const pathname,
+ const unsigned int mode)
+{
+ const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+
+ const kernel_ulong_t arg1 = fill | dirfd;
+ const kernel_ulong_t arg2 = (uintptr_t) pathname;
+ const kernel_ulong_t arg3 = fill | mode;
+ const long rc = syscall(__NR_faccessat,
+ arg1, arg2, arg3, bad, bad, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
int
main(void)
{
- static const char sample[] = "faccessat.sample";
- const long int fd = (long int) 0xdeadbeefffffffffULL;
+ SKIP_IF_PROC_IS_UNAVAILABLE;
- long rc = syscall(__NR_faccessat, fd, sample, F_OK);
- printf("faccessat(%d, \"%s\", F_OK) = %ld %s (%m)\n",
- (int) fd, sample, rc, errno2name());
+ TAIL_ALLOC_OBJECT_CONST_PTR(const char, unterminated);
+ char *unterminated_str;
+ if (asprintf(&unterminated_str, "%p", unterminated) < 0)
+ perror_msg_and_fail("asprintf");
+ const void *const efault = unterminated + 1;
+ char *efault_str;
+ if (asprintf(&efault_str, "%p", efault) < 0)
+ perror_msg_and_fail("asprintf");
+
+ typedef struct {
+ char sym;
+ char null;
+ } sym_null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, dot);
+ dot->sym = '.';
+ dot->null = '\0';
+ const char *const null = &dot->null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, slash);
+ slash->sym = '/';
+ slash->null = '\0';
+
+ static const char path[] = "/dev/full";
+ const char *const fd_path = tail_memdup(path, sizeof(path));
+ int fd = open(path, O_WRONLY);
+ if (fd < 0)
+ perror_msg_and_fail("open: %s", path);
+ char *fd_str;
+ if (asprintf(&fd_str, "%d%s", fd, FD_PATH) < 0)
+ perror_msg_and_fail("asprintf");
+ char *path_quoted;
+ if (asprintf(&path_quoted, "\"%s\"", path) < 0)
+ perror_msg_and_fail("asprintf");
+
+ struct {
+ int val;
+ const char *str;
+ } dirfds[] = {
+ { ARG_STR(-1) },
+ { -100, "AT_FDCWD" },
+ { fd, fd_str },
+ }, modes[] = {
+ { ARG_STR(F_OK) },
+ { ARG_STR(R_OK) },
+ { ARG_STR(W_OK) },
+ { ARG_STR(X_OK) },
+ { ARG_STR(R_OK|W_OK) },
+ { ARG_STR(R_OK|X_OK) },
+ { ARG_STR(W_OK|X_OK) },
+ { ARG_STR(R_OK|W_OK|X_OK) },
+ { 8, "0x8 /* ?_OK */" },
+ { -1, "R_OK|W_OK|X_OK|0xfffffff8" },
+ };
+
+ struct {
+ const void *val;
+ const char *str;
+ } paths[] = {
+ { 0, "NULL" },
+ { efault, efault_str },
+ { unterminated, unterminated_str },
+ { null, "\"\"" },
+ { &dot->sym, "\".\"" },
+ { &slash->sym, "\"/\"" },
+ { fd_path, path_quoted },
+ };
+
+ for (unsigned int dirfd_i = 0;
+ dirfd_i < ARRAY_SIZE(dirfds);
+ ++dirfd_i) {
+ for (unsigned int path_i = 0;
+ path_i < ARRAY_SIZE(paths);
+ ++path_i) {
+ for (unsigned int mode_i = 0;
+ mode_i < ARRAY_SIZE(modes);
+ ++mode_i) {
+ k_faccessat(dirfds[dirfd_i].val,
+ paths[path_i].val,
+ modes[mode_i].val);
+# ifdef PATH_TRACING
+ if (dirfds[dirfd_i].val == fd ||
+ paths[path_i].val == fd_path)
+# endif
+ printf("faccessat(%s, %s, %s) = %s\n",
+ dirfds[dirfd_i].str,
+ paths[path_i].str,
+ modes[mode_i].str,
+ errstr);
+ }
+ }
+ }
puts("+++ exited with 0 +++");
return 0;
Index: strace-5.7/tests/faccessat.test
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests/faccessat.test 2021-08-24 19:46:08.277554353 +0200
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Check decoding of faccessat syscall.
+#
+# Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog sed
+
+run_prog > /dev/null
+run_strace -a23 --trace=faccessat "$@" $args > "$EXP"
+
+# Filter out faccessat() calls made by ld.so and libc.
+sed -n '/^faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
Index: strace-5.7/tests/gen_tests.in
===================================================================
--- strace-5.7.orig/tests/gen_tests.in 2021-08-24 19:37:43.192829355 +0200
+++ strace-5.7/tests/gen_tests.in 2021-08-24 19:46:08.278554345 +0200
@@ -73,7 +73,9 @@
erestartsys -a34 -e signal=none -e trace=recvfrom
execveat
execveat-v -v -e trace=execveat
-faccessat -P $NAME.sample
+faccessat-P -a23 --trace=faccessat -P /dev/full
+faccessat-y +faccessat.test -a24 -y
+faccessat-yy +faccessat.test -a24 -yy
fadvise64_64 +fadvise64.test
fallocate -a18
fanotify_init
Index: strace-5.7/tests/pure_executables.list
===================================================================
--- strace-5.7.orig/tests/pure_executables.list 2021-08-24 19:37:43.192829355 +0200
+++ strace-5.7/tests/pure_executables.list 2021-08-24 19:46:08.279554336 +0200
@@ -61,6 +61,9 @@
execve
execveat
faccessat
+faccessat-P
+faccessat-y
+faccessat-yy
fadvise64
fadvise64_64
fallocate
Index: strace-5.7/tests-m32/Makefile.am
===================================================================
--- strace-5.7.orig/tests-m32/Makefile.am 2021-08-24 19:42:16.045519949 +0200
+++ strace-5.7/tests-m32/Makefile.am 2021-08-24 19:46:08.279554336 +0200
@@ -346,6 +346,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \
Index: strace-5.7/tests-m32/faccessat-P.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-m32/faccessat-P.c 2021-08-24 19:46:08.279554336 +0200
@@ -0,0 +1,4 @@
+#define PATH_TRACING
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-m32/faccessat-y.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-m32/faccessat-y.c 2021-08-24 19:46:08.280554328 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-m32/faccessat-yy.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-m32/faccessat-yy.c 2021-08-24 19:46:08.280554328 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full<char 1:7>>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-m32/faccessat.c
===================================================================
--- strace-5.7.orig/tests-m32/faccessat.c 2019-09-25 03:02:03.000000000 +0200
+++ strace-5.7/tests-m32/faccessat.c 2021-08-24 19:46:08.281554319 +0200
@@ -1,4 +1,6 @@
/*
+ * Check decoding of faccessat syscall.
+ *
* Copyright (c) 2016-2019 The strace developers.
* All rights reserved.
*
@@ -10,18 +12,133 @@
#ifdef __NR_faccessat
+# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
+# ifndef FD_PATH
+# define FD_PATH ""
+# endif
+# ifndef SKIP_IF_PROC_IS_UNAVAILABLE
+# define SKIP_IF_PROC_IS_UNAVAILABLE
+# endif
+
+static const char *errstr;
+
+static long
+k_faccessat(const unsigned int dirfd,
+ const void *const pathname,
+ const unsigned int mode)
+{
+ const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+
+ const kernel_ulong_t arg1 = fill | dirfd;
+ const kernel_ulong_t arg2 = (uintptr_t) pathname;
+ const kernel_ulong_t arg3 = fill | mode;
+ const long rc = syscall(__NR_faccessat,
+ arg1, arg2, arg3, bad, bad, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
int
main(void)
{
- static const char sample[] = "faccessat.sample";
- const long int fd = (long int) 0xdeadbeefffffffffULL;
+ SKIP_IF_PROC_IS_UNAVAILABLE;
- long rc = syscall(__NR_faccessat, fd, sample, F_OK);
- printf("faccessat(%d, \"%s\", F_OK) = %ld %s (%m)\n",
- (int) fd, sample, rc, errno2name());
+ TAIL_ALLOC_OBJECT_CONST_PTR(const char, unterminated);
+ char *unterminated_str;
+ if (asprintf(&unterminated_str, "%p", unterminated) < 0)
+ perror_msg_and_fail("asprintf");
+ const void *const efault = unterminated + 1;
+ char *efault_str;
+ if (asprintf(&efault_str, "%p", efault) < 0)
+ perror_msg_and_fail("asprintf");
+
+ typedef struct {
+ char sym;
+ char null;
+ } sym_null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, dot);
+ dot->sym = '.';
+ dot->null = '\0';
+ const char *const null = &dot->null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, slash);
+ slash->sym = '/';
+ slash->null = '\0';
+
+ static const char path[] = "/dev/full";
+ const char *const fd_path = tail_memdup(path, sizeof(path));
+ int fd = open(path, O_WRONLY);
+ if (fd < 0)
+ perror_msg_and_fail("open: %s", path);
+ char *fd_str;
+ if (asprintf(&fd_str, "%d%s", fd, FD_PATH) < 0)
+ perror_msg_and_fail("asprintf");
+ char *path_quoted;
+ if (asprintf(&path_quoted, "\"%s\"", path) < 0)
+ perror_msg_and_fail("asprintf");
+
+ struct {
+ int val;
+ const char *str;
+ } dirfds[] = {
+ { ARG_STR(-1) },
+ { -100, "AT_FDCWD" },
+ { fd, fd_str },
+ }, modes[] = {
+ { ARG_STR(F_OK) },
+ { ARG_STR(R_OK) },
+ { ARG_STR(W_OK) },
+ { ARG_STR(X_OK) },
+ { ARG_STR(R_OK|W_OK) },
+ { ARG_STR(R_OK|X_OK) },
+ { ARG_STR(W_OK|X_OK) },
+ { ARG_STR(R_OK|W_OK|X_OK) },
+ { 8, "0x8 /* ?_OK */" },
+ { -1, "R_OK|W_OK|X_OK|0xfffffff8" },
+ };
+
+ struct {
+ const void *val;
+ const char *str;
+ } paths[] = {
+ { 0, "NULL" },
+ { efault, efault_str },
+ { unterminated, unterminated_str },
+ { null, "\"\"" },
+ { &dot->sym, "\".\"" },
+ { &slash->sym, "\"/\"" },
+ { fd_path, path_quoted },
+ };
+
+ for (unsigned int dirfd_i = 0;
+ dirfd_i < ARRAY_SIZE(dirfds);
+ ++dirfd_i) {
+ for (unsigned int path_i = 0;
+ path_i < ARRAY_SIZE(paths);
+ ++path_i) {
+ for (unsigned int mode_i = 0;
+ mode_i < ARRAY_SIZE(modes);
+ ++mode_i) {
+ k_faccessat(dirfds[dirfd_i].val,
+ paths[path_i].val,
+ modes[mode_i].val);
+# ifdef PATH_TRACING
+ if (dirfds[dirfd_i].val == fd ||
+ paths[path_i].val == fd_path)
+# endif
+ printf("faccessat(%s, %s, %s) = %s\n",
+ dirfds[dirfd_i].str,
+ paths[path_i].str,
+ modes[mode_i].str,
+ errstr);
+ }
+ }
+ }
puts("+++ exited with 0 +++");
return 0;
Index: strace-5.7/tests-m32/faccessat.test
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-m32/faccessat.test 2021-08-24 19:46:08.281554319 +0200
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Check decoding of faccessat syscall.
+#
+# Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog sed
+
+run_prog > /dev/null
+run_strace -a23 --trace=faccessat "$@" $args > "$EXP"
+
+# Filter out faccessat() calls made by ld.so and libc.
+sed -n '/^faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
Index: strace-5.7/tests-m32/gen_tests.in
===================================================================
--- strace-5.7.orig/tests-m32/gen_tests.in 2021-08-24 19:37:43.193829347 +0200
+++ strace-5.7/tests-m32/gen_tests.in 2021-08-24 19:46:08.282554311 +0200
@@ -73,7 +73,9 @@
erestartsys -a34 -e signal=none -e trace=recvfrom
execveat
execveat-v -v -e trace=execveat
-faccessat -P $NAME.sample
+faccessat-P -a23 --trace=faccessat -P /dev/full
+faccessat-y +faccessat.test -a24 -y
+faccessat-yy +faccessat.test -a24 -yy
fadvise64_64 +fadvise64.test
fallocate -a18
fanotify_init
Index: strace-5.7/tests-m32/pure_executables.list
===================================================================
--- strace-5.7.orig/tests-m32/pure_executables.list 2021-08-24 19:37:43.193829347 +0200
+++ strace-5.7/tests-m32/pure_executables.list 2021-08-24 19:46:08.283554302 +0200
@@ -61,6 +61,9 @@
execve
execveat
faccessat
+faccessat-P
+faccessat-y
+faccessat-yy
fadvise64
fadvise64_64
fallocate
Index: strace-5.7/tests-mx32/Makefile.am
===================================================================
--- strace-5.7.orig/tests-mx32/Makefile.am 2021-08-24 19:42:16.048519924 +0200
+++ strace-5.7/tests-mx32/Makefile.am 2021-08-24 19:46:08.283554302 +0200
@@ -346,6 +346,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \
Index: strace-5.7/tests-mx32/faccessat-P.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-mx32/faccessat-P.c 2021-08-24 19:46:08.283554302 +0200
@@ -0,0 +1,4 @@
+#define PATH_TRACING
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-mx32/faccessat-y.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-mx32/faccessat-y.c 2021-08-24 19:46:08.284554294 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-mx32/faccessat-yy.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-mx32/faccessat-yy.c 2021-08-24 19:46:08.284554294 +0200
@@ -0,0 +1,4 @@
+#define FD_PATH "</dev/full<char 1:7>>"
+#define SKIP_IF_PROC_IS_UNAVAILABLE skip_if_unavailable("/proc/self/fd/")
+
+#include "faccessat.c"
Index: strace-5.7/tests-mx32/faccessat.c
===================================================================
--- strace-5.7.orig/tests-mx32/faccessat.c 2019-09-25 03:02:03.000000000 +0200
+++ strace-5.7/tests-mx32/faccessat.c 2021-08-24 19:46:08.285554285 +0200
@@ -1,4 +1,6 @@
/*
+ * Check decoding of faccessat syscall.
+ *
* Copyright (c) 2016-2019 The strace developers.
* All rights reserved.
*
@@ -10,18 +12,133 @@
#ifdef __NR_faccessat
+# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
+# ifndef FD_PATH
+# define FD_PATH ""
+# endif
+# ifndef SKIP_IF_PROC_IS_UNAVAILABLE
+# define SKIP_IF_PROC_IS_UNAVAILABLE
+# endif
+
+static const char *errstr;
+
+static long
+k_faccessat(const unsigned int dirfd,
+ const void *const pathname,
+ const unsigned int mode)
+{
+ const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
+ const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
+
+ const kernel_ulong_t arg1 = fill | dirfd;
+ const kernel_ulong_t arg2 = (uintptr_t) pathname;
+ const kernel_ulong_t arg3 = fill | mode;
+ const long rc = syscall(__NR_faccessat,
+ arg1, arg2, arg3, bad, bad, bad);
+ errstr = sprintrc(rc);
+ return rc;
+}
+
int
main(void)
{
- static const char sample[] = "faccessat.sample";
- const long int fd = (long int) 0xdeadbeefffffffffULL;
+ SKIP_IF_PROC_IS_UNAVAILABLE;
- long rc = syscall(__NR_faccessat, fd, sample, F_OK);
- printf("faccessat(%d, \"%s\", F_OK) = %ld %s (%m)\n",
- (int) fd, sample, rc, errno2name());
+ TAIL_ALLOC_OBJECT_CONST_PTR(const char, unterminated);
+ char *unterminated_str;
+ if (asprintf(&unterminated_str, "%p", unterminated) < 0)
+ perror_msg_and_fail("asprintf");
+ const void *const efault = unterminated + 1;
+ char *efault_str;
+ if (asprintf(&efault_str, "%p", efault) < 0)
+ perror_msg_and_fail("asprintf");
+
+ typedef struct {
+ char sym;
+ char null;
+ } sym_null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, dot);
+ dot->sym = '.';
+ dot->null = '\0';
+ const char *const null = &dot->null;
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(sym_null, slash);
+ slash->sym = '/';
+ slash->null = '\0';
+
+ static const char path[] = "/dev/full";
+ const char *const fd_path = tail_memdup(path, sizeof(path));
+ int fd = open(path, O_WRONLY);
+ if (fd < 0)
+ perror_msg_and_fail("open: %s", path);
+ char *fd_str;
+ if (asprintf(&fd_str, "%d%s", fd, FD_PATH) < 0)
+ perror_msg_and_fail("asprintf");
+ char *path_quoted;
+ if (asprintf(&path_quoted, "\"%s\"", path) < 0)
+ perror_msg_and_fail("asprintf");
+
+ struct {
+ int val;
+ const char *str;
+ } dirfds[] = {
+ { ARG_STR(-1) },
+ { -100, "AT_FDCWD" },
+ { fd, fd_str },
+ }, modes[] = {
+ { ARG_STR(F_OK) },
+ { ARG_STR(R_OK) },
+ { ARG_STR(W_OK) },
+ { ARG_STR(X_OK) },
+ { ARG_STR(R_OK|W_OK) },
+ { ARG_STR(R_OK|X_OK) },
+ { ARG_STR(W_OK|X_OK) },
+ { ARG_STR(R_OK|W_OK|X_OK) },
+ { 8, "0x8 /* ?_OK */" },
+ { -1, "R_OK|W_OK|X_OK|0xfffffff8" },
+ };
+
+ struct {
+ const void *val;
+ const char *str;
+ } paths[] = {
+ { 0, "NULL" },
+ { efault, efault_str },
+ { unterminated, unterminated_str },
+ { null, "\"\"" },
+ { &dot->sym, "\".\"" },
+ { &slash->sym, "\"/\"" },
+ { fd_path, path_quoted },
+ };
+
+ for (unsigned int dirfd_i = 0;
+ dirfd_i < ARRAY_SIZE(dirfds);
+ ++dirfd_i) {
+ for (unsigned int path_i = 0;
+ path_i < ARRAY_SIZE(paths);
+ ++path_i) {
+ for (unsigned int mode_i = 0;
+ mode_i < ARRAY_SIZE(modes);
+ ++mode_i) {
+ k_faccessat(dirfds[dirfd_i].val,
+ paths[path_i].val,
+ modes[mode_i].val);
+# ifdef PATH_TRACING
+ if (dirfds[dirfd_i].val == fd ||
+ paths[path_i].val == fd_path)
+# endif
+ printf("faccessat(%s, %s, %s) = %s\n",
+ dirfds[dirfd_i].str,
+ paths[path_i].str,
+ modes[mode_i].str,
+ errstr);
+ }
+ }
+ }
puts("+++ exited with 0 +++");
return 0;
Index: strace-5.7/tests-mx32/faccessat.test
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ strace-5.7/tests-mx32/faccessat.test 2021-08-24 19:46:08.285554285 +0200
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Check decoding of faccessat syscall.
+#
+# Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog sed
+
+run_prog > /dev/null
+run_strace -a23 --trace=faccessat "$@" $args > "$EXP"
+
+# Filter out faccessat() calls made by ld.so and libc.
+sed -n '/^faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
Index: strace-5.7/tests-mx32/gen_tests.in
===================================================================
--- strace-5.7.orig/tests-mx32/gen_tests.in 2021-08-24 19:37:43.194829339 +0200
+++ strace-5.7/tests-mx32/gen_tests.in 2021-08-24 19:46:08.286554277 +0200
@@ -73,7 +73,9 @@
erestartsys -a34 -e signal=none -e trace=recvfrom
execveat
execveat-v -v -e trace=execveat
-faccessat -P $NAME.sample
+faccessat-P -a23 --trace=faccessat -P /dev/full
+faccessat-y +faccessat.test -a24 -y
+faccessat-yy +faccessat.test -a24 -yy
fadvise64_64 +fadvise64.test
fallocate -a18
fanotify_init
Index: strace-5.7/tests-mx32/pure_executables.list
===================================================================
--- strace-5.7.orig/tests-mx32/pure_executables.list 2021-08-24 19:37:43.195829330 +0200
+++ strace-5.7/tests-mx32/pure_executables.list 2021-08-24 19:46:08.286554277 +0200
@@ -61,6 +61,9 @@
execve
execveat
faccessat
+faccessat-P
+faccessat-y
+faccessat-yy
fadvise64
fadvise64_64
fallocate
Index: strace-5.7/tests/Makefile.in
===================================================================
--- strace-5.7.orig/tests/Makefile.in 2021-08-24 19:42:54.720192609 +0200
+++ strace-5.7/tests/Makefile.in 2021-08-24 19:46:08.292554226 +0200
@@ -6523,6 +6523,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \
Index: strace-5.7/tests-m32/Makefile.in
===================================================================
--- strace-5.7.orig/tests-m32/Makefile.in 2021-08-24 19:43:13.669032228 +0200
+++ strace-5.7/tests-m32/Makefile.in 2021-08-24 19:46:08.296554192 +0200
@@ -6523,6 +6523,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \
Index: strace-5.7/tests-mx32/Makefile.in
===================================================================
--- strace-5.7.orig/tests-mx32/Makefile.in 2021-08-24 19:43:32.469873099 +0200
+++ strace-5.7/tests-mx32/Makefile.in 2021-08-24 19:46:08.299554167 +0200
@@ -6523,6 +6523,7 @@
execve-v.test \
execve.test \
fadvise64.test \
+ faccessat.test \
futex.test \
getuid.test \
int_0x80.test \