[PATCH v4 2/2] tests: improve test coverage of prctl syscall decoder

Srikavin Ramkumar srikavinramkumar at gmail.com
Mon Jul 12 16:14:25 UTC 2021


Add tests for PR_CAP_AMBIENT, PR_CAPBSET_READ, PR_CAPBSET_DROP,
PR_[GS]ET_FP_MODE, PR_MCE_KILL, PR_SVE_[GS]ET_VL, PR_[GS]ET_UNALIGN.

* tests/.gitignore: Add prctl-cap-ambient, prctl-capbset, prctl-fp-mode,
prctl-mce-kill, prctl-sve, and prctl-unalign.
* tests/Makefile.am (check_PROGRAMS): Add prctl-fp-mode.
(DECODER_TESTS): Add prctl-fp-mode.test.
* tests/pure_executables.list: Add prctl-cap-ambient, prctl-capbset,
prctl-mce-kill, prctl-sve, and prctl-unalign.
* tests/gen_tests.in (prctl-cap-ambient, prctl-capbset, prctl-mce-kill,
prctl-sve, prctl-unalign): New entries.
* tests/prctl-cap-ambient.c: New file.
* tests/prctl-capbset.c: Likewise.
* tests/prctl-fp-mode.c: Likewise.
* tests/prctl-fp-mode.test: Likewise.
* tests/prctl-mce-kill.c: Likewise.
* tests/prctl-sve.c: Likewise.
* tests/prctl-unalign.c: Likewise.
---
 tests/.gitignore            |  6 +++
 tests/Makefile.am           |  2 +
 tests/gen_tests.in          |  5 ++
 tests/prctl-cap-ambient.c   | 80 ++++++++++++++++++++++++++++++
 tests/prctl-capbset.c       | 50 +++++++++++++++++++
 tests/prctl-fp-mode.c       | 98 +++++++++++++++++++++++++++++++++++++
 tests/prctl-fp-mode.test    | 32 ++++++++++++
 tests/prctl-mce-kill.c      | 61 +++++++++++++++++++++++
 tests/prctl-sve.c           | 55 +++++++++++++++++++++
 tests/prctl-unalign.c       | 51 +++++++++++++++++++
 tests/pure_executables.list |  5 ++
 11 files changed, 445 insertions(+)
 create mode 100644 tests/prctl-cap-ambient.c
 create mode 100644 tests/prctl-capbset.c
 create mode 100644 tests/prctl-fp-mode.c
 create mode 100755 tests/prctl-fp-mode.test
 create mode 100644 tests/prctl-mce-kill.c
 create mode 100644 tests/prctl-sve.c
 create mode 100644 tests/prctl-unalign.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 8f2472b64..6f4c3d217 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -599,7 +599,11 @@ ppoll
 ppoll-P
 ppoll-v
 prctl-arg2-intptr
+prctl-cap-ambient
+prctl-capbset
 prctl-dumpable
+prctl-fp-mode
+prctl-mce-kill
 prctl-name
 prctl-no-args
 prctl-pdeathsig
@@ -607,8 +611,10 @@ prctl-seccomp-filter-v
 prctl-seccomp-strict
 prctl-securebits
 prctl-spec-inject
+prctl-sve
 prctl-tid_address
 prctl-tsc
+prctl-unalign
 pread64-pwrite64
 preadv
 preadv-pwritev
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 86687c800..8e4a00b4d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -235,6 +235,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	poll-P \
 	ppoll-P \
 	ppoll-v \
+	prctl-fp-mode \
 	prctl-seccomp-filter-v \
 	prctl-seccomp-strict \
 	prctl-spec-inject \
@@ -418,6 +419,7 @@ DECODER_TESTS = \
 	pipe.test \
 	poll-P.test \
 	poll.test \
+	prctl-fp-mode.test \
 	prctl-seccomp-strict.test \
 	prctl-spec-inject.test \
 	qual_fault-exit_group.test \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 125a0a5f2..23cd2da44 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -565,14 +565,19 @@ ppoll	-s2
 ppoll-P	-s2 -e trace=ppoll -P /dev/full 9>>/dev/full
 ppoll-v	-v -s2 -e trace=ppoll
 prctl-arg2-intptr	    +prctl.sh -a25
+prctl-cap-ambient   	+prctl.sh -a21
+prctl-capbset   		+prctl.sh -a21
 prctl-dumpable		    +prctl.sh -a23
+prctl-mce-kill  		+prctl.sh -a21
 prctl-name			    +prctl.sh -a23
 prctl-no-args		    +prctl.sh -a21
 prctl-pdeathsig		    +prctl.sh -a30
 prctl-seccomp-filter-v	+prctl.sh -v
 prctl-securebits    	+prctl.sh -a25
+prctl-sve   			+prctl.sh -a21
 prctl-tid_address   	+prctl.sh -a23
 prctl-tsc		    	+prctl.sh -a24
+prctl-unalign   		+prctl.sh -a28
 pread64-pwrite64	-a21 -eread=0 -ewrite=1 -e trace=pread64,pwrite64 -P pread64-pwrite64-tmpfile -P /dev/zero -P /dev/null
 preadv	-a21
 preadv-pwritev	-a19 -eread=0 -ewrite=1 -e trace=preadv,pwritev
diff --git a/tests/prctl-cap-ambient.c b/tests/prctl-cap-ambient.c
new file mode 100644
index 000000000..70acfa167
--- /dev/null
+++ b/tests/prctl-cap-ambient.c
@@ -0,0 +1,80 @@
+/*
+ * Check decoding of prctl PR_CAP_AMBIENT operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+#include <linux/capability.h>
+
+int
+main(void)
+{
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	long rc;
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE,
+				 CAP_NET_RAW, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_NET_RAW, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE,
+				 CAP_AUDIT_CONTROL, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, CAP_AUDIT_CONTROL, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, 0xff, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, 0xff /* CAP_??? */, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER,
+				 CAP_NET_RAW, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, CAP_NET_RAW, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER,
+				 CAP_KILL, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, CAP_KILL, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, 0xff, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, 0xff /* CAP_??? */, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET,
+				 CAP_NET_RAW, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_NET_RAW, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET,
+				 CAP_AUDIT_CONTROL, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_AUDIT_CONTROL, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0xff, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, 0xff /* CAP_??? */, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, 0xff, 0xaaaa, 0, 0);
+	printf("prctl(PR_CAP_AMBIENT, 0xff /* PR_CAP_AMBIENT_??? */, 0xaaaa, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAP_AMBIENT, 0xff, 0xaaaa, 0xbbbb, 0xcccc);
+	printf("prctl(PR_CAP_AMBIENT, 0xff /* PR_CAP_AMBIENT_??? */, 0xaaaa, 0xbbbb, 0xcccc) = %s\n",
+		   sprintrc(rc));
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/prctl-capbset.c b/tests/prctl-capbset.c
new file mode 100644
index 000000000..b82259761
--- /dev/null
+++ b/tests/prctl-capbset.c
@@ -0,0 +1,50 @@
+/*
+ * Check decoding of prctl PR_CAPBSET_READ/PR_CAPBSET_DROP operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+#include <linux/capability.h>
+
+int
+main(void)
+{
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	long rc;
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_READ, CAP_AUDIT_CONTROL);
+	printf("prctl(PR_CAPBSET_READ, CAP_AUDIT_CONTROL) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_READ, CAP_NET_RAW);
+	printf("prctl(PR_CAPBSET_READ, CAP_NET_RAW) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_READ, 0xff);
+	printf("prctl(PR_CAPBSET_READ, 0xff /* CAP_??? */) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_DROP, CAP_AUDIT_CONTROL);
+	printf("prctl(PR_CAPBSET_DROP, CAP_AUDIT_CONTROL) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_DROP, CAP_NET_RAW);
+	printf("prctl(PR_CAPBSET_DROP, CAP_NET_RAW) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_CAPBSET_DROP, 0xff);
+	printf("prctl(PR_CAPBSET_DROP, 0xff /* CAP_??? */) = %s\n",
+		   sprintrc(rc));
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/prctl-fp-mode.c b/tests/prctl-fp-mode.c
new file mode 100644
index 000000000..aa4b92c74
--- /dev/null
+++ b/tests/prctl-fp-mode.c
@@ -0,0 +1,98 @@
+/*
+ * Check decoding of prctl PR_GET_FP_MODE/PR_SET_FP_MODE operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+
+static long injected_val;
+
+static long
+do_prctl(kernel_ulong_t cmd, kernel_ulong_t arg2, kernel_ulong_t arg3)
+{
+	long rc = syscall(__NR_prctl, cmd, arg2, arg3);
+
+	if (rc != injected_val)
+		error_msg_and_fail("Return value (%ld) differs from expected "
+						   "injected value (%ld)",
+						   rc, injected_val);
+
+	return rc;
+}
+
+int
+main(int argc, char **argv)
+{
+	static const kernel_ulong_t bogus_arg2 =
+			(kernel_ulong_t) 0xdecafeedbeefda7eULL;
+	static const kernel_ulong_t bogus_arg3 =
+			(kernel_ulong_t) 0xdecafeedbeefda7eULL;
+
+	static const struct {
+		long arg;
+		const char *str;
+	} get_strs[] = {
+			{-1,       ""},
+			{0,        ""},
+			{1,        " (PR_FP_MODE_FR)"},
+			{2,        " (PR_FP_MODE_FRE)"},
+			{3,        " (PR_FP_MODE_FR|PR_FP_MODE_FRE)"},
+			{0x20,     " (0x20)"},
+			{0x20 | 3, " (PR_FP_MODE_FR|PR_FP_MODE_FRE|0x20)"}
+	};
+	static const struct {
+		kernel_ulong_t arg;
+		const char *str;
+	} set_strs[] = {
+			{0,        "0"},
+			{1,        "PR_FP_MODE_FR"},
+			{2,        "PR_FP_MODE_FRE"},
+			{3,        "PR_FP_MODE_FR|PR_FP_MODE_FRE"},
+			{0x20,     "0x20 /* PR_FP_MODE_??? */"},
+			{0x20 | 3, "PR_FP_MODE_FR|PR_FP_MODE_FRE|0x20"}
+	};
+
+	long rc;
+	const char *str = NULL;
+
+	if (argc < 2)
+		error_msg_and_fail("Usage: %s INJECTED_VAL", argv[0]);
+
+	injected_val = strtol(argv[1], NULL, 0);
+
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	/* PR_GET_FP_MODE */
+	rc = do_prctl(PR_GET_FP_MODE, bogus_arg2, bogus_arg3);
+
+	for (size_t i = 0; i < ARRAY_SIZE(get_strs); i++) {
+		if (get_strs[i].arg == rc) {
+			str = get_strs[i].str;
+			break;
+		}
+	}
+	if (!str)
+		error_msg_and_fail("Unknown return value: %ld", rc);
+
+	printf("prctl(PR_GET_FP_MODE) = %s%s (INJECTED)\n", sprintrc(rc), str);
+
+	/* PR_SET_FP_MODE */
+	for (size_t i = 0; i < ARRAY_SIZE(set_strs); i++) {
+		rc = do_prctl(PR_SET_FP_MODE, set_strs[i].arg, bogus_arg3);
+
+		printf("prctl(PR_SET_FP_MODE, %s) = %s (INJECTED)\n", set_strs[i].str,
+			   sprintrc(rc));
+	}
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/prctl-fp-mode.test b/tests/prctl-fp-mode.test
new file mode 100755
index 000000000..ce6c786b9
--- /dev/null
+++ b/tests/prctl-fp-mode.test
@@ -0,0 +1,32 @@
+#!/bin/sh -efu
+#
+# Check decoding of prctl PR_GET_FP_MODE/PR_SET_FP_MODE operations.
+#
+# Copyright (c) 2021 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/scno_tampering.sh"
+
+fault_args='-a21 -e trace=prctl -e inject=prctl:'
+prog="../$NAME"
+
+test_run_rval()
+{
+	local rval injexpr
+	rval="$1"; shift
+	injexpr="$1"; shift
+
+	run_strace $fault_args$injexpr $prog $rval > "$EXP"
+	sed '0,/^prctl(0xffffffff \/\* PR_??? \*\/, 0xfffffffe, 0xfffffffd, 0xfffffffc, 0xfffffffb) = .\+ (INJECTED)/d' < "$LOG" > "$OUT"
+	match_diff "$OUT" "$EXP"
+}
+
+test_run_rval -1 "error=ENOTTY"
+test_run_rval 0 "retval=0"
+test_run_rval 1 "retval=1"
+test_run_rval 2 "retval=2"
+test_run_rval 3 "retval=3"
+test_run_rval 32 "retval=32"
+test_run_rval 35 "retval=35"
diff --git a/tests/prctl-mce-kill.c b/tests/prctl-mce-kill.c
new file mode 100644
index 000000000..e21641b17
--- /dev/null
+++ b/tests/prctl-mce-kill.c
@@ -0,0 +1,61 @@
+/*
+ * Check decoding of prctl PR_MCE_KILL/PR_MCE_KILL_GET operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+
+int
+main(void)
+{
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	long rc;
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0, 0);
+	printf("prctl(PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0);
+	printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_LATE, 0, 0);
+	printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_LATE, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, 0xff, 0, 0);
+	printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, 0xff /* PR_MCE_KILL_??? */, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd);
+	printf("prctl(PR_MCE_KILL, 0xaaaa /* PR_MCE_KILL_??? */, 0xbbbb, 0xcccc, 0xdddd) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_DEFAULT, 0, 0);
+	printf("prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_DEFAULT, 0, 0) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL_GET, 0, 0, 0, 0);
+	if (rc)
+		printf("prctl(PR_MCE_KILL_GET, 0, 0, 0, 0) = %s (PR_MCE_KILL_DEFAULT)\n",
+			   sprintrc(rc));
+	else
+		printf("prctl(PR_MCE_KILL_GET, 0, 0, 0, 0) = %s\n",
+			   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_MCE_KILL_GET, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd);
+	printf("prctl(PR_MCE_KILL_GET, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd) = %s\n",
+		   sprintrc(rc));
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/prctl-sve.c b/tests/prctl-sve.c
new file mode 100644
index 000000000..4e5bbdb3f
--- /dev/null
+++ b/tests/prctl-sve.c
@@ -0,0 +1,55 @@
+/*
+ * Check decoding of prctl PR_SVE_SET_VL/PR_SVE_GET_VL operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+
+int
+main(void)
+{
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	long rc;
+
+	rc = syscall(__NR_prctl, PR_SVE_SET_VL, 0xf);
+	printf("prctl(PR_SVE_SET_VL, %#lx) = %s\n", (unsigned long) 0xf,
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SVE_SET_VL, 0xff);
+	printf("prctl(PR_SVE_SET_VL, %#lx) = %s\n", (unsigned long) 0xff,
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SVE_SET_VL, PR_SVE_SET_VL_ONEXEC | 0xff);
+	printf("prctl(PR_SVE_SET_VL, PR_SVE_SET_VL_ONEXEC|%#lx) = %s\n",
+		   (unsigned long) 0xff, sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SVE_SET_VL, PR_SVE_VL_INHERIT | 0xff);
+	printf("prctl(PR_SVE_SET_VL, PR_SVE_VL_INHERIT|%#lx) = %s\n",
+		   (unsigned long) 0xff, sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SVE_SET_VL,
+				 PR_SVE_SET_VL_ONEXEC | PR_SVE_VL_INHERIT | 0xff);
+	printf("prctl(PR_SVE_SET_VL, "
+		   "PR_SVE_SET_VL_ONEXEC|PR_SVE_VL_INHERIT|%#lx) = %s\n",
+		   (unsigned long) 0xff, sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SVE_GET_VL);
+	printf("prctl(PR_SVE_GET_VL) = %s", sprintrc(rc));
+	if (rc >= 0) {
+		printf(" (PR_SVE_SET_VL_ONEXEC|PR_SVE_VL_INHERIT|%#lx)",
+			   (unsigned long) 0xff);
+	}
+	puts("");
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/prctl-unalign.c b/tests/prctl-unalign.c
new file mode 100644
index 000000000..9d008b2f1
--- /dev/null
+++ b/tests/prctl-unalign.c
@@ -0,0 +1,51 @@
+/*
+ * Check decoding of prctl PR_GET_UNALIGN/PR_SET_UNALIGN operations.
+ *
+ * Copyright (c) 2021 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "scno.h"
+#include <stdio.h>
+#include <unistd.h>
+#include <linux/prctl.h>
+
+int
+main(void)
+{
+	TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, unalign);
+
+	syscall(__NR_prctl, -1U, -2U, -3U, -4U, -5U);
+
+	long rc;
+
+	rc = syscall(__NR_prctl, PR_SET_UNALIGN, PR_UNALIGN_NOPRINT | PR_UNALIGN_SIGBUS);
+	printf("prctl(PR_SET_UNALIGN, PR_UNALIGN_NOPRINT|PR_UNALIGN_SIGBUS) = %s\n",
+		   sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SET_UNALIGN, 0xff00);
+	printf("prctl(PR_SET_UNALIGN, %#llx /* PR_UNALIGN_??? */) = %s\n",
+		   (unsigned long long) 0xff00, sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_SET_UNALIGN, PR_UNALIGN_SIGBUS);
+	printf("prctl(PR_SET_UNALIGN, PR_UNALIGN_SIGBUS) = %s\n", sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_GET_UNALIGN, unalign + 1);
+	printf("prctl(PR_GET_UNALIGN, %p) = %s\n", unalign + 1, sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_GET_UNALIGN, NULL);
+	printf("prctl(PR_GET_UNALIGN, NULL) = %s\n", sprintrc(rc));
+
+	rc = syscall(__NR_prctl, PR_GET_UNALIGN, unalign);
+	if (rc)
+		printf("prctl(PR_GET_UNALIGN, %p) = %s\n", unalign, sprintrc(rc));
+	else
+		printf("prctl(PR_GET_UNALIGN, [PR_UNALIGN_SIGBUS]) = %s\n",
+			   sprintrc(rc));
+
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index c59e11783..87759022f 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -452,13 +452,18 @@ poke-sendfile
 poll
 ppoll
 prctl-arg2-intptr
+prctl-cap-ambient
+prctl-capbset
 prctl-dumpable
+prctl-mce-kill
 prctl-name
 prctl-no-args
 prctl-pdeathsig
 prctl-securebits
+prctl-sve
 prctl-tid_address
 prctl-tsc
+prctl-unalign
 pread64-pwrite64
 preadv
 preadv-pwritev
-- 
2.25.1



More information about the Strace-devel mailing list