[LTP] [PATCH v2] Move prctl04 in seccomp testing suite

Andrea Cervesato
2024-06-11T07:39:04Z

From: Andrea Cervesato <andrea.cervesato@suse.com>

prictl04 has been renamed as seccomp01 and a test variant has been added
in order to support the seccomp() syscall, that is currently equivalent
to prctl(PR_SET_SECCOMP).

Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
This testing suite is aiming to test seccomp() syscall which is
supposed to wrap prctl(PR_SET_SECCOMP). Some parts have been moved from
prctl tesitng suite to a new seccomp testing suite and added a test
variant.
---
Changes in v2:
- more information about the current running variant
- Link to v1: https://lore.kernel.org/r/20240607-seccomp-v1-1-70063fea55ba@suse.com
---
runtest/syscalls | 3 +-
testcases/kernel/syscalls/prctl/.gitignore | 1 -
testcases/kernel/syscalls/seccomp/.gitignore | 1 +
testcases/kernel/syscalls/seccomp/Makefile | 7 ++
.../{prctl/prctl04.c => seccomp/seccomp01.c} | 85 +++++++++++++---------
5 files changed, 61 insertions(+), 36 deletions(-)

diff --git a/runtest/syscalls b/runtest/syscalls
index cf06ee563..a6614141a 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1021,7 +1021,6 @@ ppoll01 ppoll01
prctl01 prctl01
prctl02 prctl02
prctl03 prctl03
-prctl04 prctl04
prctl05 prctl05
prctl06 prctl06
prctl07 prctl07
@@ -1239,6 +1238,8 @@ sched_setattr01 sched_setattr01
sched_getattr01 sched_getattr01
sched_getattr02 sched_getattr02

+seccomp01 seccomp01
+
select01 select01
select02 select02
select03 select03
diff --git a/testcases/kernel/syscalls/prctl/.gitignore b/testcases/kernel/syscalls/prctl/.gitignore
index 50ee4bf60..8bcc22f98 100644
--- a/testcases/kernel/syscalls/prctl/.gitignore
+++ b/testcases/kernel/syscalls/prctl/.gitignore
@@ -1,7 +1,6 @@
/prctl01
/prctl02
/prctl03
-/prctl04
/prctl05
/prctl06
/prctl06_execve
diff --git a/testcases/kernel/syscalls/seccomp/.gitignore b/testcases/kernel/syscalls/seccomp/.gitignore
new file mode 100644
index 000000000..9196906cf
--- /dev/null
+++ b/testcases/kernel/syscalls/seccomp/.gitignore
@@ -0,0 +1 @@
+seccomp01
diff --git a/testcases/kernel/syscalls/seccomp/Makefile b/testcases/kernel/syscalls/seccomp/Makefile
new file mode 100644
index 000000000..8cf1b9024
--- /dev/null
+++ b/testcases/kernel/syscalls/seccomp/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+
+top_srcdir ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/prctl/prctl04.c b/testcases/kernel/syscalls/seccomp/seccomp01.c
similarity index 73%
rename from testcases/kernel/syscalls/prctl/prctl04.c
rename to testcases/kernel/syscalls/seccomp/seccomp01.c
index 8b135d611..73ee09c1d 100644
--- a/testcases/kernel/syscalls/prctl/prctl04.c
+++ b/testcases/kernel/syscalls/seccomp/seccomp01.c
@@ -2,12 +2,14 @@
/*
* Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
* Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/

/*\
* [Description]
*
- * Test PR_GET_SECCOMP and PR_SET_SECCOMP of prctl(2).
+ * Test PR_GET_SECCOMP and PR_SET_SECCOMP with both prctl(2) and seccomp().
+ * The second one is called via __NR_seccomp using tst_syscall().
*
* - If PR_SET_SECCOMP sets the SECCOMP_MODE_STRICT for the calling thread,
* the only system call that the thread is permitted to make are read(2),
@@ -35,6 +37,7 @@
#include <stdlib.h>
#include <stddef.h>
#include "tst_test.h"
+#include "tst_kconfig.h"
#include "lapi/syscalls.h"
#include "lapi/prctl.h"
#include "config.h"
@@ -62,11 +65,11 @@ static const struct sock_fprog strict = {
.filter = (struct sock_filter *)strict_filter
};

-static void check_strict_mode(int);
-static void check_filter_mode(int);
+static void check_strict_mode(int mode);
+static void check_filter_mode(int mode);

static struct tcase {
- void (*func_check)();
+ void (*func_check)(int mode);
int pass_flag;
int val;
int exp_signal;
@@ -94,8 +97,8 @@ static struct tcase {
"SECCOMP_MODE_FILTER doesn't permit exit()"}
};

-
-static int mode_filter_not_supported;
+static int strict_not_supported;
+static int filter_not_supported;

static void check_filter_mode_inherit(void)
{
@@ -122,13 +125,20 @@ static void check_strict_mode(int val)
int fd;
char buf[2];

+ if (strict_not_supported)
+ return;
+
fd = SAFE_OPEN(FNAME, O_RDWR | O_CREAT, 0666);

- TEST(prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT));
- if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO,
- "prctl(PR_SET_SECCOMP) sets SECCOMP_MODE_STRICT failed");
- return;
+ if (tst_variant == 1) {
+ TEST(tst_syscall(__NR_seccomp, SECCOMP_SET_MODE_STRICT, 0, NULL));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "seccomp(SECCOMP_SET_MODE_STRICT) error");
+ } else {
+ TEST(prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, NULL));
+
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "prctl(SECCOMP_MODE_STRICT) error");
}

switch (val) {
@@ -158,18 +168,20 @@ static void check_filter_mode(int val)
{
int fd;

- if (mode_filter_not_supported == 1) {
- tst_res(TCONF, "kernel doesn't support SECCOMP_MODE_FILTER");
+ if (filter_not_supported)
return;
- }

fd = SAFE_OPEN(FNAME, O_RDWR | O_CREAT, 0666);

- TEST(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &strict));
- if (TST_RET == -1) {
- tst_res(TFAIL | TERRNO,
- "prctl(PR_SET_SECCOMP) sets SECCOMP_MODE_FILTER failed");
- return;
+ if (tst_variant == 1) {
+ TEST(tst_syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &strict));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "seccomp(SECCOMP_SET_MODE_FILTER) error");
+ } else {
+ TEST(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &strict));
+
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "prctl(SECCOMP_MODE_FILTER) error");
}

switch (val) {
@@ -213,7 +225,7 @@ static void verify_prctl(unsigned int n)
return;
}

- if (tc->pass_flag == 2 && mode_filter_not_supported == 0)
+ if (tc->pass_flag == 2)
tst_res(TFAIL,
"SECCOMP_MODE_FILTER permits exit() unexpectedly");
}
@@ -221,31 +233,36 @@ static void verify_prctl(unsigned int n)

static void setup(void)
{
- TEST(prctl(PR_GET_SECCOMP));
- if (TST_RET == 0) {
- tst_res(TINFO, "kernel supports PR_GET/SET_SECCOMP");
+ static const char * const kconf_strict[] = {"CONFIG_SECCOMP=y", NULL};
+ static const char * const kconf_filter[] = {"CONFIG_SECCOMP_FILTER=y", NULL};

- TEST(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL));
- if (TST_RET == -1 && TST_ERR == EINVAL) {
- mode_filter_not_supported = 1;
- return;
- }
+ tst_res(TINFO, "Testing variant: %s",
+ tst_variant == 1 ? "seccomp()" : "pctrl(PR_SET_SECCOMP)");

- tst_res(TINFO, "kernel supports SECCOMP_MODE_FILTER");
- return;
+ if (tst_kconfig_check(kconf_strict)) {
+ tst_brk(TCONF, "kernel doesn't support SECCOMP_MODE_STRICT. "
+ "Skipping CONFIG_SECCOMP tests");
+
+ strict_not_supported = 1;
+ } else {
+ tst_res(TINFO, "kernel supports SECCOMP_MODE_STRICT");
}

- if (TST_ERR == EINVAL)
- tst_brk(TCONF, "kernel doesn't support PR_GET/SET_SECCOMP");
+ if (tst_kconfig_check(kconf_filter)) {
+ tst_brk(TCONF, "kernel doesn't support SECCOMP_MODE_FILTER. "
+ "Skipping CONFIG_SECCOMP_FILTER tests");

- tst_brk(TBROK | TTERRNO,
- "current environment doesn't permit PR_GET/SET_SECCOMP");
+ filter_not_supported = 1;
+ } else {
+ tst_res(TINFO, "kernel supports SECCOMP_MODE_FILTER");
+ }
}

static struct tst_test test = {
.setup = setup,
.test = verify_prctl,
.tcnt = ARRAY_SIZE(tcases),
+ .test_variants = 2,
.forks_child = 1,
.needs_tmpdir = 1,
.needs_root = 1,

---
base-commit: 66517b89141fc455ed807f3b95e5260dcf9fb90f
change-id: 20240603-seccomp-06f18e9551df

Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>

--
Mailing list info: https://lists.linux.it/listinfo/ltp