* [LTP] [PATCH v3 1/4] Fallback landlock network support
2024-11-06 11:13 [LTP] [PATCH v3 0/4] landlock network coverage support Andrea Cervesato
@ 2024-11-06 11:13 ` Andrea Cervesato
2024-11-08 15:53 ` Cyril Hrubis
2024-11-06 11:13 ` [LTP] [PATCH v3 2/4] Network helpers in landlock suite common functions Andrea Cervesato
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Andrea Cervesato @ 2024-11-06 11:13 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Landlock network support has been added in the ABI v4, adding features
for bind() and connect() syscalls. It also defined one more member in
the landlock_ruleset_attr struct, breaking our LTP fallbacks, used to
build landlock testing suite. For this reason, we introduce
tst_landlock_ruleset_attr_abi[14] struct(s) which fallback ABI v1 and v4
ruleset_attr definitions.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
configure.ac | 5 ++--
include/lapi/capability.h | 4 ++++
include/lapi/landlock.h | 28 ++++++++++++----------
testcases/kernel/syscalls/landlock/landlock01.c | 15 ++++--------
testcases/kernel/syscalls/landlock/landlock02.c | 8 +++----
testcases/kernel/syscalls/landlock/landlock03.c | 6 ++---
testcases/kernel/syscalls/landlock/landlock04.c | 6 ++---
testcases/kernel/syscalls/landlock/landlock05.c | 10 ++++----
testcases/kernel/syscalls/landlock/landlock06.c | 14 ++++-------
testcases/kernel/syscalls/landlock/landlock07.c | 6 ++---
.../kernel/syscalls/landlock/landlock_common.h | 12 ++++------
11 files changed, 53 insertions(+), 61 deletions(-)
diff --git a/configure.ac b/configure.ac
index cd1233d19fad376973fc880d6689859845613fb0..6992d75ca300ccc4cc21a45a916f6b3be1a3b8fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,8 @@ m4_ifndef([PKG_CHECK_EXISTS],
AC_PREFIX_DEFAULT(/opt/ltp)
AC_CHECK_DECLS([IFLA_NET_NS_PID],,,[#include <linux/if_link.h>])
+AC_CHECK_DECLS([LANDLOCK_RULE_PATH_BENEATH],,,[#include <linux/landlock.h>])
+AC_CHECK_DECLS([LANDLOCK_RULE_NET_PORT],,,[#include <linux/landlock.h>])
AC_CHECK_DECLS([MADV_MERGEABLE],,,[#include <sys/mman.h>])
AC_CHECK_DECLS([NFTA_CHAIN_ID, NFTA_VERDICT_CHAIN_ID],,,[#include <linux/netfilter/nf_tables.h>])
AC_CHECK_DECLS([PR_CAPBSET_DROP, PR_CAPBSET_READ],,,[#include <sys/prctl.h>])
@@ -158,7 +160,6 @@ AC_CHECK_FUNCS_ONCE([ \
AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!))
AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>])
-AC_CHECK_MEMBERS([struct landlock_ruleset_attr.handled_access_net],,,[#include <linux/landlock.h>])
AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>])
AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>])
AC_CHECK_MEMBERS([struct statx.stx_mnt_id, struct statx.stx_dio_mem_align],,,[
@@ -172,7 +173,6 @@ AC_CHECK_MEMBERS([struct utsname.domainname],,,[
])
AC_CHECK_TYPES([enum kcmp_type],,,[#include <linux/kcmp.h>])
-AC_CHECK_TYPES([enum landlock_rule_type],,,[#include <linux/landlock.h>])
AC_CHECK_TYPES([struct acct_v3],,,[#include <sys/acct.h>])
AC_CHECK_TYPES([struct af_alg_iv, struct sockaddr_alg],,,[# include <linux/if_alg.h>])
AC_CHECK_TYPES([struct fanotify_event_info_fid, struct fanotify_event_info_error,
@@ -194,7 +194,6 @@ AC_CHECK_TYPES([struct if_nextdqblk],,,[#include <linux/quota.h>])
AC_CHECK_TYPES([struct iovec],,,[#include <sys/uio.h>])
AC_CHECK_TYPES([struct ipc64_perm],,,[#include <sys/ipcbuf.h>])
AC_CHECK_TYPES([struct loop_config],,,[#include <linux/loop.h>])
-AC_CHECK_TYPES([struct landlock_ruleset_attr],,,[#include <linux/landlock.h>])
AC_CHECK_TYPES([struct landlock_path_beneath_attr],,,[#include <linux/landlock.h>])
AC_CHECK_TYPES([struct landlock_net_port_attr],,,[#include <linux/landlock.h>])
diff --git a/include/lapi/capability.h b/include/lapi/capability.h
index 0f317d6d770e86b399f0fed2de04c1dce6723eae..14d2d3c12c051006875f1f864ec58a88a3870ec0 100644
--- a/include/lapi/capability.h
+++ b/include/lapi/capability.h
@@ -20,6 +20,10 @@
# endif
#endif
+#ifndef CAP_NET_BIND_SERVICE
+# define CAP_NET_BIND_SERVICE 10
+#endif
+
#ifndef CAP_NET_RAW
# define CAP_NET_RAW 13
#endif
diff --git a/include/lapi/landlock.h b/include/lapi/landlock.h
index 211d171ebecd92d75224369dc7f1d5c5903c9ce7..b3c8c548e661680541cdf6e4a8fb68a3f5029fec 100644
--- a/include/lapi/landlock.h
+++ b/include/lapi/landlock.h
@@ -7,6 +7,7 @@
#define LAPI_LANDLOCK_H__
#include "config.h"
+#include <stdint.h>
#ifdef HAVE_LINUX_LANDLOCK_H
# include <linux/landlock.h>
@@ -14,13 +15,16 @@
#include "lapi/syscalls.h"
-#ifndef HAVE_STRUCT_LANDLOCK_RULESET_ATTR
-struct landlock_ruleset_attr
+struct tst_landlock_ruleset_attr_abi1
+{
+ uint64_t handled_access_fs;
+};
+
+struct tst_landlock_ruleset_attr_abi4
{
uint64_t handled_access_fs;
uint64_t handled_access_net;
};
-#endif
#ifndef HAVE_STRUCT_LANDLOCK_PATH_BENEATH_ATTR
struct landlock_path_beneath_attr
@@ -30,12 +34,12 @@ struct landlock_path_beneath_attr
} __attribute__((packed));
#endif
-#ifndef HAVE_ENUM_LANDLOCK_RULE_TYPE
-enum landlock_rule_type
-{
- LANDLOCK_RULE_PATH_BENEATH = 1,
- LANDLOCK_RULE_NET_PORT,
-};
+#if !HAVE_DECL_LANDLOCK_RULE_PATH_BENEATH
+# define LANDLOCK_RULE_PATH_BENEATH 1
+#endif
+
+#if !HAVE_DECL_LANDLOCK_RULE_NET_PORT
+# define LANDLOCK_RULE_NET_PORT 2
#endif
#ifndef HAVE_STRUCT_LANDLOCK_NET_PORT_ATTR
@@ -123,8 +127,7 @@ struct landlock_net_port_attr
#endif
static inline int safe_landlock_create_ruleset(const char *file, const int lineno,
- const struct landlock_ruleset_attr *attr,
- size_t size , uint32_t flags)
+ const void *attr, size_t size , uint32_t flags)
{
int rval;
@@ -143,8 +146,7 @@ static inline int safe_landlock_create_ruleset(const char *file, const int linen
}
static inline int safe_landlock_add_rule(const char *file, const int lineno,
- int ruleset_fd, enum landlock_rule_type rule_type,
- const void *rule_attr, uint32_t flags)
+ int ruleset_fd, int rule_type, const void *rule_attr, uint32_t flags)
{
int rval;
diff --git a/testcases/kernel/syscalls/landlock/landlock01.c b/testcases/kernel/syscalls/landlock/landlock01.c
index 083685c64fa6d1c0caab887ee03594ea1426f62f..d0d68c8e4d905b8991527cc0c225d747601919a4 100644
--- a/testcases/kernel/syscalls/landlock/landlock01.c
+++ b/testcases/kernel/syscalls/landlock/landlock01.c
@@ -17,14 +17,14 @@
#include "landlock_common.h"
-static struct landlock_ruleset_attr *ruleset_attr;
-static struct landlock_ruleset_attr *null_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *null_attr;
static size_t rule_size;
static size_t rule_small_size;
static size_t rule_big_size;
static struct tcase {
- struct landlock_ruleset_attr **attr;
+ struct tst_landlock_ruleset_attr_abi1 **attr;
uint64_t access_fs;
size_t *size;
uint32_t flags;
@@ -60,13 +60,8 @@ static void setup(void)
{
verify_landlock_is_enabled();
- rule_size = sizeof(struct landlock_ruleset_attr);
-
-#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET
- rule_small_size = rule_size - sizeof(uint64_t) - 1;
-#else
+ rule_size = sizeof(struct tst_landlock_ruleset_attr_abi1);
rule_small_size = rule_size - 1;
-#endif
rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
}
@@ -77,7 +72,7 @@ static struct tst_test test = {
.setup = setup,
.needs_root = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{},
},
.caps = (struct tst_cap []) {
diff --git a/testcases/kernel/syscalls/landlock/landlock02.c b/testcases/kernel/syscalls/landlock/landlock02.c
index 1a3df69c9cc3eda98e28cfbfd1e12c57e26d0128..8566d407f6d17ab367695125f07d0a80cf4130e5 100644
--- a/testcases/kernel/syscalls/landlock/landlock02.c
+++ b/testcases/kernel/syscalls/landlock/landlock02.c
@@ -20,7 +20,7 @@
#include "landlock_common.h"
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static struct landlock_path_beneath_attr *path_beneath_attr;
static struct landlock_path_beneath_attr *rule_null;
static int ruleset_fd;
@@ -93,7 +93,7 @@ static void run(unsigned int n)
}
TST_EXP_FAIL(tst_syscall(__NR_landlock_add_rule,
- *tc->fd, tc->rule_type, *tc->attr, tc->flags),
+ *tc->fd, tc->rule_type, *tc->attr, tc->flags),
tc->exp_errno,
"%s",
tc->msg);
@@ -106,7 +106,7 @@ static void setup(void)
ruleset_attr->handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE;
ruleset_fd = TST_EXP_FD_SILENT(tst_syscall(__NR_landlock_create_ruleset,
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0));
+ ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0));
}
static void cleanup(void)
@@ -122,7 +122,7 @@ static struct tst_test test = {
.cleanup = cleanup,
.needs_root = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
{},
},
diff --git a/testcases/kernel/syscalls/landlock/landlock03.c b/testcases/kernel/syscalls/landlock/landlock03.c
index 224482255b287cef64f579b5707a92a6b5908f8b..150c8cc4e50ee1b41af3c8c01771c51a8715746f 100644
--- a/testcases/kernel/syscalls/landlock/landlock03.c
+++ b/testcases/kernel/syscalls/landlock/landlock03.c
@@ -21,7 +21,7 @@
#define MAX_STACKED_RULESETS 16
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static int ruleset_fd = -1;
static int ruleset_invalid = -1;
static int file_fd = -1;
@@ -89,7 +89,7 @@ static void setup(void)
ruleset_attr->handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE;
ruleset_fd = TST_EXP_FD_SILENT(tst_syscall(__NR_landlock_create_ruleset,
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0));
+ ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0));
file_fd = SAFE_OPEN("junk.bin", O_CREAT, 0777);
}
@@ -112,7 +112,7 @@ static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{},
},
.caps = (struct tst_cap []) {
diff --git a/testcases/kernel/syscalls/landlock/landlock04.c b/testcases/kernel/syscalls/landlock/landlock04.c
index e9dedd45091ecd15cdce2fa7227bbfceb14abb5e..2485591e2196072f81708fc10cebd382e536e2a9 100644
--- a/testcases/kernel/syscalls/landlock/landlock04.c
+++ b/testcases/kernel/syscalls/landlock/landlock04.c
@@ -15,7 +15,7 @@
#include "landlock_tester.h"
#include "tst_safe_stdio.h"
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static struct landlock_path_beneath_attr *path_beneath_attr;
static int ruleset_fd = -1;
@@ -153,7 +153,7 @@ static void setup(void)
ruleset_attr->handled_access_fs = tester_get_all_fs_rules();
ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
+ ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0);
/* since our binary is dynamically linked, we need to enable dependences
* to be read and executed
@@ -192,7 +192,7 @@ static struct tst_test test = {
NULL,
},
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
{},
},
diff --git a/testcases/kernel/syscalls/landlock/landlock05.c b/testcases/kernel/syscalls/landlock/landlock05.c
index 703f7d81c336907f360acbe45b42720dc12bac23..3d5048f0ab51b2d7c3eedc82ef80c04935ac5d86 100644
--- a/testcases/kernel/syscalls/landlock/landlock05.c
+++ b/testcases/kernel/syscalls/landlock/landlock05.c
@@ -28,7 +28,7 @@
#define FILENAME2 DIR2"/file"
#define FILENAME3 DIR3"/file"
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static struct landlock_path_beneath_attr *path_beneath_attr;
static void run(void)
@@ -68,15 +68,15 @@ static void setup(void)
LANDLOCK_ACCESS_FS_REFER;
ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
+ ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0);
- apply_landlock_rule(
+ apply_landlock_fs_rule(
path_beneath_attr,
ruleset_fd,
LANDLOCK_ACCESS_FS_REFER,
DIR1);
- apply_landlock_rule(
+ apply_landlock_fs_rule(
path_beneath_attr,
ruleset_fd,
LANDLOCK_ACCESS_FS_REFER,
@@ -93,7 +93,7 @@ static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
{},
},
diff --git a/testcases/kernel/syscalls/landlock/landlock06.c b/testcases/kernel/syscalls/landlock/landlock06.c
index 1a6e59241557db23b23beabf9863a9c51353757a..74237d11657054985f06431467fbb161ded0c1b6 100644
--- a/testcases/kernel/syscalls/landlock/landlock06.c
+++ b/testcases/kernel/syscalls/landlock/landlock06.c
@@ -18,7 +18,7 @@
#define MNTPOINT "sandbox"
#define FILENAME MNTPOINT"/fifo"
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static struct landlock_path_beneath_attr *path_beneath_attr;
static int file_fd = -1;
static int dev_fd = -1;
@@ -42,8 +42,6 @@ static void run(void)
static void setup(void)
{
- int ruleset_fd;
-
if (verify_landlock_is_enabled() < 5)
tst_brk(TCONF, "LANDLOCK_ACCESS_FS_IOCTL_DEV is not supported");
@@ -56,17 +54,13 @@ static void setup(void)
ruleset_attr->handled_access_fs = LANDLOCK_ACCESS_FS_IOCTL_DEV;
- ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
-
- apply_landlock_layer(
+ apply_landlock_fs_layer(
ruleset_attr,
+ sizeof(struct tst_landlock_ruleset_attr_abi1),
path_beneath_attr,
MNTPOINT,
LANDLOCK_ACCESS_FS_IOCTL_DEV
);
-
- SAFE_CLOSE(ruleset_fd);
}
static void cleanup(void)
@@ -85,7 +79,7 @@ static struct tst_test test = {
.needs_root = 1,
.forks_child = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
{},
},
diff --git a/testcases/kernel/syscalls/landlock/landlock07.c b/testcases/kernel/syscalls/landlock/landlock07.c
index 6115ad53876209051952873679eb96014b4dd805..8ee614856312d55e573e18f88a6690b50497ee8b 100644
--- a/testcases/kernel/syscalls/landlock/landlock07.c
+++ b/testcases/kernel/syscalls/landlock/landlock07.c
@@ -25,7 +25,7 @@
#include "lapi/prctl.h"
#include "landlock_common.h"
-static struct landlock_ruleset_attr *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
static int ruleset_fd;
static pid_t spawn_houdini(void)
@@ -77,7 +77,7 @@ static void setup(void)
ruleset_attr->handled_access_fs = LANDLOCK_ACCESS_FS_WRITE_FILE;
ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
ruleset_attr,
- sizeof(struct landlock_ruleset_attr),
+ sizeof(struct tst_landlock_ruleset_attr_abi1),
0);
}
@@ -93,7 +93,7 @@ static struct tst_test test = {
.cleanup = cleanup,
.forks_child = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
{},
},
.caps = (struct tst_cap []) {
diff --git a/testcases/kernel/syscalls/landlock/landlock_common.h b/testcases/kernel/syscalls/landlock/landlock_common.h
index da91daeab7b3def7184f611a90273419e4cfa6f2..f3096f4bf15f155f2a00b39c461d0805a76306e5 100644
--- a/testcases/kernel/syscalls/landlock/landlock_common.h
+++ b/testcases/kernel/syscalls/landlock/landlock_common.h
@@ -33,7 +33,7 @@ static inline int verify_landlock_is_enabled(void)
return abi;
}
-static inline void apply_landlock_rule(
+static inline void apply_landlock_fs_rule(
struct landlock_path_beneath_attr *path_beneath_attr,
const int ruleset_fd,
const int access,
@@ -57,21 +57,19 @@ static inline void enforce_ruleset(const int ruleset_fd)
SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0);
}
-static inline void apply_landlock_layer(
- struct landlock_ruleset_attr *ruleset_attr,
+static inline void apply_landlock_fs_layer(
+ void *ruleset_attr, size_t attr_size,
struct landlock_path_beneath_attr *path_beneath_attr,
const char *path,
const int access)
{
int ruleset_fd;
- ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
- ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
+ ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(ruleset_attr, attr_size, 0);
- apply_landlock_rule(path_beneath_attr, ruleset_fd, access, path);
+ apply_landlock_fs_rule(path_beneath_attr, ruleset_fd, access, path);
enforce_ruleset(ruleset_fd);
SAFE_CLOSE(ruleset_fd);
}
-
#endif /* LANDLOCK_COMMON_H__ */
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread* [LTP] [PATCH v3 3/4] Add landlock08 test
2024-11-06 11:13 [LTP] [PATCH v3 0/4] landlock network coverage support Andrea Cervesato
2024-11-06 11:13 ` [LTP] [PATCH v3 1/4] Fallback landlock network support Andrea Cervesato
2024-11-06 11:13 ` [LTP] [PATCH v3 2/4] Network helpers in landlock suite common functions Andrea Cervesato
@ 2024-11-06 11:13 ` Andrea Cervesato
2024-11-06 11:13 ` [LTP] [PATCH v3 4/4] Add error coverage for landlock network support Andrea Cervesato
3 siblings, 0 replies; 10+ messages in thread
From: Andrea Cervesato @ 2024-11-06 11:13 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Verify the landlock support for bind()/connect() syscalls in IPV4
and IPV6 protocols. In particular, check that bind() is assigning
the address only on the TCP port enforced by
LANDLOCK_ACCESS_NET_BIND_TCP and check that connect() is connecting
only to a specific TCP port enforced by
LANDLOCK_ACCESS_NET_CONNECT_TCP.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/landlock08.c | 209 ++++++++++++++++++++++++
3 files changed, 211 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 7dc308fa88486b9ace80ef0d906201dd407dcf3e..5fd62617df1a116b1d94c57ff30f74693320a2ab 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -708,6 +708,7 @@ landlock04 landlock04
landlock05 landlock05
landlock06 landlock06
landlock07 landlock07
+landlock08 landlock08
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index db11bff2fe245d462e5b7e5691a9eb2ee2305aab..fc7317394948c4ac20cd14c3cd7ba7a47282b2bf 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -6,3 +6,4 @@ landlock04
landlock05
landlock06
landlock07
+landlock08
diff --git a/testcases/kernel/syscalls/landlock/landlock08.c b/testcases/kernel/syscalls/landlock/landlock08.c
new file mode 100644
index 0000000000000000000000000000000000000000..c3c320c340355b6b910079c1bf31984dcf2c906b
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock08.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify the landlock support for bind()/connect() syscalls in IPV4 and IPV6
+ * protocols. In particular, check that bind() is assigning the address only on
+ * the TCP port enforced by LANDLOCK_ACCESS_NET_BIND_TCP and check that
+ * connect() is connecting only to a specific TCP port enforced by
+ * LANDLOCK_ACCESS_NET_CONNECT_TCP.
+ *
+ * [Algorithm]
+ *
+ * Repeat the following procedure for IPV4 and IPV6:
+ *
+ * - create a socket on PORT1, bind() it and check if it passes
+ * - enforce the current sandbox with LANDLOCK_ACCESS_NET_BIND_TCP on PORT1
+ * - create a socket on PORT1, bind() it and check if it passes
+ * - create a socket on PORT2, bind() it and check if it fails
+ *
+ * - create a server listening on PORT1
+ * - create a socket on PORT1, connect() to it and check if it passes
+ * - enforce the current sandbox with LANDLOCK_ACCESS_NET_CONNECT_TCP on PORT1
+ * - create a socket on PORT1, connect() to it and check if it passes
+ * - create a socket on PORT2, connect() to it and check if it fails
+ */
+
+#include "landlock_common.h"
+
+static int variants[] = {
+ AF_INET,
+ AF_INET6,
+};
+
+static struct tst_landlock_ruleset_attr_abi4 *ruleset_attr;
+static struct landlock_net_port_attr *net_port_attr;
+static in_port_t *server_port;
+static int addr_port;
+
+static void create_server(const int addr_family)
+{
+ struct socket_data socket;
+ struct sockaddr *addr = NULL;
+
+ create_socket(&socket, addr_family, 0);
+ getsocket_addr(&socket, addr_family, &addr);
+
+ SAFE_BIND(socket.fd, addr, socket.address_size);
+ SAFE_LISTEN(socket.fd, 1);
+
+ *server_port = getsocket_port(&socket, addr_family);
+
+ tst_res(TDEBUG, "Server listening on port %u", *server_port);
+
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ SAFE_CLOSE(socket.fd);
+}
+
+static void test_bind(const int addr_family, const in_port_t port,
+ const int exp_err)
+{
+ struct socket_data socket;
+ struct sockaddr *addr = NULL;
+
+ create_socket(&socket, addr_family, port);
+ getsocket_addr(&socket, addr_family, &addr);
+
+ if (exp_err) {
+ TST_EXP_FAIL(
+ bind(socket.fd, addr, socket.address_size),
+ exp_err, "bind() access on port %u", port);
+ } else {
+ TST_EXP_PASS(
+ bind(socket.fd, addr, socket.address_size),
+ "bind() access on port %u", port);
+ }
+
+ SAFE_CLOSE(socket.fd);
+}
+
+static void test_connect(const int addr_family, const in_port_t port,
+ const int exp_err)
+{
+ struct socket_data socket;
+ struct sockaddr *addr = NULL;
+
+ create_socket(&socket, addr_family, port);
+ getsocket_addr(&socket, addr_family, &addr);
+
+ if (exp_err) {
+ TST_EXP_FAIL(
+ connect(socket.fd, addr, socket.address_size),
+ exp_err, "connect() on port %u", port);
+ } else {
+ TST_EXP_PASS(
+ connect(socket.fd, addr, socket.address_size),
+ "connect() on port %u", port);
+ }
+
+ SAFE_CLOSE(socket.fd);
+}
+
+static void run(void)
+{
+ int addr_family = variants[tst_variant];
+
+ tst_res(TINFO, "Using %s protocol",
+ addr_family == AF_INET ? "IPV4" : "IPV6");
+
+ if (!SAFE_FORK()) {
+ create_server(addr_family);
+ exit(0);
+ }
+
+ TST_CHECKPOINT_WAIT(0);
+
+ /* verify bind() syscall accessibility */
+ if (!SAFE_FORK()) {
+ ruleset_attr->handled_access_net =
+ LANDLOCK_ACCESS_NET_BIND_TCP;
+
+ test_bind(addr_family, addr_port, 0);
+
+ tst_res(TINFO, "Enable bind() access only for port %u",
+ addr_port);
+
+ apply_landlock_net_layer(
+ ruleset_attr,
+ sizeof(struct tst_landlock_ruleset_attr_abi4),
+ net_port_attr,
+ addr_port,
+ LANDLOCK_ACCESS_NET_BIND_TCP);
+
+ test_bind(addr_family, addr_port, 0);
+ test_bind(addr_family, addr_port + 0x80, EACCES);
+
+ exit(0);
+ }
+
+ /* verify connect() syscall accessibility */
+ if (!SAFE_FORK()) {
+ ruleset_attr->handled_access_net =
+ LANDLOCK_ACCESS_NET_CONNECT_TCP;
+
+ test_connect(addr_family, *server_port, 0);
+
+ tst_res(TINFO, "Enable connect() access only on port %u",
+ *server_port);
+
+ apply_landlock_net_layer(
+ ruleset_attr,
+ sizeof(struct tst_landlock_ruleset_attr_abi4),
+ net_port_attr,
+ *server_port,
+ LANDLOCK_ACCESS_NET_CONNECT_TCP);
+
+ test_connect(addr_family, *server_port, 0);
+ test_connect(addr_family, *server_port + 0x80, EACCES);
+
+ TST_CHECKPOINT_WAKE(0);
+
+ exit(0);
+ }
+}
+
+static void setup(void)
+{
+ if (verify_landlock_is_enabled() < 4)
+ tst_brk(TCONF, "Landlock network is not supported");
+
+ addr_port = TST_GET_UNUSED_PORT(AF_INET, SOCK_STREAM);
+
+ server_port = SAFE_MMAP(NULL, sizeof(in_port_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+}
+
+static void cleanup(void)
+{
+ if (server_port)
+ SAFE_MUNMAP(server_port, sizeof(in_port_t));
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .forks_child = 1,
+ .test_variants = ARRAY_SIZE(variants),
+ .bufs = (struct tst_buffers[]) {
+ {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi4)},
+ {&net_port_attr, .size = sizeof(struct landlock_net_port_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ TST_CAP(TST_CAP_REQ, CAP_NET_BIND_SERVICE),
+ {}
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_INET=y",
+ NULL
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread* [LTP] [PATCH v3 4/4] Add error coverage for landlock network support
2024-11-06 11:13 [LTP] [PATCH v3 0/4] landlock network coverage support Andrea Cervesato
` (2 preceding siblings ...)
2024-11-06 11:13 ` [LTP] [PATCH v3 3/4] Add landlock08 test Andrea Cervesato
@ 2024-11-06 11:13 ` Andrea Cervesato
3 siblings, 0 replies; 10+ messages in thread
From: Andrea Cervesato @ 2024-11-06 11:13 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add two more errors checks inside the landlock02 which is testing
landlock_add_rule syscall. In particular, test now verifies when the
syscall is raising EINVAL due to invalid network attributes.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/landlock/landlock02.c | 93 +++++++++++++++++++------
1 file changed, 72 insertions(+), 21 deletions(-)
diff --git a/testcases/kernel/syscalls/landlock/landlock02.c b/testcases/kernel/syscalls/landlock/landlock02.c
index 8566d407f6d17ab367695125f07d0a80cf4130e5..e1e3228b54f3fdb10774cb333ccc5646c7c4e37b 100644
--- a/testcases/kernel/syscalls/landlock/landlock02.c
+++ b/testcases/kernel/syscalls/landlock/landlock02.c
@@ -20,93 +20,142 @@
#include "landlock_common.h"
-static struct tst_landlock_ruleset_attr_abi1 *ruleset_attr;
+static struct tst_landlock_ruleset_attr_abi1 *attr_abi1;
+static struct tst_landlock_ruleset_attr_abi4 *attr_abi4;
static struct landlock_path_beneath_attr *path_beneath_attr;
static struct landlock_path_beneath_attr *rule_null;
+static struct landlock_net_port_attr *net_port_attr;
static int ruleset_fd;
static int invalid_fd = -1;
+static int abi_current;
static struct tcase {
int *fd;
- enum landlock_rule_type rule_type;
- struct landlock_path_beneath_attr **attr;
+ int rule_type;
+ struct landlock_path_beneath_attr **path_attr;
+ struct landlock_net_port_attr **net_attr;
int access;
int parent_fd;
+ int net_port;
uint32_t flags;
int exp_errno;
+ int abi_ver;
char *msg;
} tcases[] = {
{
.fd = &ruleset_fd,
- .attr = &path_beneath_attr,
+ .path_attr = &path_beneath_attr,
.access = LANDLOCK_ACCESS_FS_EXECUTE,
.flags = 1,
.exp_errno = EINVAL,
+ .abi_ver = 1,
.msg = "Invalid flags"
},
{
.fd = &ruleset_fd,
- .attr = &path_beneath_attr,
+ .path_attr = &path_beneath_attr,
.access = LANDLOCK_ACCESS_FS_EXECUTE,
.exp_errno = EINVAL,
+ .abi_ver = 1,
.msg = "Invalid rule type"
},
{
.fd = &ruleset_fd,
.rule_type = LANDLOCK_RULE_PATH_BENEATH,
- .attr = &path_beneath_attr,
+ .path_attr = &path_beneath_attr,
.exp_errno = ENOMSG,
+ .abi_ver = 1,
.msg = "Empty accesses"
},
{
.fd = &invalid_fd,
- .attr = &path_beneath_attr,
+ .path_attr = &path_beneath_attr,
.access = LANDLOCK_ACCESS_FS_EXECUTE,
.exp_errno = EBADF,
+ .abi_ver = 1,
.msg = "Invalid file descriptor"
},
{
.fd = &ruleset_fd,
.rule_type = LANDLOCK_RULE_PATH_BENEATH,
- .attr = &path_beneath_attr,
+ .path_attr = &path_beneath_attr,
.access = LANDLOCK_ACCESS_FS_EXECUTE,
.parent_fd = -1,
.exp_errno = EBADF,
+ .abi_ver = 1,
.msg = "Invalid parent fd"
},
{
.fd = &ruleset_fd,
.rule_type = LANDLOCK_RULE_PATH_BENEATH,
- .attr = &rule_null,
+ .path_attr = &rule_null,
.exp_errno = EFAULT,
+ .abi_ver = 1,
.msg = "Invalid rule attr"
},
+ {
+ .fd = &ruleset_fd,
+ .rule_type = LANDLOCK_RULE_NET_PORT,
+ .net_attr = &net_port_attr,
+ .access = LANDLOCK_ACCESS_FS_EXECUTE,
+ .net_port = 448,
+ .exp_errno = EINVAL,
+ .abi_ver = 4,
+ .msg = "Invalid access rule for network type"
+ },
+ {
+ .fd = &ruleset_fd,
+ .rule_type = LANDLOCK_RULE_NET_PORT,
+ .net_attr = &net_port_attr,
+ .access = LANDLOCK_ACCESS_NET_BIND_TCP,
+ .net_port = INT16_MAX + 1,
+ .exp_errno = EINVAL,
+ .abi_ver = 4,
+ .msg = "Socket port greater than 65535"
+ },
};
static void run(unsigned int n)
{
struct tcase *tc = &tcases[n];
+ void *attr = NULL;
- if (*tc->attr) {
- (*tc->attr)->allowed_access = tc->access;
- (*tc->attr)->parent_fd = tc->parent_fd;
+ if (tc->abi_ver > abi_current) {
+ tst_res(TCONF, "Minimum ABI required: %d", tc->abi_ver);
+ return;
+ }
+
+ if (tc->path_attr && *tc->path_attr) {
+ (*tc->path_attr)->allowed_access = tc->access;
+ (*tc->path_attr)->parent_fd = tc->parent_fd;
+
+ attr = *tc->path_attr;
+ } else if (tc->net_attr && *tc->net_attr) {
+ (*tc->net_attr)->allowed_access = tc->access;
+ (*tc->net_attr)->port = tc->net_port;
+
+ attr = *tc->net_attr;
}
TST_EXP_FAIL(tst_syscall(__NR_landlock_add_rule,
- *tc->fd, tc->rule_type, *tc->attr, tc->flags),
- tc->exp_errno,
- "%s",
- tc->msg);
+ *tc->fd, tc->rule_type, attr, tc->flags),
+ tc->exp_errno, "%s", tc->msg);
}
static void setup(void)
{
- verify_landlock_is_enabled();
+ abi_current = verify_landlock_is_enabled();
- ruleset_attr->handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE;
+ attr_abi1->handled_access_fs =
+ attr_abi4->handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE;
- ruleset_fd = TST_EXP_FD_SILENT(tst_syscall(__NR_landlock_create_ruleset,
- ruleset_attr, sizeof(struct tst_landlock_ruleset_attr_abi1), 0));
+ if (abi_current < 4) {
+ ruleset_fd = TST_EXP_FD_SILENT(tst_syscall(__NR_landlock_create_ruleset,
+ attr_abi1, sizeof(struct tst_landlock_ruleset_attr_abi1), 0));
+ } else {
+ ruleset_fd = TST_EXP_FD_SILENT(tst_syscall(__NR_landlock_create_ruleset,
+ attr_abi4, sizeof(struct tst_landlock_ruleset_attr_abi4), 0));
+ }
}
static void cleanup(void)
@@ -122,8 +171,10 @@ static struct tst_test test = {
.cleanup = cleanup,
.needs_root = 1,
.bufs = (struct tst_buffers []) {
- {&ruleset_attr, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
+ {&attr_abi1, .size = sizeof(struct tst_landlock_ruleset_attr_abi1)},
+ {&attr_abi4, .size = sizeof(struct tst_landlock_ruleset_attr_abi4)},
{&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
+ {&net_port_attr, .size = sizeof(struct landlock_net_port_attr)},
{},
},
.caps = (struct tst_cap []) {
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 10+ messages in thread