summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore5
-rw-r--r--tests/Makefile.am11
-rw-r--r--tests/access.c23
-rw-r--r--tests/chmod.c35
-rw-r--r--tests/execve.c53
-rwxr-xr-xtests/execve.test2
-rw-r--r--tests/execveat.c122
-rw-r--r--tests/faccessat.c137
-rwxr-xr-xtests/faccessat.test2
-rw-r--r--tests/fanotify_mark.c121
-rw-r--r--tests/fchmod.c23
-rw-r--r--tests/fchmodat.c67
-rw-r--r--tests/fchownat.c73
-rw-r--r--tests/file_handle.c204
-rwxr-xr-xtests/gen_secontext.sh72
-rw-r--r--tests/gen_tests.in30
-rw-r--r--tests/linkat.c150
-rw-r--r--tests/open.c18
-rw-r--r--tests/openat.c91
-rwxr-xr-xtests/options-syntax.test11
-rw-r--r--tests/secontext.c201
-rw-r--r--tests/secontext.h46
-rwxr-xr-xtests/strace-V.test4
23 files changed, 1309 insertions, 192 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index bed7c5b7f..6532542b5 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,3 +1,7 @@
+*--secontext
+*--secontext.c
+*--secontext_full
+*--secontext_full.c
*.dir
*.gen.test
*.log
@@ -711,6 +715,7 @@ seccomp-filter
seccomp-filter-v
seccomp-strict
seccomp_get_action_avail
+secontext.am
select
select-P
semop
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8327e84cf..cb6e7ef1c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -31,6 +31,12 @@ AM_CPPFLAGS = $(ARCH_MFLAGS) \
-DTESTS_SIZEOF_LONG=$(SIZEOF_LONG)
AM_LDFLAGS = $(ARCH_MFLAGS)
+if HAVE_SELINUX_RUNTIME
+libselinux_LDADD = $(libselinux_LIBS)
+else
+libselinux_LDADD =
+endif
+
libtests_a_SOURCES = \
create_nl_socket.c \
create_tmpfile.c \
@@ -57,6 +63,8 @@ libtests_a_SOURCES = \
printxval-Xabbrev.c \
printxval-Xraw.c \
printxval-Xverbose.c \
+ secontext.c \
+ secontext.h \
signal2name.c \
skip_unavailable.c \
sprintrc.c \
@@ -79,7 +87,10 @@ LDADD = libtests.a
include pure_executables.am
+include secontext.am
+
check_PROGRAMS = $(PURE_EXECUTABLES) \
+ $(secontext_EXECUTABLES) \
_newselect-P \
answer \
attach-f-p \
diff --git a/tests/access.c b/tests/access.c
index fe7e21d5b..5d37ba534 100644
--- a/tests/access.c
+++ b/tests/access.c
@@ -10,9 +10,12 @@
#ifdef __NR_access
+# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -22,15 +25,27 @@ main(void)
*/
create_and_enter_subdir("access_subdir");
+ char *my_secontext = SECONTEXT_PID_MY();
+
static const char sample[] = "access_sample";
+ (void) unlink(sample);
+ if (open(sample, O_CREAT|O_RDONLY, 0400) == -1)
+ perror_msg_and_fail("open: %s", sample);
long rc = syscall(__NR_access, sample, F_OK);
- printf("access(\"%s\", F_OK) = %ld %s (%m)\n",
- sample, rc, errno2name());
+ printf("%s%s(\"%s\"%s, F_OK) = %s\n",
+ my_secontext, "access",
+ sample, SECONTEXT_FILE(sample),
+ sprintrc(rc));
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink: %s", sample);
rc = syscall(__NR_access, sample, R_OK|W_OK|X_OK);
- printf("access(\"%s\", R_OK|W_OK|X_OK) = %ld %s (%m)\n",
- sample, rc, errno2name());
+ printf("%s%s(\"%s\", R_OK|W_OK|X_OK) = %s\n",
+ my_secontext, "access",
+ sample,
+ sprintrc(rc));
leave_and_remove_subdir();
diff --git a/tests/chmod.c b/tests/chmod.c
index 845e54aac..7d0ef5657 100644
--- a/tests/chmod.c
+++ b/tests/chmod.c
@@ -16,6 +16,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -25,22 +27,33 @@ main(void)
*/
create_and_enter_subdir("chmod_subdir");
- static const char fname[] = "chmod_test_file";
+ char *my_secontext = SECONTEXT_PID_MY();
- if (open(fname, O_CREAT|O_RDONLY, 0400) < 0)
- perror_msg_and_fail("open");
+ static const char sample[] = "chmod_test_file";
+ (void) unlink(sample);
+ if (open(sample, O_CREAT|O_RDONLY, 0400) < 0)
+ perror_msg_and_fail("open: %s", sample);
- long rc = syscall(__NR_chmod, fname, 0600);
- printf("chmod(\"%s\", 0600) = %s\n", fname, sprintrc(rc));
+ long rc = syscall(__NR_chmod, sample, 0600);
+ printf("%s%s(\"%s\"%s, 0600) = %s\n",
+ my_secontext, "chmod",
+ sample, SECONTEXT_FILE(sample),
+ sprintrc(rc));
- if (unlink(fname))
- perror_msg_and_fail("unlink");
+ if (unlink(sample))
+ perror_msg_and_fail("unlink: %s", sample);
- rc = syscall(__NR_chmod, fname, 051);
- printf("chmod(\"%s\", 051) = %s\n", fname, sprintrc(rc));
+ rc = syscall(__NR_chmod, sample, 051);
+ printf("%s%s(\"%s\", 051) = %s\n",
+ my_secontext, "chmod",
+ sample,
+ sprintrc(rc));
- rc = syscall(__NR_chmod, fname, 004);
- printf("chmod(\"%s\", 004) = %s\n", fname, sprintrc(rc));
+ rc = syscall(__NR_chmod, sample, 004);
+ printf("%s%s(\"%s\", 004) = %s\n",
+ my_secontext, "chmod",
+ sample,
+ sprintrc(rc));
leave_and_remove_subdir();
diff --git a/tests/execve.c b/tests/execve.c
index 961d284a1..baf3eeb61 100644
--- a/tests/execve.c
+++ b/tests/execve.c
@@ -9,9 +9,12 @@
*/
#include "tests.h"
+#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
+#include "secontext.h"
+
static const char *errstr;
static int
@@ -52,9 +55,16 @@ main(void)
char ** const tail_argv = tail_memdup(argv, sizeof(argv));
char ** const tail_envp = tail_memdup(envp, sizeof(envp));
+ char *my_secontext = SECONTEXT_PID_MY();
+
+ (void) unlink(FILENAME);
+ if (open(FILENAME, O_RDONLY | O_CREAT, 0400) < 0)
+ perror_msg_and_fail("open");
+
+ char *FILENAME_secontext = SECONTEXT_FILE(FILENAME);
call_execve(FILENAME, tail_argv, tail_envp);
- printf("execve(\"%s\""
+ printf("%s%s(\"%s\"%s"
", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
#if VERBOSE
", [\"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
@@ -62,7 +72,9 @@ main(void)
", %p /* 5 vars, unterminated */"
#endif
") = %s\n",
- Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext,
+ q_argv[0], q_argv[1], q_argv[2],
argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv)
#if VERBOSE
, q_envp[0], q_envp[1], envp[2], envp[3], envp[4],
@@ -77,14 +89,16 @@ main(void)
(void) q_envp; /* workaround for clang bug #33068 */
call_execve(FILENAME, tail_argv, tail_envp);
- printf("execve(\"%s\", [\"%s\", \"%s\", \"%s\"]"
+ printf("%s%s(\"%s\"%s, [\"%s\", \"%s\", \"%s\"]"
#if VERBOSE
", [\"%s\", \"%s\"]"
#else
", %p /* 2 vars */"
#endif
") = %s\n",
- Q_FILENAME, q_argv[0], q_argv[1], q_argv[2]
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext,
+ q_argv[0], q_argv[1], q_argv[2]
#if VERBOSE
, q_envp[0], q_envp[1]
#else
@@ -93,14 +107,16 @@ main(void)
, errstr);
call_execve(FILENAME, tail_argv + 2, tail_envp + 1);
- printf("execve(\"%s\", [\"%s\"]"
+ printf("%s%s(\"%s\"%s, [\"%s\"]"
#if VERBOSE
", [\"%s\"]"
#else
", %p /* 1 var */"
#endif
") = %s\n",
- Q_FILENAME, q_argv[2]
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext,
+ q_argv[2]
#if VERBOSE
, q_envp[1]
#else
@@ -113,13 +129,15 @@ main(void)
*empty = NULL;
call_execve(FILENAME, empty, empty);
- printf("execve(\"%s\", []"
+ printf("%s%s(\"%s\"%s, []"
#if VERBOSE
", []"
#else
", %p /* 0 vars */"
#endif
- ") = %s\n", Q_FILENAME
+ ") = %s\n",
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext
#if !VERBOSE
, empty
#endif
@@ -143,7 +161,10 @@ main(void)
a[i] = b[i] = NULL;
call_execve(FILENAME, a, b);
- printf("execve(\"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
+ printf("%s%s(\"%s\"%s, [\"%.*s\"...",
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext,
+ DEFAULT_STRLEN, a[0]);
for (i = 1; i < DEFAULT_STRLEN; ++i)
printf(", \"%s\"", a[i]);
#if VERBOSE
@@ -162,7 +183,10 @@ main(void)
printf(") = %s\n", errstr);
call_execve(FILENAME, a + 1, b + 1);
- printf("execve(\"%s\", [\"%s\"", Q_FILENAME, a[1]);
+ printf("%s%s(\"%s\"%s, [\"%s\"",
+ my_secontext, "execve",
+ Q_FILENAME, FILENAME_secontext,
+ a[1]);
for (i = 2; i <= DEFAULT_STRLEN; ++i)
printf(", \"%s\"", a[i]);
#if VERBOSE
@@ -175,12 +199,17 @@ main(void)
#endif
printf(") = %s\n", errstr);
+ if (unlink(FILENAME))
+ perror_msg_and_fail("unlink");
+
call_execve(FILENAME, (char **) tail_argv[ARRAY_SIZE(q_argv)], efault);
- printf("execve(\"%s\", NULL, %p) = %s\n",
+ printf("%s%s(\"%s\", NULL, %p) = %s\n",
+ my_secontext, "execve",
Q_FILENAME, efault, errstr);
call_execve(FILENAME, efault, NULL);
- printf("execve(\"%s\", %p, NULL) = %s\n",
+ printf("%s%s(\"%s\", %p, NULL) = %s\n",
+ my_secontext, "execve",
Q_FILENAME, efault, errstr);
leave_and_remove_subdir();
diff --git a/tests/execve.test b/tests/execve.test
index 0824bab48..3275226ae 100755
--- a/tests/execve.test
+++ b/tests/execve.test
@@ -11,7 +11,7 @@
check_prog grep
run_prog > /dev/null
-run_strace -eexecve $args > "$EXP"
+run_strace -eexecve "$@" $args > "$EXP"
# Filter out execve() call made by strace.
grep -F test.execve < "$LOG" > "$OUT"
diff --git a/tests/execveat.c b/tests/execveat.c
index 43b53edb1..a41c42319 100644
--- a/tests/execveat.c
+++ b/tests/execveat.c
@@ -13,9 +13,102 @@
#ifdef __NR_execveat
+# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
+static void
+tests_with_existing_file(void)
+{
+ /*
+ * Make sure the current workdir of the tracee
+ * is different from the current workdir of the tracer.
+ */
+ create_and_enter_subdir("execveat_subdir");
+
+ char *my_secontext = SECONTEXT_PID_MY();
+
+ static const char sample[] = "execveat_sample";
+ (void) unlink(sample);
+ if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
+ perror_msg_and_fail("open");
+
+ char *sample_secontext = SECONTEXT_FILE(sample);
+ static const char *argv[] = { sample, NULL };
+
+ /*
+ * Tests with AT_FDCWD.
+ */
+
+ long rc = syscall(__NR_execveat, -100, sample, argv, NULL, 0);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, [\"%s\"], NULL, 0) = %s\n",
+ my_secontext, "execveat",
+ sample, sample_secontext,
+ argv[0],
+ sprintrc(rc));
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
+ rc = syscall(__NR_execveat, -100, sample, argv, NULL, 0);
+ printf("%s%s(AT_FDCWD, \"%s\", [\"%s\"], NULL, 0) = %s\n",
+ my_secontext, "execveat",
+ sample,
+ argv[0],
+ sprintrc(rc));
+
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd = get_fd_path(cwd_fd);
+ char *cwd_secontext = SECONTEXT_FILE(".");
+ char *sample_realpath = xasprintf("%s/%s", cwd, sample);
+
+ /* no file */
+ rc = syscall(__NR_execveat, cwd_fd, sample, argv, NULL, 0);
+ printf("%s%s(%d%s, \"%s\", [\"%s\"], NULL, 0) = %s\n",
+ my_secontext, "execveat",
+ cwd_fd, cwd_secontext,
+ sample,
+ argv[0],
+ sprintrc(rc));
+
+ if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
+ perror_msg_and_fail("open");
+
+ rc = syscall(__NR_execveat, cwd_fd, sample, argv, NULL, 0);
+ printf("%s%s(%d%s, \"%s\"%s, [\"%s\"], NULL, 0) = %s\n",
+ my_secontext, "execveat",
+ cwd_fd, cwd_secontext,
+ sample, sample_secontext,
+ argv[0],
+ sprintrc(rc));
+
+ /* cwd_fd ignored when path is absolute */
+ if (chdir("../.."))
+ perror_msg_and_fail("chdir");
+
+ rc = syscall(__NR_execveat, cwd_fd, sample_realpath, argv, NULL, 0);
+ printf("%s%s(%d%s, \"%s\"%s, [\"%s\"], NULL, 0) = %s\n",
+ my_secontext, "execveat",
+ cwd_fd, cwd_secontext,
+ sample_realpath, sample_secontext,
+ argv[0],
+ sprintrc(rc));
+
+ if (fchdir(cwd_fd))
+ perror_msg_and_fail("fchdir");
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
+ leave_and_remove_subdir();
+}
+
# define FILENAME "test.execveat\nfilename"
# define Q_FILENAME "test.execveat\\nfilename"
@@ -40,9 +133,10 @@ main(void)
{
const char ** const tail_argv = tail_memdup(argv, sizeof(argv));
const char ** const tail_envp = tail_memdup(envp, sizeof(envp));
+ char *my_secontext = SECONTEXT_PID_MY();
syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\""
+ printf("%s%s(AT_FDCWD, \"%s\""
", [\"%s\", \"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
# if VERBOSE
", [\"%s\", \"%s\", %p, %p, %p, ... /* %p */]"
@@ -50,6 +144,7 @@ main(void)
", %p /* 5 vars, unterminated */"
# endif
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
argv[3], argv[4], argv[5], (char *) tail_argv + sizeof(argv),
# if VERBOSE
@@ -65,13 +160,14 @@ main(void)
(void) q_envp; /* workaround for clang bug #33068 */
syscall(__NR_execveat, -100, FILENAME, tail_argv, tail_envp, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]"
+ printf("%s%s(AT_FDCWD, \"%s\", [\"%s\", \"%s\", \"%s\"]"
# if VERBOSE
", [\"%s\", \"%s\"]"
# else
", %p /* 2 vars */"
# endif
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME, q_argv[0], q_argv[1], q_argv[2],
# if VERBOSE
q_envp[0], q_envp[1],
@@ -81,13 +177,14 @@ main(void)
errno2name());
syscall(__NR_execveat, -100, FILENAME, tail_argv + 2, tail_envp + 1, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", [\"%s\"]"
+ printf("%s%s(AT_FDCWD, \"%s\", [\"%s\"]"
# if VERBOSE
", [\"%s\"]"
# else
", %p /* 1 var */"
# endif
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME, q_argv[2],
# if VERBOSE
q_envp[1],
@@ -101,13 +198,14 @@ main(void)
*empty = NULL;
syscall(__NR_execveat, -100, FILENAME, empty, empty, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", []"
+ printf("%s%s(AT_FDCWD, \"%s\", []"
# if VERBOSE
", []"
# else
", %p /* 0 vars */"
# endif
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME,
# if !VERBOSE
empty,
@@ -132,7 +230,9 @@ main(void)
a[i] = b[i] = NULL;
syscall(__NR_execveat, -100, FILENAME, a, b, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", [\"%.*s\"...", Q_FILENAME, DEFAULT_STRLEN, a[0]);
+ printf("%s%s(AT_FDCWD, \"%s\", [\"%.*s\"...",
+ my_secontext, "execveat",
+ Q_FILENAME, DEFAULT_STRLEN, a[0]);
for (i = 1; i < DEFAULT_STRLEN; ++i)
printf(", \"%s\"", a[i]);
# if VERBOSE
@@ -152,7 +252,9 @@ main(void)
errno2name());
syscall(__NR_execveat, -100, FILENAME, a + 1, b + 1, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", [\"%s\"", Q_FILENAME, a[1]);
+ printf("%s%s(AT_FDCWD, \"%s\", [\"%s\"",
+ my_secontext, "execveat",
+ Q_FILENAME, a[1]);
for (i = 2; i <= DEFAULT_STRLEN; ++i)
printf(", \"%s\"", a[i]);
# if VERBOSE
@@ -167,15 +269,19 @@ main(void)
errno2name());
syscall(__NR_execveat, -100, FILENAME, NULL, efault, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", NULL, %p"
+ printf("%s%s(AT_FDCWD, \"%s\", NULL, %p"
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME, efault, errno2name());
syscall(__NR_execveat, -100, FILENAME, efault, NULL, 0x1100);
- printf("execveat(AT_FDCWD, \"%s\", %p, NULL"
+ printf("%s%s(AT_FDCWD, \"%s\", %p, NULL"
", AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) = -1 %s (%m)\n",
+ my_secontext, "execveat",
Q_FILENAME, efault, errno2name());
+ tests_with_existing_file();
+
puts("+++ exited with 0 +++");
return 0;
}
diff --git a/tests/faccessat.c b/tests/faccessat.c
index 670e9b21f..2b05a8b5a 100644
--- a/tests/faccessat.c
+++ b/tests/faccessat.c
@@ -12,12 +12,16 @@
#ifdef __NR_faccessat
-# include "xmalloc.h"
# include <fcntl.h>
# include <stdio.h>
# include <unistd.h>
-# ifndef FD_PATH
+# include "secontext.h"
+# include "xmalloc.h"
+
+# ifdef FD_PATH
+# define YFLAG
+# else
# define FD_PATH ""
# endif
# ifndef SKIP_IF_PROC_IS_UNAVAILABLE
@@ -43,11 +47,130 @@ k_faccessat(const unsigned int dirfd,
return rc;
}
+# ifndef PATH_TRACING
+static void
+tests_with_existing_file(void)
+{
+ /*
+ * Make sure the current workdir of the tracee
+ * is different from the current workdir of the tracer.
+ */
+ create_and_enter_subdir("faccessat_subdir");
+
+ char *my_secontext = SECONTEXT_PID_MY();
+
+ k_faccessat(-1, NULL, F_OK);
+ printf("%s%s(-1, NULL, F_OK) = %s\n",
+ my_secontext, "faccessat", errstr);
+
+ static const char sample[] = "faccessat_sample";
+ (void) unlink(sample);
+ int fd = open(sample, O_CREAT|O_RDONLY, 0400);
+ if (fd == -1)
+ perror_msg_and_fail("open");
+ close(fd);
+ char *sample_secontext = SECONTEXT_FILE(sample);
+
+ /*
+ * Tests with AT_FDCWD.
+ */
+
+ k_faccessat(-100, sample, F_OK);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, F_OK) = %s\n",
+ my_secontext, "faccessat",
+ sample, sample_secontext,
+ errstr);
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
+ k_faccessat(-100, sample, F_OK);
+ printf("%s%s(AT_FDCWD, \"%s\", F_OK) = %s\n",
+ my_secontext, "faccessat",
+ sample,
+ errstr);
+
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd = get_fd_path(cwd_fd);
+ char *cwd_secontext = SECONTEXT_FILE(".");
+ char *sample_realpath = xasprintf("%s/%s", cwd, sample);
+
+ /* no file */
+ k_faccessat(cwd_fd, sample, F_OK);
+# ifdef YFLAG
+ printf("%s%s(%d<%s>%s, \"%s\", F_OK) = %s\n",
+# else
+ printf("%s%s(%d%s, \"%s\", F_OK) = %s\n",
+# endif
+ my_secontext, "faccessat",
+ cwd_fd,
+# ifdef YFLAG
+ cwd,
+# endif
+ cwd_secontext,
+ sample,
+ errstr);
+
+ fd = open(sample, O_CREAT|O_RDONLY, 0400);
+ if (fd == -1)
+ perror_msg_and_fail("open");
+ close(fd);
+
+ k_faccessat(cwd_fd, sample, F_OK);
+# ifdef YFLAG
+ printf("%s%s(%d<%s>%s, \"%s\"%s, F_OK) = %s\n",
+# else
+ printf("%s%s(%d%s, \"%s\"%s, F_OK) = %s\n",
+# endif
+ my_secontext, "faccessat",
+ cwd_fd,
+# ifdef YFLAG
+ cwd,
+# endif
+ cwd_secontext,
+ sample, sample_secontext,
+ errstr);
+
+ /* cwd_fd ignored when path is absolute */
+ if (chdir("../.."))
+ perror_msg_and_fail("chdir");
+
+ k_faccessat(cwd_fd, sample_realpath, F_OK);
+# ifdef YFLAG
+ printf("%s%s(%d<%s>%s, \"%s\"%s, F_OK) = %s\n",
+# else
+ printf("%s%s(%d%s, \"%s\"%s, F_OK) = %s\n",
+# endif
+ my_secontext, "faccessat",
+ cwd_fd,
+# ifdef YFLAG
+ cwd,
+# endif
+ cwd_secontext,
+ sample_realpath, sample_secontext,
+ errstr);
+
+ if (fchdir(cwd_fd))
+ perror_msg_and_fail("fchdir");
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
+ leave_and_remove_subdir();
+}
+# endif
+
int
main(void)
{
SKIP_IF_PROC_IS_UNAVAILABLE;
+# ifndef TEST_SECONTEXT
+
TAIL_ALLOC_OBJECT_CONST_PTR(const char, unterminated);
char *unterminated_str = xasprintf("%p", unterminated);
const void *const efault = unterminated + 1;
@@ -120,10 +243,10 @@ main(void)
k_faccessat(dirfds[dirfd_i].val,
paths[path_i].val,
modes[mode_i].val);
-# ifdef PATH_TRACING
+# ifdef PATH_TRACING
if (dirfds[dirfd_i].val == fd ||
paths[path_i].val == fd_path)
-# endif
+# endif
printf("faccessat(%s, %s, %s) = %s\n",
dirfds[dirfd_i].str,
paths[path_i].str,
@@ -133,6 +256,12 @@ main(void)
}
}
+# endif /* !TEST_SECONTEXT */
+
+# ifndef PATH_TRACING
+ tests_with_existing_file();
+# endif
+
puts("+++ exited with 0 +++");
return 0;
}
diff --git a/tests/faccessat.test b/tests/faccessat.test
index 83f94ba40..325e343b7 100755
--- a/tests/faccessat.test
+++ b/tests/faccessat.test
@@ -15,5 +15,5 @@ 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"
+sed -n '/faccessat(-1, NULL,/,$p' < "$LOG" > "$OUT"
match_diff "$OUT" "$EXP"
diff --git a/tests/fanotify_mark.c b/tests/fanotify_mark.c
index bd14f4790..15eab3e01 100644
--- a/tests/fanotify_mark.c
+++ b/tests/fanotify_mark.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2015-2016 Dmitry V. Levin <ldv@strace.io>
* Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
- * Copyright (c) 2015-2020 The strace developers.
+ * Copyright (c) 2015-2021 The strace developers.
* All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -21,6 +21,8 @@
# include <unistd.h>
# include <sys/fanotify.h>
+# include "secontext.h"
+
# if XLAT_RAW
# define str_fan_mark_add "0x1"
# define str_fan_modify_ondir "0x40000002"
@@ -35,6 +37,7 @@
# define str_at_fdcwd "AT_FDCWD"
# endif
+# ifndef TEST_SECONTEXT
/* Performs fanotify_mark call via the syscall interface. */
static void
do_call(kernel_ulong_t fd, kernel_ulong_t flags, const char *flags_str,
@@ -44,18 +47,18 @@ do_call(kernel_ulong_t fd, kernel_ulong_t flags, const char *flags_str,
long rc;
rc = syscall(__NR_fanotify_mark, fd, flags,
-# if (LONG_MAX > INT_MAX) \
- || (defined __x86_64__ && defined __ILP32__) \
- || defined LINUX_MIPSN32
+# if (LONG_MAX > INT_MAX) \
+ || (defined __x86_64__ && defined __ILP32__) \
+ || defined LINUX_MIPSN32
mask,
-# else
+# else
/* arch/parisc/kernel/sys_parisc32.c, commit ab8a261b */
-# ifdef HPPA
+# ifdef HPPA
LL_VAL_TO_PAIR((mask << 32) | (mask >> 32)),
-# else
+# else
LL_VAL_TO_PAIR(mask),
+# endif
# endif
-# endif
dirfd, path);
printf("fanotify_mark(%d, %s, %s, %s, %s) = %s\n",
@@ -68,12 +71,14 @@ struct strval {
const char *str;
};
-# define STR16 "0123456789abcdef"
-# define STR64 STR16 STR16 STR16 STR16
+# define STR16 "0123456789abcdef"
+# define STR64 STR16 STR16 STR16 STR16
+# endif /* !TEST_SECONTEXT */
int
main(void)
{
+# ifndef TEST_SECONTEXT
enum {
PATH1_SIZE = 64,
};
@@ -87,47 +92,47 @@ main(void)
{ F8ILL_KULONG_MASK, "0" },
{ (kernel_ulong_t) 0xdec0deddefacec00ULL,
"0xefacec00"
-# if !XLAT_RAW
+# if !XLAT_RAW
" /* FAN_MARK_??? */"
-# endif
+# endif
},
{ (kernel_ulong_t) 0xda7a105700000040ULL,
-# if XLAT_RAW
+# if XLAT_RAW
"0x40"
-# elif XLAT_VERBOSE
+# elif XLAT_VERBOSE
"0x40 /* FAN_MARK_IGNORED_SURV_MODIFY */"
-# else
+# else
"FAN_MARK_IGNORED_SURV_MODIFY"
-# endif
+# endif
},
{ (kernel_ulong_t) 0xbadc0deddeadffffULL,
-# if XLAT_RAW || XLAT_VERBOSE
+# if XLAT_RAW || XLAT_VERBOSE
"0xdeadffff"
-# endif
-# if XLAT_VERBOSE
+# endif
+# if XLAT_VERBOSE
" /* "
-# endif
-# if !XLAT_RAW
+# endif
+# if !XLAT_RAW
"FAN_MARK_ADD|FAN_MARK_REMOVE|FAN_MARK_DONT_FOLLOW|"
"FAN_MARK_ONLYDIR|FAN_MARK_MOUNT|FAN_MARK_IGNORED_MASK|"
"FAN_MARK_IGNORED_SURV_MODIFY|FAN_MARK_FLUSH|"
"FAN_MARK_FILESYSTEM|0xdeadfe00"
-# endif
-# if XLAT_VERBOSE
+# endif
+# if XLAT_VERBOSE
" */"
-# endif
+# endif
},
};
static const struct strval64 masks[] = {
{ ARG_ULL_STR(0) },
{ 0xdeadfeedffffffffULL,
-# if XLAT_RAW || XLAT_VERBOSE
+# if XLAT_RAW || XLAT_VERBOSE
"0xdeadfeedffffffff"
-# endif
-# if XLAT_VERBOSE
+# endif
+# if XLAT_VERBOSE
" /* "
-# endif
-# if !XLAT_RAW
+# endif
+# if !XLAT_RAW
"FAN_ACCESS|"
"FAN_MODIFY|"
"FAN_ATTRIB|"
@@ -149,27 +154,27 @@ main(void)
"FAN_ONDIR|"
"FAN_EVENT_ON_CHILD|"
"0xdeadfeedb7f0a000"
-# endif
-# if XLAT_VERBOSE
+# endif
+# if XLAT_VERBOSE
" */"
-# endif
+# endif
},
{ ARG_ULL_STR(0xffffffffb7f0a000)
-# if !XLAT_RAW
+# if !XLAT_RAW
" /* FAN_??? */"
-# endif
+# endif
},
};
static const struct strval dirfds[] = {
{ (kernel_ulong_t) 0xfacefeed00000001ULL, "1" },
{ (kernel_ulong_t) 0xdec0ded0ffffffffULL,
-# if XLAT_RAW
+# if XLAT_RAW
"-1"
-# elif XLAT_VERBOSE
+# elif XLAT_VERBOSE
"-1 /* FAN_NOFD */"
-# else
+# else
"FAN_NOFD"
-# endif
+# endif
},
{ (kernel_ulong_t) 0xbadfacedffffff9cULL, str_at_fdcwd },
{ (kernel_ulong_t) 0xdefaced1beeff00dULL, "-1091571699" },
@@ -202,12 +207,6 @@ main(void)
snprintf(bogus_path1_after_addr, sizeof(bogus_path1_after_addr), "%p",
bogus_path1 + PATH1_SIZE);
- rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
- -100, ".");
- printf("fanotify_mark(-1, %s, %s, %s, \".\") = %s\n",
- str_fan_mark_add, str_fan_modify_ondir, str_at_fdcwd,
- sprintrc(rc));
-
for (i = 0; i < ARRAY_SIZE(fds); i++) {
for (j = 0; j < ARRAY_SIZE(flags); j++) {
for (k = 0; k < ARRAY_SIZE(masks); k++) {
@@ -226,6 +225,40 @@ main(void)
}
}
}
+# else /* TEST_SECONTEXT */
+ int rc;
+# endif
+ /*
+ * Test with AT_FDCWD.
+ */
+
+ char *my_secontext = SECONTEXT_PID_MY();
+ char path[] = ".";
+ char *path_secontext = SECONTEXT_FILE(path);
+
+ rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
+ -100, path);
+ printf("%s%s(-1, %s, %s, %s, \"%s\"%s) = %s\n",
+ my_secontext, "fanotify_mark",
+ str_fan_mark_add, str_fan_modify_ondir, str_at_fdcwd,
+ path, path_secontext,
+ sprintrc(rc));
+
+ /*
+ * Test with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd_secontext = SECONTEXT_FILE(".");
+
+ rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
+ cwd_fd, path);
+ printf("%s%s(-1, %s, %s, %d%s, \"%s\"%s) = %s\n",
+ my_secontext, "fanotify_mark",
+ str_fan_mark_add, str_fan_modify_ondir,
+ cwd_fd, cwd_secontext,
+ path, path_secontext,
+ sprintrc(rc));
puts("+++ exited with 0 +++");
return 0;
diff --git a/tests/fchmod.c b/tests/fchmod.c
index 4da4f0658..0b0570cfe 100644
--- a/tests/fchmod.c
+++ b/tests/fchmod.c
@@ -18,6 +18,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -27,6 +29,8 @@ main(void)
*/
create_and_enter_subdir("fchmod_subdir");
+ char *my_secontext = SECONTEXT_PID_MY();
+
static const char sample[] = "fchmod_sample_file";
(void) unlink(sample);
int fd = open(sample, O_CREAT|O_RDONLY, 0400);
@@ -37,16 +41,19 @@ main(void)
char *sample_realpath = get_fd_path(fd);
# endif
+ const char *sample_secontext = SECONTEXT_FILE(sample);
long rc = syscall(__NR_fchmod, fd, 0600);
# ifdef YFLAG
- printf("fchmod(%d<%s>, 0600) = %s\n",
+ printf("%s%s(%d<%s>%s, 0600) = %s\n",
# else
- printf("fchmod(%d, 0600) = %s\n",
+ printf("%s%s(%d%s, 0600) = %s\n",
# endif
+ my_secontext, "fchmod",
fd,
# ifdef YFLAG
sample_realpath,
# endif
+ sample_secontext,
sprintrc(rc));
if (unlink(sample))
@@ -54,26 +61,30 @@ main(void)
rc = syscall(__NR_fchmod, fd, 051);
# ifdef YFLAG
- printf("fchmod(%d<%s (deleted)>, 051) = %s\n",
+ printf("%s%s(%d<%s (deleted)>%s, 051) = %s\n",
# else
- printf("fchmod(%d, 051) = %s\n",
+ printf("%s%s(%d%s, 051) = %s\n",
# endif
+ my_secontext, "fchmod",
fd,
# ifdef YFLAG
sample_realpath,
# endif
+ sample_secontext,
sprintrc(rc));
rc = syscall(__NR_fchmod, fd, 004);
# ifdef YFLAG
- printf("fchmod(%d<%s (deleted)>, 004) = %s\n",
+ printf("%s%s(%d<%s (deleted)>%s, 004) = %s\n",
# else
- printf("fchmod(%d, 004) = %s\n",
+ printf("%s%s(%d%s, 004) = %s\n",
# endif
+ my_secontext, "fchmod",
fd,
# ifdef YFLAG
sample_realpath,
# endif
+ sample_secontext,
sprintrc(rc));
leave_and_remove_subdir();
diff --git a/tests/fchmodat.c b/tests/fchmodat.c
index 37dc6b563..2c69f4624 100644
--- a/tests/fchmodat.c
+++ b/tests/fchmodat.c
@@ -17,6 +17,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -26,26 +28,81 @@ main(void)
*/
create_and_enter_subdir("fchmodat_subdir");
- static const char sample[] = "fchmodat_sample";
+ char *my_secontext = SECONTEXT_PID_MY();
+ static const char sample[] = "fchmodat_sample_file";
if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
perror_msg_and_fail("open");
+ char *sample_secontext = SECONTEXT_FILE(sample);
+
+ /*
+ * Tests with AT_FDCWD.
+ */
+
long rc = syscall(__NR_fchmodat, -100, sample, 0600);
- printf("fchmodat(AT_FDCWD, \"%s\", 0600) = %s\n",
- sample, sprintrc(rc));
+ printf("%s%s(AT_FDCWD, \"%s\"%s, 0600) = %s\n",
+ my_secontext, "fchmodat",
+ sample, sample_secontext,
+ sprintrc(rc));
if (unlink(sample))
perror_msg_and_fail("unlink");
rc = syscall(__NR_fchmodat, -100, sample, 051);
- printf("fchmodat(AT_FDCWD, \"%s\", 051) = %s\n",
+ printf("%s%s(AT_FDCWD, \"%s\", 051) = %s\n",
+ my_secontext, "fchmodat",
sample, sprintrc(rc));
rc = syscall(__NR_fchmodat, -100, sample, 004);
- printf("fchmodat(AT_FDCWD, \"%s\", 004) = %s\n",
+ printf("%s%s(AT_FDCWD, \"%s\", 004) = %s\n",
+ my_secontext, "fchmodat",
sample, sprintrc(rc));
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd = get_fd_path(cwd_fd);
+ char *cwd_secontext = SECONTEXT_FILE(".");
+ char *sample_realpath = xasprintf("%s/%s", cwd, sample);
+
+ /* no file */
+ rc = syscall(__NR_fchmodat, cwd_fd, sample, 0400);
+ printf("%s%s(%d%s, \"%s\", 0400) = %s\n",
+ my_secontext, "fchmodat",
+ cwd_fd, cwd_secontext,
+ sample,
+ sprintrc(rc));
+
+ if (open(sample, O_RDONLY | O_CREAT, 0400) < 0)
+ perror_msg_and_fail("open");
+
+ rc = syscall(__NR_fchmodat, cwd_fd, sample, 0400);
+ printf("%s%s(%d%s, \"%s\"%s, 0400) = %s\n",
+ my_secontext, "fchmodat",
+ cwd_fd, cwd_secontext,
+ sample, sample_secontext,
+ sprintrc(rc));
+
+ /* cwd_fd ignored when path is absolute */
+ if (chdir("../.."))
+ perror_msg_and_fail("chdir");
+
+ rc = syscall(__NR_fchmodat, cwd_fd, sample_realpath, 0400);
+ printf("%s%s(%d%s, \"%s\"%s, 0400) = %s\n",
+ my_secontext, "fchmodat",
+ cwd_fd, cwd_secontext,
+ sample_realpath, sample_secontext,
+ sprintrc(rc));
+
+ if (fchdir(cwd_fd))
+ perror_msg_and_fail("fchdir");
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
leave_and_remove_subdir();
puts("+++ exited with 0 +++");
diff --git a/tests/fchownat.c b/tests/fchownat.c
index 766fd0241..bebb25445 100644
--- a/tests/fchownat.c
+++ b/tests/fchownat.c
@@ -17,6 +17,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -26,25 +28,86 @@ main(void)
*/
create_and_enter_subdir("fchownat_subdir");
- static const char sample[] = "fchownat_sample";
+ char *my_secontext = SECONTEXT_PID_MY();
uid_t uid = geteuid();
uid_t gid = getegid();
- if (open(sample, O_RDONLY | O_CREAT, 0400) == -1)
+ static const char sample[] = "fchownat_sample";
+ int fd = open(sample, O_RDONLY | O_CREAT, 0400);
+ if (fd == -1)
perror_msg_and_fail("open");
+ close(fd);
+
+ char *sample_secontext = SECONTEXT_FILE(sample);
+
+ /*
+ * Tests with AT_FDCWD.
+ */
long rc = syscall(__NR_fchownat, AT_FDCWD, sample, uid, gid, 0);
- printf("fchownat(AT_FDCWD, \"%s\", %d, %d, 0) = %s\n",
- sample, uid, gid, sprintrc(rc));
+ printf("%s%s(AT_FDCWD, \"%s\"%s, %d, %d, 0) = %s\n",
+ my_secontext, "fchownat",
+ sample, sample_secontext,
+ uid, gid, sprintrc(rc));
if (unlink(sample))
perror_msg_and_fail("unlink");
rc = syscall(__NR_fchownat, AT_FDCWD,
sample, -1, -1L, AT_SYMLINK_NOFOLLOW);
- printf("fchownat(AT_FDCWD, \"%s\", -1, -1, AT_SYMLINK_NOFOLLOW) = %s\n",
+ printf("%s%s(AT_FDCWD, \"%s\", -1, -1, AT_SYMLINK_NOFOLLOW) = %s\n",
+ my_secontext, "fchownat",
sample, sprintrc(rc));
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd = get_fd_path(cwd_fd);
+ char *cwd_secontext = SECONTEXT_FILE(".");
+ char *sample_realpath = xasprintf("%s/%s", cwd, sample);
+
+ /* no file */
+ rc = syscall(__NR_fchownat, cwd_fd, sample, uid, gid, 0);
+ printf("%s%s(%d%s, \"%s\", %d, %d, 0) = %s\n",
+ my_secontext, "fchownat",
+ cwd_fd, cwd_secontext,
+ sample,
+ uid, gid,
+ sprintrc(rc));
+
+ fd = open(sample, O_RDONLY | O_CREAT, 0400);
+ if (fd == -1)
+ perror_msg_and_fail("open");
+ close(fd);
+
+ rc = syscall(__NR_fchownat, cwd_fd, sample, uid, gid, 0);
+ printf("%s%s(%d%s, \"%s\"%s, %d, %d, 0) = %s\n",
+ my_secontext, "fchownat",
+ cwd_fd, cwd_secontext,
+ sample, sample_secontext,
+ uid, gid,
+ sprintrc(rc));
+
+ /* cwd_fd ignored when path is absolute */
+ if (chdir("../.."))
+ perror_msg_and_fail("chdir");
+
+ rc = syscall(__NR_fchownat, cwd_fd, sample_realpath, uid, gid, 0);
+ printf("%s%s(%d%s, \"%s\"%s, %d, %d, 0) = %s\n",
+ my_secontext, "fchownat",
+ cwd_fd, cwd_secontext,
+ sample_realpath, sample_secontext,
+ uid, gid,
+ sprintrc(rc));
+
+ if (fchdir(cwd_fd))
+ perror_msg_and_fail("fchdir");
+
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+
leave_and_remove_subdir();
puts("+++ exited with 0 +++");
diff --git a/tests/file_handle.c b/tests/file_handle.c
index e6a69910b..86d51b636 100644
--- a/tests/file_handle.c
+++ b/tests/file_handle.c
@@ -21,6 +21,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
enum assert_rc {
ASSERT_NONE,
ASSERT_SUCCESS,
@@ -48,6 +50,7 @@ print_handle_data(unsigned char *bytes, unsigned int size)
printf("...");
}
+# ifndef TEST_SECONTEXT
void
do_name_to_handle_at(kernel_ulong_t dirfd, const char *dirfd_str,
kernel_ulong_t pathname, const char *pathname_str,
@@ -129,6 +132,7 @@ do_open_by_handle_at(kernel_ulong_t mount_fd,
printf("%s\n", sprintrc(rc));
}
+# endif /* !TEST_SECONTEXT */
struct strval {
kernel_ulong_t val;
@@ -141,12 +145,86 @@ struct strval {
int
main(void)
{
+ char *my_secontext = SECONTEXT_PID_MY();
enum {
PATH1_SIZE = 64,
};
static const kernel_ulong_t fdcwd =
(kernel_ulong_t) 0x87654321ffffff9cULL;
+
+ struct file_handle *handle =
+ tail_alloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
+ struct file_handle *handle_0 =
+ tail_alloc(sizeof(struct file_handle) + 0);
+ struct file_handle *handle_8 =
+ tail_alloc(sizeof(struct file_handle) + 8);
+ struct file_handle *handle_128 =
+ tail_alloc(sizeof(struct file_handle) + 128);
+ struct file_handle *handle_256 =
+ tail_alloc(sizeof(struct file_handle) + 256);
+ TAIL_ALLOC_OBJECT_CONST_PTR(int, bogus_mount_id);
+
+ char handle_0_addr[sizeof("0x") + sizeof(void *) * 2];
+
+ const int flags = 0x400;
+ int mount_id;
+
+ handle_0->handle_bytes = 256;
+ handle_8->handle_bytes = 0;
+ handle_128->handle_bytes = 128;
+ handle_256->handle_bytes = 256;
+
+ fill_memory((char *) handle_128 + sizeof(struct file_handle), 128);
+ fill_memory((char *) handle_256 + sizeof(struct file_handle), 256);
+
+ snprintf(handle_0_addr, sizeof(handle_0_addr), "%p",
+ handle_0 + sizeof(struct file_handle));
+
+ handle->handle_bytes = 0;
+
+ char path[] = ".";
+ char *path_secontext = SECONTEXT_FILE(path);
+
+ assert(syscall(__NR_name_to_handle_at, fdcwd, path, handle, &mount_id,
+ flags | 1) == -1);
+ if (EINVAL != errno)
+ perror_msg_and_skip("name_to_handle_at");
+ printf("%s%s(AT_FDCWD, \"%s\"%s, {handle_bytes=0}, %p"
+ ", AT_SYMLINK_FOLLOW|0x1) = -1 EINVAL (%m)\n",
+ my_secontext, "name_to_handle_at",
+ path, path_secontext,
+ &mount_id);
+
+ assert(syscall(__NR_name_to_handle_at, fdcwd, path, handle, &mount_id,
+ flags) == -1);
+ if (EOVERFLOW != errno)
+ perror_msg_and_skip("name_to_handle_at");
+ printf("%s%s(AT_FDCWD, \"%s\"%s, {handle_bytes=0 => %u}"
+ ", %p, AT_SYMLINK_FOLLOW) = -1 EOVERFLOW (%m)\n",
+ my_secontext, "name_to_handle_at",
+ path, path_secontext,
+ handle->handle_bytes, &mount_id);
+
+ assert(syscall(__NR_name_to_handle_at, fdcwd, path, handle, &mount_id,
+ flags) == 0);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, {handle_bytes=%u"
+ ", handle_type=%d, f_handle=",
+ my_secontext, "name_to_handle_at",
+ path, path_secontext,
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data(handle->f_handle, handle->handle_bytes);
+ printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
+
+ printf("%s%s(-1, {handle_bytes=%u, handle_type=%d, f_handle=",
+ my_secontext, "open_by_handle_at",
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data(handle->f_handle, handle->handle_bytes);
+ int rc = syscall(__NR_open_by_handle_at, -1, handle,
+ O_RDONLY | O_DIRECTORY);
+ printf("}, O_RDONLY|O_DIRECTORY) = %d %s (%m)\n", rc, errno2name());
+
+# ifndef TEST_SECONTEXT
static const struct strval dirfds[] = {
{ (kernel_ulong_t) 0xdeadca57badda7a1ULL, "-1159878751" },
{ (kernel_ulong_t) 0x12345678ffffff9cULL, "AT_FDCWD" },
@@ -171,29 +249,11 @@ main(void)
};
static const char str64[] = STR64;
-
-
char *bogus_path1 = tail_memdup(str64, PATH1_SIZE);
char *bogus_path2 = tail_memdup(str64, sizeof(str64));
-
- struct file_handle *handle =
- tail_alloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
- struct file_handle *handle_0 =
- tail_alloc(sizeof(struct file_handle) + 0);
- struct file_handle *handle_8 =
- tail_alloc(sizeof(struct file_handle) + 8);
- struct file_handle *handle_128 =
- tail_alloc(sizeof(struct file_handle) + 128);
- struct file_handle *handle_256 =
- tail_alloc(sizeof(struct file_handle) + 256);
- TAIL_ALLOC_OBJECT_CONST_PTR(int, bogus_mount_id);
-
- char handle_0_addr[sizeof("0x") + sizeof(void *) * 2];
-
char bogus_path1_addr[sizeof("0x") + sizeof(void *) * 2];
char bogus_path1_after_addr[sizeof("0x") + sizeof(void *) * 2];
-
struct strval paths[] = {
{ (kernel_ulong_t) 0, "NULL" },
{ (kernel_ulong_t) (uintptr_t) (bogus_path1 + PATH1_SIZE),
@@ -229,62 +289,16 @@ main(void)
(kernel_ulong_t) (uintptr_t) bogus_mount_id,
};
- const int flags = 0x400;
- int mount_id;
unsigned int i;
unsigned int j;
unsigned int k;
unsigned int l;
unsigned int m;
-
snprintf(bogus_path1_addr, sizeof(bogus_path1_addr), "%p", bogus_path1);
snprintf(bogus_path1_after_addr, sizeof(bogus_path1_after_addr), "%p",
bogus_path1 + PATH1_SIZE);
- handle_0->handle_bytes = 256;
- handle_8->handle_bytes = 0;
- handle_128->handle_bytes = 128;
- handle_256->handle_bytes = 256;
-
- fill_memory((char *) handle_128 + sizeof(struct file_handle), 128);
- fill_memory((char *) handle_256 + sizeof(struct file_handle), 256);
-
- snprintf(handle_0_addr, sizeof(handle_0_addr), "%p",
- handle_0 + sizeof(struct file_handle));
-
- handle->handle_bytes = 0;
-
- assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
- flags | 1) == -1);
- if (EINVAL != errno)
- perror_msg_and_skip("name_to_handle_at");
- printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=0}, %p"
- ", AT_SYMLINK_FOLLOW|0x1) = -1 EINVAL (%m)\n", &mount_id);
-
- assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
- flags) == -1);
- if (EOVERFLOW != errno)
- perror_msg_and_skip("name_to_handle_at");
- printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=0 => %u}"
- ", %p, AT_SYMLINK_FOLLOW) = -1 EOVERFLOW (%m)\n",
- handle->handle_bytes, &mount_id);
-
- assert(syscall(__NR_name_to_handle_at, fdcwd, ".", handle, &mount_id,
- flags) == 0);
- printf("name_to_handle_at(AT_FDCWD, \".\", {handle_bytes=%u"
- ", handle_type=%d, f_handle=",
- handle->handle_bytes, handle->handle_type);
- print_handle_data(handle->f_handle, handle->handle_bytes);
- printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
-
- printf("open_by_handle_at(-1, {handle_bytes=%u, handle_type=%d"
- ", f_handle=", handle->handle_bytes, handle->handle_type);
- print_handle_data(handle->f_handle, handle->handle_bytes);
- int rc = syscall(__NR_open_by_handle_at, -1, handle,
- O_RDONLY | O_DIRECTORY);
- printf("}, O_RDONLY|O_DIRECTORY) = %d %s (%m)\n", rc, errno2name());
-
for (i = 0; i < ARRAY_SIZE(dirfds); i++) {
for (j = 0; j < ARRAY_SIZE(paths); j++) {
for (k = 0; k < ARRAY_SIZE(name_handles); k++) {
@@ -320,6 +334,68 @@ main(void)
}
}
}
+# endif
+
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd = get_fd_path(cwd_fd);
+ char *cwd_secontext = SECONTEXT_FILE(".");
+
+ assert(syscall(__NR_name_to_handle_at, cwd_fd, path, handle, &mount_id,
+ flags) == 0);
+ printf("%s%s(%d%s, \"%s\"%s, {handle_bytes=%u, handle_type=%d"
+ ", f_handle=",
+ my_secontext, "name_to_handle_at",
+ cwd_fd, cwd_secontext,
+ path, path_secontext,
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data((unsigned char *) handle +
+ sizeof(struct file_handle),
+ handle->handle_bytes);
+ printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
+
+ printf("%s%s(-1, {handle_bytes=%u, handle_type=%d, f_handle=",
+ my_secontext, "open_by_handle_at",
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data((unsigned char *) handle +
+ sizeof(struct file_handle),
+ handle->handle_bytes);
+ rc = syscall(__NR_open_by_handle_at, -1, handle,
+ O_RDONLY | O_DIRECTORY);
+ printf("}, O_RDONLY|O_DIRECTORY) = %s\n", sprintrc(rc));
+
+ /* cwd_fd ignored when path is absolute */
+ if (chdir(".."))
+ perror_msg_and_fail("chdir");
+
+ assert(syscall(__NR_name_to_handle_at, cwd_fd, cwd, handle, &mount_id,
+ flags) == 0);
+ printf("%s%s(%d%s, \"%s\"%s, {handle_bytes=%u"
+ ", handle_type=%d, f_handle=",
+ my_secontext, "name_to_handle_at",
+ cwd_fd, cwd_secontext,
+ cwd, cwd_secontext,
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data((unsigned char *) handle +
+ sizeof(struct file_handle),
+ handle->handle_bytes);
+ printf("}, [%d], AT_SYMLINK_FOLLOW) = 0\n", mount_id);
+
+ printf("%s%s(-1, {handle_bytes=%u, handle_type=%d, f_handle=",
+ my_secontext, "open_by_handle_at",
+ handle->handle_bytes, handle->handle_type);
+ print_handle_data((unsigned char *) handle +
+ sizeof(struct file_handle),
+ handle->handle_bytes);
+ rc = syscall(__NR_open_by_handle_at, -1, handle,
+ O_RDONLY | O_DIRECTORY);
+ printf("}, O_RDONLY|O_DIRECTORY) = %s\n", sprintrc(rc));
+
+ if (fchdir(cwd_fd))
+ perror_msg_and_fail("fchdir");
puts("+++ exited with 0 +++");
return 0;
diff --git a/tests/gen_secontext.sh b/tests/gen_secontext.sh
new file mode 100755
index 000000000..407a39b9f
--- /dev/null
+++ b/tests/gen_secontext.sh
@@ -0,0 +1,72 @@
+#!/bin/sh -efu
+#
+# Copyright (c) 2021 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+usage()
+{
+ cat >&2 <<EOF
+Usage: $0 [<input>]
+
+Generate secontext files from <input> list.
+EOF
+ exit 1
+}
+
+if [ $# -eq 0 ]; then
+ input="${0%/*}/gen_tests.in"
+else
+ input="$1"
+ shift
+fi
+dir="$(dirname "$input")"
+[ $# -eq 0 ] || usage
+
+{
+ cat <<EOF
+# Generated by $0 from $input; do not edit.
+
+secontext_EXECUTABLES = \\
+EOF
+ sed -r -n 's/^([^#[:space:]]+--secontext(_full)?)[[:space:]].*/ \1 \\/p' < "$input"
+ cat <<EOF
+ #
+
+EOF
+ sed -r -n 's/-/_/g; s/^([^#[:space:]]+__secontext(_full)?)[[:space:]].*/\1_LDADD = \$(LDADD) \$(libselinux_LDADD)/p' < "$input"
+} > "$dir/secontext.am"
+
+sed -r -n 's/^([^#[:space:]]+--secontext)[[:space:]].*/\1/p' < "$input" |
+while read -r name; do {
+ cat <<-EOF > "$dir/$name.c"
+ /*
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+ #include "tests.h"
+
+ #ifdef HAVE_SELINUX_RUNTIME
+
+ # define TEST_SECONTEXT
+ # include "${name%--secontext}.c"
+
+ #else
+
+ SKIP_MAIN_UNDEFINED("HAVE_SELINUX_RUNTIME")
+
+ #endif
+ EOF
+} < /dev/null; done
+
+sed -r -n 's/^([^#[:space:]]+--secontext_full)[[:space:]].*/\1/p' < "$input" |
+while read -r name; do {
+ cat <<-EOF > "$dir/$name.c"
+ #define PRINT_SECONTEXT_FULL
+ #include "${name%_full}.c"
+ EOF
+} < /dev/null; done
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 93702bafe..5ca88e29a 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -10,6 +10,8 @@ _newselect-P -e trace=_newselect -P /dev/full 9>>/dev/full
accept -a22
accept4 -a37
access -a30 --trace-path=access_sample
+access--secontext -a30 --secontext --trace-path=access_sample -e trace=access
+access--secontext_full -a30 --secontext=full --trace-path=access_sample -e trace=access
acct -a20
add_key -a30 -s12
adjtimex -a15
@@ -25,6 +27,8 @@ bpf-v -a20 -v -e trace=bpf
btrfs +ioctl.test
chdir -a10
chmod -a28
+chmod--secontext -a28 --secontext -e trace=chmod
+chmod--secontext_full -a28 --secontext=full -e trace=chmod
chown -a28
chown32 -a31
chroot -a13
@@ -81,10 +85,18 @@ epoll_pwait2-P --trace=epoll_pwait2 -P /dev/full
epoll_pwait2-y --trace=epoll_pwait2 -y
epoll_wait -a26
erestartsys -a34 -e signal=none -e trace=recvfrom
+execve--secontext +execve.test --secontext
+execve--secontext_full +execve.test --secontext=full
execveat
+execveat--secontext --secontext --trace=execveat
+execveat--secontext_full --secontext=full --trace=execveat
execveat-v -v -e trace=execveat
+faccessat--secontext +faccessat.test -a24 --secontext
+faccessat--secontext_full +faccessat.test -a24 --secontext=full
faccessat-P -a23 --trace=faccessat -P /dev/full
faccessat-y +faccessat.test -a24 -y
+faccessat-y--secontext +faccessat.test -a24 -y --secontext
+faccessat-y--secontext_full +faccessat.test -a24 -y --secontext=full
faccessat-yy +faccessat.test -a24 -yy
faccessat2-P -a27 --trace=faccessat2 -P /dev/full
faccessat2-y +faccessat2.test -a28 -y
@@ -93,22 +105,34 @@ fadvise64_64 +fadvise64.test
fallocate -a18
fanotify_init
fanotify_mark -a32
+fanotify_mark--secontext -a32 --secontext -e trace=fanotify_mark
+fanotify_mark--secontext_full -a32 --secontext=full -e trace=fanotify_mark
fanotify_mark-Xabbrev -a32 -Xabbrev -e trace=fanotify_mark
fanotify_mark-Xraw -a32 -Xraw -e trace=fanotify_mark
fanotify_mark-Xverbose -a32 -Xverbose -e trace=fanotify_mark
fchdir -a11
fchmod -a15
+fchmod--secontext -a15 --secontext -e trace=fchmod
+fchmod--secontext_full -a15 --secontext=full -e trace=fchmod
fchmod-y -y -e trace=fchmod
+fchmod-y--secontext -a15 -y --secontext -e trace=fchmod
+fchmod-y--secontext_full -a15 -y --secontext=full -e trace=fchmod
fchmodat
+fchmodat--secontext --secontext -e trace=fchmodat
+fchmodat--secontext_full --secontext=full -e trace=fchmodat
fchown -a16
fchown32 -a18
fchownat
+fchownat--secontext --secontext -e trace=fchownat
+fchownat--secontext_full --secontext=full -e trace=fchownat
fcntl -a8
fcntl--pidns-translation test_pidns -a8 -e trace=fcntl
fcntl64 -a8
fcntl64--pidns-translation test_pidns -a8 -e trace=fcntl64
fdatasync -a14
file_handle -e trace=name_to_handle_at,open_by_handle_at
+file_handle--secontext --secontext -e trace=name_to_handle_at,open_by_handle_at
+file_handle--secontext_full --secontext=full -e trace=name_to_handle_at,open_by_handle_at
filter_seccomp . "${srcdir=.}/filter_seccomp.sh"; test_prog_set --seccomp-bpf -f
filter_seccomp-flag ../$NAME
finit_module -a25
@@ -353,6 +377,8 @@ lchown -a30
lchown32 -a32
link
linkat
+linkat--secontext --secontext -e trace=linkat
+linkat--secontext_full --secontext=full -e trace=linkat
lookup_dcookie -a27
lstat -a31 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
lstat64 -a32 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
@@ -492,9 +518,13 @@ oldselect-efault -a13 -e trace=select
oldselect-efault-P -a13 -e trace=select -P /dev/full 9>>/dev/full
oldstat -a32 -v -P stat.sample -P /dev/full
open -a30 -P $NAME.sample
+open--secontext -a30 -P open.sample --secontext --trace=open
+open--secontext_full -a30 -P open.sample --secontext=full --trace=open
open_tree -a30 -y
open_tree-P -a30 --decode-fds -P /dev/full -e trace=open_tree
openat -a36 -P $NAME.sample
+openat--secontext -a36 -P openat.sample -P $PWD/openat.sample --secontext -e trace=openat
+openat--secontext_full -a36 -P openat.sample -P $PWD/openat.sample --secontext=full -e trace=openat
openat2 -a35
openat2-Xabbrev --trace=openat2 -a35 -Xabbrev
openat2-Xraw --trace=openat2 -a32 -Xraw
diff --git a/tests/linkat.c b/tests/linkat.c
index 6fcc6b4cf..bf6b6e39e 100644
--- a/tests/linkat.c
+++ b/tests/linkat.c
@@ -10,8 +10,14 @@
#ifdef __NR_linkat
+# include <fcntl.h>
# include <stdio.h>
+# include <stdlib.h>
# include <unistd.h>
+# include <sys/stat.h>
+
+# include "secontext.h"
+# include "xmalloc.h"
int
main(void)
@@ -27,18 +33,158 @@ main(void)
const long fd_old = (long) 0xdeadbeefffffffffULL;
const long fd_new = (long) 0xdeadbeeffffffffeULL;
+ char *my_secontext = SECONTEXT_PID_MY();
+
+ (void) unlink(sample_1);
+ (void) unlink(sample_2);
+
long rc = syscall(__NR_linkat, fd_old, sample_1, fd_new, sample_2, 0);
- printf("linkat(%d, \"%s\", %d, \"%s\", 0) = %ld %s (%m)\n",
+ printf("%s%s(%d, \"%s\", %d, \"%s\", 0) = %ld %s (%m)\n",
+ my_secontext, "linkat",
(int) fd_old, sample_1, (int) fd_new, sample_2,
rc, errno2name());
rc = syscall(__NR_linkat, -100, sample_1, -100, sample_2, -1L);
- printf("linkat(%s, \"%s\", %s, \"%s\", %s) = %ld %s (%m)\n",
+ printf("%s%s(%s, \"%s\", %s, \"%s\", %s) = %ld %s (%m)\n",
+ my_secontext, "linkat",
"AT_FDCWD", sample_1, "AT_FDCWD", sample_2,
"AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW"
"|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE|0xffff60ff",
rc, errno2name());
+ /*
+ * Tests with AT_FDCWD.
+ */
+
+ int fd_sample_1 = open(sample_1, O_RDONLY | O_CREAT, 0400);
+ if (fd_sample_1 < 0)
+ perror_msg_and_fail("open");
+ if (close(fd_sample_1))
+ perror_msg_and_fail("close");
+
+ char *sample_1_secontext = SECONTEXT_FILE(sample_1);
+
+ rc = syscall(__NR_linkat, -100, sample_1, -100, sample_2, 0);
+ /* no context printed for sample_2 since file doesn't exist yet */
+ printf("%s%s(AT_FDCWD, \"%s\"%s, AT_FDCWD, \"%s\", 0) = %s\n",
+ my_secontext, "linkat",
+ sample_1, sample_1_secontext,
+ sample_2,
+ sprintrc(rc));
+
+ const char *sample_2_secontext = sample_1_secontext;
+
+ rc = syscall(__NR_linkat, -100, sample_1, -100, sample_2, 0);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, AT_FDCWD, \"%s\"%s, 0) = %s\n",
+ my_secontext, "linkat",
+ sample_1, sample_1_secontext,
+ sample_2, sample_2_secontext,
+ sprintrc(rc));
+
+ int fd_sample_2 = open(sample_2, O_RDONLY | O_CREAT, 0400);
+ if (fd_sample_2 < 0)
+ perror_msg_and_fail("open");
+ if (close(fd_sample_2))
+ perror_msg_and_fail("close");
+
+ free(sample_1_secontext);
+ update_secontext_type(sample_1, "default_t");
+ sample_1_secontext = SECONTEXT_FILE(sample_1);
+ sample_2_secontext = sample_1_secontext;
+
+ rc = syscall(__NR_linkat, -100, sample_1, -100, sample_2, 0);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, AT_FDCWD, \"%s\"%s, 0) = %s\n",
+ my_secontext, "linkat",
+ sample_1, sample_1_secontext,
+ sample_2, sample_2_secontext,
+ sprintrc(rc));
+
+ if (unlink(sample_2))
+ perror_msg_and_fail("unlink: %s", sample_2);
+
+ /*
+ * Tests with dirfd.
+ */
+
+ int dfd_old = get_dir_fd(".");
+ char *cwd = get_fd_path(dfd_old);
+ char *dfd_old_secontext = SECONTEXT_FILE(".");
+
+ rc = syscall(__NR_linkat, dfd_old, sample_1, -100, sample_2, 0);
+ /* no context printed for sample_2 since file doesn't exist yet */
+ printf("%s%s(%d%s, \"%s\"%s, AT_FDCWD, \"%s\", 0) = %s\n",
+ my_secontext, "linkat",
+ dfd_old, dfd_old_secontext,
+ sample_1, sample_1_secontext,
+ sample_2,
+ sprintrc(rc));
+
+ rc = syscall(__NR_linkat, dfd_old, sample_1, -100, sample_2, 0);
+ printf("%s%s(%d%s, \"%s\"%s, AT_FDCWD, \"%s\"%s, 0) = %s\n",
+ my_secontext, "linkat",
+ dfd_old, dfd_old_secontext,
+ sample_1, sample_1_secontext,
+ sample_2, sample_2_secontext,
+ sprintrc(rc));
+
+ if (unlink(sample_2))
+ perror_msg_and_fail("unlink: %s", sample_2);
+
+ static const char new_dir[] = "new";
+ char *new_sample_2 = xasprintf("%s/%s", new_dir, sample_2);
+
+ (void) unlink(new_sample_2);
+ (void) rmdir(new_dir);
+
+ if (mkdir(new_dir, 0700))
+ perror_msg_and_fail("mkdir");
+ char *new_dir_realpath = xasprintf("%s/%s", cwd, new_dir);
+ char *new_dir_secontext = SECONTEXT_FILE(new_dir);
+ int dfd_new = get_dir_fd(new_dir);
+
+ rc = syscall(__NR_linkat, dfd_old, sample_1, dfd_new, sample_2, 0);
+ /* no context printed for sample_2 since file doesn't exist yet */
+ printf("%s%s(%d%s, \"%s\"%s, %d%s, \"%s\", 0) = %s\n",
+ my_secontext, "linkat",
+ dfd_old, dfd_old_secontext,
+ sample_1, sample_1_secontext,
+ dfd_new, new_dir_secontext,
+ sample_2,
+ sprintrc(rc));
+
+ rc = syscall(__NR_linkat, dfd_old, sample_1, dfd_new, sample_2, 0);
+ printf("%s%s(%d%s, \"%s\"%s, %d%s, \"%s\"%s, 0) = %s\n",
+ my_secontext, "linkat",
+ dfd_old, dfd_old_secontext,
+ sample_1, sample_1_secontext,
+ dfd_new, new_dir_secontext,
+ sample_2, SECONTEXT_FILE(new_sample_2),
+ sprintrc(rc));
+
+ char *new_sample_2_realpath = xasprintf("%s/%s", new_dir_realpath, sample_2);
+
+ /* dfd ignored when path is absolute */
+ if (chdir("../.."))
+ perror_msg_and_fail("chdir");
+
+ rc = syscall(__NR_linkat, dfd_old, sample_1, -100, new_sample_2_realpath, 0);
+ printf("%s%s(%d%s, \"%s\"%s, AT_FDCWD, \"%s\"%s, 0) = %s\n",
+ my_secontext, "linkat",
+ dfd_old, dfd_old_secontext,
+ sample_1, sample_1_secontext,
+ new_sample_2_realpath, SECONTEXT_FILE(new_sample_2_realpath),
+ sprintrc(rc));
+
+ if (fchdir(dfd_old))
+ perror_msg_and_fail("fchdir");
+
+ if (unlink(sample_1))
+ perror_msg_and_fail("unlink: %s", sample_1);
+ if (unlink(new_sample_2))
+ perror_msg_and_fail("unlink: %s", new_sample_2);
+ if (rmdir(new_dir))
+ perror_msg_and_fail("rmdir: %s", new_dir);
+
leave_and_remove_subdir();
puts("+++ exited with 0 +++");
diff --git a/tests/open.c b/tests/open.c
index 3fce327ba..5c7295395 100644
--- a/tests/open.c
+++ b/tests/open.c
@@ -15,6 +15,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
int
main(void)
{
@@ -25,10 +27,12 @@ main(void)
create_and_enter_subdir("open_subdir");
static const char sample[] = "open.sample";
+ char *my_secontext = SECONTEXT_PID_MY();
long fd = syscall(__NR_open, sample, O_RDONLY|O_CREAT, 0400);
- printf("open(\"%s\", O_RDONLY|O_CREAT, 0400) = %s\n",
- sample, sprintrc(fd));
+ printf("%s%s(\"%s\", O_RDONLY|O_CREAT, 0400) = %s%s\n",
+ my_secontext, "open",
+ sample, sprintrc(fd), SECONTEXT_FILE(sample));
if (fd != -1) {
close(fd);
@@ -36,16 +40,18 @@ main(void)
perror_msg_and_fail("unlink");
fd = syscall(__NR_open, sample, O_RDONLY);
- printf("open(\"%s\", O_RDONLY) = %s\n", sample, sprintrc(fd));
+ printf("%s%s(\"%s\", O_RDONLY) = %s\n",
+ my_secontext, "open", sample, sprintrc(fd));
fd = syscall(__NR_open, sample, O_WRONLY|O_NONBLOCK|0x80000000);
- printf("open(\"%s\", O_WRONLY|O_NONBLOCK|0x80000000) = %s\n",
- sample, sprintrc(fd));
+ printf("%s%s(\"%s\", O_WRONLY|O_NONBLOCK|0x80000000) = %s\n",
+ my_secontext, "open", sample, sprintrc(fd));
}
# ifdef O_TMPFILE
fd = syscall(__NR_open, sample, O_WRONLY|O_TMPFILE, 0600);
- printf("open(\"%s\", O_WRONLY|O_TMPFILE, 0600) = %s\n",
+ printf("%s%s(\"%s\", O_WRONLY|O_TMPFILE, 0600) = %s\n",
+ my_secontext, "open",
sample, sprintrc(fd));
# endif /* O_TMPFILE */
diff --git a/tests/openat.c b/tests/openat.c
index 0c4bb3d10..b43055d3c 100644
--- a/tests/openat.c
+++ b/tests/openat.c
@@ -15,6 +15,8 @@
# include <stdio.h>
# include <unistd.h>
+# include "secontext.h"
+
# ifdef O_TMPFILE
/* The kernel & C libraries often inline O_DIRECTORY. */
# define STRACE_O_TMPFILE (O_TMPFILE & ~O_DIRECTORY)
@@ -26,10 +28,12 @@ static const char sample[] = "openat.sample";
static void
test_mode_flag(unsigned int mode_val, const char *mode_str,
- unsigned int flag_val, const char *flag_str)
+ unsigned int flag_val, const char *flag_str,
+ const char *my_secontext)
{
long rc = syscall(__NR_openat, -1, sample, mode_val | flag_val, 0);
- printf("openat(-1, \"%s\", %s%s%s%s) = %s\n",
+ printf("%s%s(-1, \"%s\", %s%s%s%s) = %s\n",
+ my_secontext, "openat",
sample, mode_str,
flag_val ? "|" : "", flag_str,
flag_val & (O_CREAT | STRACE_O_TMPFILE) ? ", 000" : "",
@@ -45,20 +49,7 @@ main(void)
*/
create_and_enter_subdir("openat_subdir");
- long fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
- printf("openat(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400) = %s\n",
- sample, sprintrc(fd));
-
- if (fd != -1) {
- close(fd);
- if (unlink(sample) == -1)
- perror_msg_and_fail("unlink");
-
- fd = syscall(__NR_openat, -100, sample, O_RDONLY);
- printf("openat(AT_FDCWD, \"%s\", O_RDONLY) = %s\n",
- sample, sprintrc(fd));
- }
-
+ char *my_secontext = SECONTEXT_PID_MY();
struct {
unsigned int val;
const char *str;
@@ -105,7 +96,73 @@ main(void)
for (unsigned int m = 0; m < ARRAY_SIZE(modes); ++m)
for (unsigned int f = 0; f < ARRAY_SIZE(flags); ++f)
test_mode_flag(modes[m].val, modes[m].str,
- flags[f].val, flags[f].str);
+ flags[f].val, flags[f].str,
+ my_secontext);
+
+ /*
+ * Tests with AT_FDCWD.
+ */
+
+ (void) unlink(sample);
+ long fd = syscall(__NR_openat, -100, sample, O_RDONLY|O_CREAT, 0400);
+
+ char *sample_secontext = SECONTEXT_FILE(sample);
+
+ /*
+ * File context in openat() is not displayed because file doesn't exist
+ * yet, but is displayed in return value since the file got created.
+ */
+ printf("%s%s(AT_FDCWD, \"%s\", O_RDONLY|O_CREAT, 0400) = %s%s\n",
+ my_secontext, "openat",
+ sample,
+ sprintrc(fd), sample_secontext);
+
+ close(fd);
+
+ fd = syscall(__NR_openat, -100, sample, O_RDONLY);
+ printf("%s%s(AT_FDCWD, \"%s\"%s, O_RDONLY) = %s%s\n",
+ my_secontext, "openat",
+ sample, sample_secontext,
+ sprintrc(fd), sample_secontext);
+ if (fd != -1) {
+ close(fd);
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+ }
+
+ /*
+ * Tests with dirfd.
+ */
+
+ int cwd_fd = get_dir_fd(".");
+ char *cwd_secontext = SECONTEXT_FILE(".");
+
+ fd = syscall(__NR_openat, cwd_fd, sample, O_RDONLY|O_CREAT, 0400);
+ if (fd == -1)
+ perror_msg_and_fail("openat");
+ close(fd);
+
+ /*
+ * File context in openat() is not displayed because file doesn't exist
+ * yet, but is displayed in return value since the file got created.
+ */
+ printf("%s%s(%d%s, \"%s\", O_RDONLY|O_CREAT, 0400) = %s%s\n",
+ my_secontext, "openat",
+ cwd_fd, cwd_secontext,
+ sample,
+ sprintrc(fd), sample_secontext);
+
+ fd = syscall(__NR_openat, cwd_fd, sample, O_RDONLY);
+ printf("%s%s(%d%s, \"%s\"%s, O_RDONLY) = %s%s\n",
+ my_secontext, "openat",
+ cwd_fd, cwd_secontext,
+ sample, sample_secontext,
+ sprintrc(fd), sample_secontext);
+ if (fd != -1) {
+ close(fd);
+ if (unlink(sample))
+ perror_msg_and_fail("unlink");
+ }
leave_and_remove_subdir();
diff --git a/tests/options-syntax.test b/tests/options-syntax.test
index 4c071ac5a..765b2f867 100755
--- a/tests/options-syntax.test
+++ b/tests/options-syntax.test
@@ -3,13 +3,15 @@
# Check strace options syntax.
#
# Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
-# Copyright (c) 2016-2020 The strace developers.
+# Copyright (c) 2016-2021 The strace developers.
# All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0-or-later
. "${srcdir=.}/syntax.sh"
+compiled_with_secontext=$(get_config_option ENABLE_SECONTEXT "y")
+
check_e "Invalid process id: '0'" -p 0
check_e "Invalid process id: '0'" --attach=0
check_e "Invalid process id: '-42'" -p -42
@@ -46,6 +48,8 @@ check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --ti
check_e '-t and --absolute-timestamps cannot be provided simultaneously' --absolute-timestamps -ttt -p $$
check_e '-t and --absolute-timestamps cannot be provided simultaneously' -t --timestamps=ns -t -p $$
check_e '-t and --absolute-timestamps cannot be provided simultaneously' --timestamps=ns -t --absolute-timestamps=unix -p $$
+[ -z "$compiled_with_secontext" ] ||
+ check_h "invalid --secontext argument: 'ss'" --secontext=ss
check_h 'PROG [ARGS] must be specified with -D/--daemonize' -D -p $$
check_h 'PROG [ARGS] must be specified with -D/--daemonize' -DD -p $$
check_h 'PROG [ARGS] must be specified with -D/--daemonize' -DDD -p $$
@@ -282,6 +286,11 @@ $STRACE_EXE: -y/--decode-fds has no effect with -c/--summary-only
$STRACE_EXE: Only the last of -z/--successful-only/-Z/--failed-only options will take effect. See status qualifier for more complex filters.
$STRACE_EXE: $umsg" -u :nosuchuser: -cinrtTyzZ true
+ if [ -n "$compiled_with_secontext" ]; then
+ check_e "--secontext has no effect with -c/--summary-only
+$STRACE_EXE: $umsg" -u :nosuchuser: -c --secontext true
+ fi
+
for c in --output-separately -A/--output-append-mode; do
check_e "$c has no effect without -o/--output
$STRACE_EXE: $umsg" -u :nosuchuser: ${c%%/*} true
diff --git a/tests/secontext.c b/tests/secontext.c
new file mode 100644
index 000000000..21c6370c9
--- /dev/null
+++ b/tests/secontext.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#ifdef HAVE_SELINUX_RUNTIME
+
+# include <assert.h>
+# include <errno.h>
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+# include <selinux/selinux.h>
+
+# include "xmalloc.h"
+
+# define TEST_SECONTEXT
+# include "secontext.h"
+
+static char *
+secontext_format(char *context, const char *fmt)
+ ATTRIBUTE_FORMAT((printf, 2, 0)) ATTRIBUTE_MALLOC;
+
+static char *
+secontext_format(char *context, const char *fmt)
+{
+ int saved_errno = errno;
+ char *res = context ? xasprintf(fmt, context) : xstrdup("");
+ free(context);
+ errno = saved_errno;
+ return res;
+}
+
+# define FORMAT_SPACE_BEFORE(string) secontext_format(string, " [%s]")
+# define FORMAT_SPACE_AFTER(string) secontext_format(string, "[%s] ")
+
+static char *
+strip_trailing_newlines(char *context)
+{
+ /*
+ * On the CI at least, the context may have a trailing \n,
+ * let's remove it just in case.
+ */
+ size_t len = strlen(context);
+ for (; len > 0; --len) {
+ if (context[len - 1] != '\n')
+ break;
+ }
+ context[len] = '\0';
+ return context;
+}
+
+static char *
+raw_secontext_full_file(const char *filename)
+{
+ int saved_errno = errno;
+ char *full_secontext = NULL;
+ char *secontext;
+
+ if (getfilecon(filename, &secontext) >= 0) {
+ full_secontext = strip_trailing_newlines(xstrdup(secontext));
+ freecon(secontext);
+ }
+ errno = saved_errno;
+ return full_secontext;
+}
+
+static char *
+raw_secontext_short_file(const char *filename)
+{
+ int saved_errno = errno;
+
+ char *ctx = raw_secontext_full_file(filename);
+ if (ctx == NULL)
+ return ctx;
+
+ char *saveptr = NULL;
+ const char *token;
+ unsigned int i;
+
+ char *ctx_copy = xstrdup(ctx);
+ char *context = NULL;
+ for (token = strtok_r(ctx_copy, ":", &saveptr), i = 0;
+ token; token = strtok_r(NULL, ":", &saveptr), i++) {
+ if (i == 2) {
+ context = xstrdup(token);
+ break;
+ }
+ }
+ if (context == NULL)
+ context = xstrdup(ctx);
+ free(ctx_copy);
+ free(ctx);
+
+ errno = saved_errno;
+ return context;
+}
+
+static char *
+raw_secontext_full_pid(pid_t pid)
+{
+ int saved_errno = errno;
+ char *full_secontext = NULL;
+ char *secontext;
+
+ if (getpidcon(pid, &secontext) == 0) {
+ full_secontext = strip_trailing_newlines(xstrdup(secontext));
+ freecon(secontext);
+ }
+ errno = saved_errno;
+ return full_secontext;
+}
+
+static char *
+raw_secontext_short_pid(pid_t pid)
+{
+ int saved_errno = errno;
+
+ char *ctx = raw_secontext_full_pid(pid);
+ if (ctx == NULL)
+ return ctx;
+
+ char *saveptr = NULL;
+ const char *token;
+ int i;
+
+ char *ctx_copy = xstrdup(ctx);
+ char *context = NULL;
+ for (token = strtok_r(ctx_copy, ":", &saveptr), i = 0;
+ token; token = strtok_r(NULL, ":", &saveptr), i++) {
+ if (i == 2) {
+ context = xstrdup(token);
+ break;
+ }
+ }
+ if (context == NULL)
+ context = xstrdup(ctx);
+ free(ctx_copy);
+ free(ctx);
+
+ errno = saved_errno;
+ return context;
+}
+
+char *
+secontext_full_file(const char *filename)
+{
+ return FORMAT_SPACE_BEFORE(raw_secontext_full_file(filename));
+}
+
+char *
+secontext_full_pid(pid_t pid)
+{
+ return FORMAT_SPACE_AFTER(raw_secontext_full_pid(pid));
+}
+
+char *
+secontext_short_file(const char *filename)
+{
+ return FORMAT_SPACE_BEFORE(raw_secontext_short_file(filename));
+}
+
+char *
+secontext_short_pid(pid_t pid)
+{
+ return FORMAT_SPACE_AFTER(raw_secontext_short_pid(pid));
+}
+
+void
+update_secontext_type(const char *file, const char *newtype)
+{
+ char *ctx = raw_secontext_full_file(file);
+ if (ctx == NULL)
+ return;
+
+ char *saveptr = NULL;
+ char *token;
+ int field;
+ char *split[4];
+
+ for (token = strtok_r(ctx, ":", &saveptr), field = 0;
+ token; token = strtok_r(NULL, ":", &saveptr), field++) {
+ assert(field < 4);
+ split[field] = token;
+ }
+ assert(field == 4);
+
+ char *newcontext = xasprintf("%s:%s:%s:%s", split[0], split[1],
+ newtype, split[3]);
+
+ (void) setfilecon(file, newcontext);
+
+ free(newcontext);
+ free(ctx);
+}
+
+#endif /* HAVE_SELINUX_RUNTIME */
diff --git a/tests/secontext.h b/tests/secontext.h
new file mode 100644
index 000000000..64bcd060f
--- /dev/null
+++ b/tests/secontext.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "xmalloc.h"
+#include <unistd.h>
+
+#if defined TEST_SECONTEXT && defined HAVE_SELINUX_RUNTIME
+
+void update_secontext_type(const char *file, const char *newtype);
+
+# ifdef PRINT_SECONTEXT_FULL
+
+char *secontext_full_file(const char *) ATTRIBUTE_MALLOC;
+char *secontext_full_pid(pid_t) ATTRIBUTE_MALLOC;
+
+# define SECONTEXT_FILE(filename) secontext_full_file(filename)
+# define SECONTEXT_PID(pid) secontext_full_pid(pid)
+
+# else
+
+char *secontext_short_file(const char *) ATTRIBUTE_MALLOC;
+char *secontext_short_pid(pid_t) ATTRIBUTE_MALLOC;
+
+# define SECONTEXT_FILE(filename) secontext_short_file(filename)
+# define SECONTEXT_PID(pid) secontext_short_pid(pid)
+
+# endif
+
+#else
+
+static inline void
+update_secontext_type(const char *file, const char *newtype)
+{
+}
+
+# define SECONTEXT_FILE(filename) xstrdup("")
+# define SECONTEXT_PID(pid) xstrdup("")
+
+#endif
+
+#define SECONTEXT_PID_MY() SECONTEXT_PID(getpid())
diff --git a/tests/strace-V.test b/tests/strace-V.test
index 30f10808c..fdac7a3e4 100755
--- a/tests/strace-V.test
+++ b/tests/strace-V.test
@@ -33,7 +33,9 @@ aarch64|powerpc64|s390x|sparc64|tile|x32)
;;
esac
-features="${option_unwind}${option_demangle}${option_m32}${option_mx32}"
+option_secontext=$(get_config_option ENABLE_SECONTEXT " secontext")
+
+features="${option_unwind}${option_demangle}${option_m32}${option_mx32}${option_secontext}"
[ -n "$features" ] || features=" (none)"
cat > "$EXP" << __EOF__