* [LTP] [PATCH v2 00/11] landlock testing suite
@ 2024-07-10 18:01 Andrea Cervesato
2024-07-10 18:01 ` [LTP] [PATCH v2 01/11] Add landlock syscalls definitions Andrea Cervesato
` (10 more replies)
0 siblings, 11 replies; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:01 UTC (permalink / raw)
To: ltp
This testing suite is meant to test the following syscalls:
- landlock_create_ruleset
- landlock_add_rule
- landlock_restrict_self
Documentation can be found in kernel manuals and inside the official
kernel documentation at
https://www.kernel.org/doc/html/latest/userspace-api/landlock.html
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Changes in v2:
- remove -lc unused dependency from Makefile
- move SAFE_LANDLOCK_* macros in lapi/landlock.h
- define CAP_MKNOD in the lapi/capability.h
- fix landlock fallback in order to let LTP build properly
- fix landlock01 EINVAL test when "struct landlock_ruleset_attr" size is
too small
- Link to v1: https://lore.kernel.org/r/20240701-landlock-v1-0-58e9af649a72@suse.com
---
Andrea Cervesato (11):
Add landlock syscalls definitions
Add lapi/landlock.h fallback
Added three more SAFE_* macros for landlock sandbox:
Add SAFE_PRCTL macro
Add landlock01 test
Add landlock02 test
Add landlock03 test
Add CAP_MKNOD fallback in lapi/capability.h
Add landlock04 test
Add landlock05 test
Add landlock06 test
configure.ac | 6 +
include/lapi/capability.h | 12 +-
include/lapi/landlock.h | 184 +++++++++++
include/lapi/syscalls/aarch64.in | 3 +
include/lapi/syscalls/arc.in | 3 +
include/lapi/syscalls/arm.in | 3 +
include/lapi/syscalls/hppa.in | 3 +
include/lapi/syscalls/i386.in | 3 +
include/lapi/syscalls/ia64.in | 3 +
include/lapi/syscalls/mips_n32.in | 3 +
include/lapi/syscalls/mips_n64.in | 3 +
include/lapi/syscalls/mips_o32.in | 3 +
include/lapi/syscalls/powerpc.in | 3 +
include/lapi/syscalls/powerpc64.in | 3 +
include/lapi/syscalls/s390.in | 3 +
include/lapi/syscalls/s390x.in | 3 +
include/lapi/syscalls/sh.in | 3 +
include/lapi/syscalls/sparc.in | 3 +
include/lapi/syscalls/sparc64.in | 3 +
include/lapi/syscalls/x86_64.in | 3 +
include/tst_safe_macros.h | 6 +
lib/tst_safe_macros.c | 17 +
runtest/syscalls | 7 +
testcases/kernel/syscalls/landlock/.gitignore | 7 +
testcases/kernel/syscalls/landlock/Makefile | 7 +
testcases/kernel/syscalls/landlock/landlock01.c | 92 ++++++
testcases/kernel/syscalls/landlock/landlock02.c | 153 +++++++++
testcases/kernel/syscalls/landlock/landlock03.c | 119 +++++++
testcases/kernel/syscalls/landlock/landlock04.c | 176 +++++++++++
testcases/kernel/syscalls/landlock/landlock05.c | 114 +++++++
testcases/kernel/syscalls/landlock/landlock06.c | 110 +++++++
.../kernel/syscalls/landlock/landlock_common.h | 74 +++++
testcases/kernel/syscalls/landlock/landlock_exec.c | 9 +
.../kernel/syscalls/landlock/landlock_tester.h | 350 +++++++++++++++++++++
34 files changed, 1490 insertions(+), 4 deletions(-)
---
base-commit: cdf739f26f33e589ab9cdf074a6b7fc04842eca2
change-id: 20240617-landlock-c48a4623a447
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 01/11] Add landlock syscalls definitions
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
@ 2024-07-10 18:01 ` Andrea Cervesato
2024-07-11 1:16 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback Andrea Cervesato
` (9 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:01 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/lapi/syscalls/aarch64.in | 3 +++
include/lapi/syscalls/arc.in | 3 +++
include/lapi/syscalls/arm.in | 3 +++
include/lapi/syscalls/hppa.in | 3 +++
include/lapi/syscalls/i386.in | 3 +++
include/lapi/syscalls/ia64.in | 3 +++
include/lapi/syscalls/mips_n32.in | 3 +++
include/lapi/syscalls/mips_n64.in | 3 +++
include/lapi/syscalls/mips_o32.in | 3 +++
include/lapi/syscalls/powerpc.in | 3 +++
include/lapi/syscalls/powerpc64.in | 3 +++
include/lapi/syscalls/s390.in | 3 +++
include/lapi/syscalls/s390x.in | 3 +++
include/lapi/syscalls/sh.in | 3 +++
include/lapi/syscalls/sparc.in | 3 +++
include/lapi/syscalls/sparc64.in | 3 +++
include/lapi/syscalls/x86_64.in | 3 +++
17 files changed, 51 insertions(+)
diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in
index 2cb6c2d87..3e7797718 100644
--- a/include/lapi/syscalls/aarch64.in
+++ b/include/lapi/syscalls/aarch64.in
@@ -296,5 +296,8 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
_sysctl 1078
diff --git a/include/lapi/syscalls/arc.in b/include/lapi/syscalls/arc.in
index 3e2ee9061..7fde1d263 100644
--- a/include/lapi/syscalls/arc.in
+++ b/include/lapi/syscalls/arc.in
@@ -316,4 +316,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/arm.in b/include/lapi/syscalls/arm.in
index 7bdbca533..693644f83 100644
--- a/include/lapi/syscalls/arm.in
+++ b/include/lapi/syscalls/arm.in
@@ -394,4 +394,7 @@ pidfd_getfd (__NR_SYSCALL_BASE+438)
faccessat2 (__NR_SYSCALL_BASE+439)
epoll_pwait2 (__NR_SYSCALL_BASE+441)
quotactl_fd (__NR_SYSCALL_BASE+443)
+landlock_create_ruleset (__NR_SYSCALL_BASE+444)
+landlock_add_rule (__NR_SYSCALL_BASE+445)
+landlock_restrict_self (__NR_SYSCALL_BASE+446)
futex_waitv (__NR_SYSCALL_BASE+449)
diff --git a/include/lapi/syscalls/hppa.in b/include/lapi/syscalls/hppa.in
index 8ebdafafb..60c02aff2 100644
--- a/include/lapi/syscalls/hppa.in
+++ b/include/lapi/syscalls/hppa.in
@@ -43,4 +43,7 @@ close_range 436
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/i386.in b/include/lapi/syscalls/i386.in
index 1472631c4..31ec1ecb2 100644
--- a/include/lapi/syscalls/i386.in
+++ b/include/lapi/syscalls/i386.in
@@ -430,4 +430,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/ia64.in b/include/lapi/syscalls/ia64.in
index 0ea6e9722..2e56da7f9 100644
--- a/include/lapi/syscalls/ia64.in
+++ b/include/lapi/syscalls/ia64.in
@@ -343,4 +343,7 @@ pidfd_getfd 1462
faccessat2 1463
epoll_pwait2 1465
quotactl_fd 1467
+landlock_create_ruleset 1468
+landlock_add_rule 1469
+landlock_restrict_self 1470
futex_waitv 1473
diff --git a/include/lapi/syscalls/mips_n32.in b/include/lapi/syscalls/mips_n32.in
index e818c9d92..5f0fe65eb 100644
--- a/include/lapi/syscalls/mips_n32.in
+++ b/include/lapi/syscalls/mips_n32.in
@@ -370,4 +370,7 @@ process_madvise 6440
epoll_pwait2 6441
mount_setattr 6442
quotactl_fd 6443
+landlock_create_ruleset 6444
+landlock_add_rule 6445
+landlock_restrict_self 6446
futex_waitv 6449
diff --git a/include/lapi/syscalls/mips_n64.in b/include/lapi/syscalls/mips_n64.in
index 6e15f43b3..f81c60e66 100644
--- a/include/lapi/syscalls/mips_n64.in
+++ b/include/lapi/syscalls/mips_n64.in
@@ -346,4 +346,7 @@ process_madvise 5440
epoll_pwait2 5441
mount_setattr 5442
quotactl_fd 5443
+landlock_create_ruleset 5444
+landlock_add_rule 5445
+landlock_restrict_self 5446
futex_waitv 5449
diff --git a/include/lapi/syscalls/mips_o32.in b/include/lapi/syscalls/mips_o32.in
index 921d5d331..c2beffb75 100644
--- a/include/lapi/syscalls/mips_o32.in
+++ b/include/lapi/syscalls/mips_o32.in
@@ -416,4 +416,7 @@ process_madvise 4440
epoll_pwait2 4441
mount_setattr 4442
quotactl_fd 4443
+landlock_create_ruleset 4444
+landlock_add_rule 4445
+landlock_restrict_self 4446
futex_waitv 4449
diff --git a/include/lapi/syscalls/powerpc.in b/include/lapi/syscalls/powerpc.in
index 545d9d3d6..5460e4197 100644
--- a/include/lapi/syscalls/powerpc.in
+++ b/include/lapi/syscalls/powerpc.in
@@ -423,4 +423,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in
index 545d9d3d6..5460e4197 100644
--- a/include/lapi/syscalls/powerpc64.in
+++ b/include/lapi/syscalls/powerpc64.in
@@ -423,4 +423,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/s390.in b/include/lapi/syscalls/s390.in
index 7213ac5f8..275b27f47 100644
--- a/include/lapi/syscalls/s390.in
+++ b/include/lapi/syscalls/s390.in
@@ -410,4 +410,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in
index 879012e2b..c200d02b2 100644
--- a/include/lapi/syscalls/s390x.in
+++ b/include/lapi/syscalls/s390x.in
@@ -358,4 +358,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/sh.in b/include/lapi/syscalls/sh.in
index 7d5192a27..6f482a77b 100644
--- a/include/lapi/syscalls/sh.in
+++ b/include/lapi/syscalls/sh.in
@@ -404,4 +404,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/sparc.in b/include/lapi/syscalls/sparc.in
index 91d2fb1c2..7181e80a0 100644
--- a/include/lapi/syscalls/sparc.in
+++ b/include/lapi/syscalls/sparc.in
@@ -409,4 +409,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/sparc64.in b/include/lapi/syscalls/sparc64.in
index 1f2fc59b7..c96ab2021 100644
--- a/include/lapi/syscalls/sparc64.in
+++ b/include/lapi/syscalls/sparc64.in
@@ -374,4 +374,7 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in
index dc61aa56e..3082ca110 100644
--- a/include/lapi/syscalls/x86_64.in
+++ b/include/lapi/syscalls/x86_64.in
@@ -351,6 +351,9 @@ pidfd_getfd 438
faccessat2 439
epoll_pwait2 441
quotactl_fd 443
+landlock_create_ruleset 444
+landlock_add_rule 445
+landlock_restrict_self 446
futex_waitv 449
rt_sigaction 512
rt_sigreturn 513
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
2024-07-10 18:01 ` [LTP] [PATCH v2 01/11] Add landlock syscalls definitions Andrea Cervesato
@ 2024-07-10 18:01 ` Andrea Cervesato
2024-07-11 1:30 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox: Andrea Cervesato
` (8 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:01 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
configure.ac | 6 +++
include/lapi/landlock.h | 123 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 129 insertions(+)
diff --git a/configure.ac b/configure.ac
index 82969b8d3..1f8796c87 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,6 +60,7 @@ AC_CHECK_HEADERS_ONCE([ \
linux/io_uring.h \
linux/ioprio.h \
linux/keyctl.h \
+ linux/landlock.h \
linux/mempolicy.h \
linux/module.h \
linux/mount.h \
@@ -157,6 +158,7 @@ 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],,,[
@@ -170,6 +172,7 @@ 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,
@@ -190,6 +193,9 @@ 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>])
AC_CHECK_TYPES([struct mmsghdr],,,[
#define _GNU_SOURCE
diff --git a/include/lapi/landlock.h b/include/lapi/landlock.h
new file mode 100644
index 000000000..2ee51b340
--- /dev/null
+++ b/include/lapi/landlock.h
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#ifndef LAPI_LANDLOCK_H__
+#define LAPI_LANDLOCK_H__
+
+#include "config.h"
+
+#ifdef HAVE_LINUX_LANDLOCK_H
+# include <linux/landlock.h>
+#endif
+
+#ifndef HAVE_STRUCT_LANDLOCK_RULESET_ATTR
+struct landlock_ruleset_attr
+{
+ uint64_t handled_access_fs;
+ uint64_t handled_access_net;
+};
+#endif
+
+#ifndef HAVE_STRUCT_LANDLOCK_PATH_BENEATH_ATTR
+struct landlock_path_beneath_attr
+{
+ uint64_t allowed_access;
+ int32_t parent_fd;
+} __attribute__((packed));
+#endif
+
+#ifndef HAVE_ENUM_LANDLOCK_RULE_TYPE
+enum landlock_rule_type
+{
+ LANDLOCK_RULE_PATH_BENEATH = 1,
+ LANDLOCK_RULE_NET_PORT,
+};
+#endif
+
+#ifndef HAVE_STRUCT_LANDLOCK_NET_PORT_ATTR
+struct landlock_net_port_attr
+{
+ uint64_t allowed_access;
+ uint64_t port;
+};
+#endif
+
+#ifndef LANDLOCK_CREATE_RULESET_VERSION
+# define LANDLOCK_CREATE_RULESET_VERSION (1U << 0)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_EXECUTE
+# define LANDLOCK_ACCESS_FS_EXECUTE (1ULL << 0)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_WRITE_FILE
+# define LANDLOCK_ACCESS_FS_WRITE_FILE (1ULL << 1)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_READ_FILE
+# define LANDLOCK_ACCESS_FS_READ_FILE (1ULL << 2)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_READ_DIR
+# define LANDLOCK_ACCESS_FS_READ_DIR (1ULL << 3)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_REMOVE_DIR
+# define LANDLOCK_ACCESS_FS_REMOVE_DIR (1ULL << 4)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_REMOVE_FILE
+# define LANDLOCK_ACCESS_FS_REMOVE_FILE (1ULL << 5)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_CHAR
+# define LANDLOCK_ACCESS_FS_MAKE_CHAR (1ULL << 6)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_DIR
+# define LANDLOCK_ACCESS_FS_MAKE_DIR (1ULL << 7)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_REG
+# define LANDLOCK_ACCESS_FS_MAKE_REG (1ULL << 8)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_SOCK
+# define LANDLOCK_ACCESS_FS_MAKE_SOCK (1ULL << 9)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_FIFO
+# define LANDLOCK_ACCESS_FS_MAKE_FIFO (1ULL << 10)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_BLOCK
+# define LANDLOCK_ACCESS_FS_MAKE_BLOCK (1ULL << 11)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_MAKE_SYM
+# define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_REFER
+# define LANDLOCK_ACCESS_FS_REFER (1ULL << 13)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_TRUNCATE
+# define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14)
+#endif
+
+#ifndef LANDLOCK_ACCESS_FS_IOCTL_DEV
+# define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15)
+#endif
+
+#ifndef LANDLOCK_ACCESS_NET_BIND_TCP
+# define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0)
+#endif
+
+#ifndef LANDLOCK_ACCESS_NET_CONNECT_TCP
+# define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1)
+#endif
+
+#endif
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox:
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
2024-07-10 18:01 ` [LTP] [PATCH v2 01/11] Add landlock syscalls definitions Andrea Cervesato
2024-07-10 18:01 ` [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback Andrea Cervesato
@ 2024-07-10 18:01 ` Andrea Cervesato
2024-07-11 3:47 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 04/11] Add SAFE_PRCTL macro Andrea Cervesato
` (7 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:01 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
- SAFE_LANDLOCK_CREATE_RULESET
- SAFE_LANDLOCK_ADD_RULE
- SAFE_LANDLOCK_RESTRICT_SELF
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/lapi/landlock.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/include/lapi/landlock.h b/include/lapi/landlock.h
index 2ee51b340..6d85eb12e 100644
--- a/include/lapi/landlock.h
+++ b/include/lapi/landlock.h
@@ -12,6 +12,8 @@
# include <linux/landlock.h>
#endif
+#include "lapi/syscalls.h"
+
#ifndef HAVE_STRUCT_LANDLOCK_RULESET_ATTR
struct landlock_ruleset_attr
{
@@ -120,4 +122,63 @@ struct landlock_net_port_attr
# define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1)
#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)
+{
+ int rval;
+
+ rval = tst_syscall(__NR_landlock_create_ruleset, attr, size, flags);
+ if (rval == -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "landlock_create_ruleset(%p, %lu, %u)",
+ attr, size, flags);
+ }
+
+ return rval;
+}
+
+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 rval;
+
+ rval = tst_syscall(__NR_landlock_add_rule,
+ ruleset_fd, rule_type, rule_attr, flags);
+
+ if (rval == -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "landlock_add_rule(%d, %d, %p, %u)",
+ ruleset_fd, rule_type, rule_attr, flags);
+ }
+
+ return rval;
+}
+
+static inline int safe_landlock_restrict_self(const char *file, const int lineno,
+ int ruleset_fd, int flags)
+{
+ int rval;
+
+ rval = tst_syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
+ if (rval == -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "landlock_restrict_self(%d, %u)",
+ ruleset_fd, flags);
+ }
+
+ return rval;
+}
+
+#define SAFE_LANDLOCK_CREATE_RULESET(attr, size, flags) \
+ safe_landlock_create_ruleset(__FILE__, __LINE__, (attr), (size), (flags))
+
+#define SAFE_LANDLOCK_ADD_RULE(ruleset_fd, rule_type, rule_attr, flags) \
+ safe_landlock_add_rule(__FILE__, __LINE__, \
+ (ruleset_fd), (rule_type), (rule_attr), (flags))
+
+#define SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, flags) \
+ safe_landlock_restrict_self(__FILE__, __LINE__, (ruleset_fd), (flags))
+
#endif
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 04/11] Add SAFE_PRCTL macro
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (2 preceding siblings ...)
2024-07-10 18:01 ` [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox: Andrea Cervesato
@ 2024-07-10 18:01 ` Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 05/11] Add landlock01 test Andrea Cervesato
` (6 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:01 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/tst_safe_macros.h | 6 ++++++
lib/tst_safe_macros.c | 17 +++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/include/tst_safe_macros.h b/include/tst_safe_macros.h
index 08b8e930a..92b9bc119 100644
--- a/include/tst_safe_macros.h
+++ b/include/tst_safe_macros.h
@@ -503,4 +503,10 @@ int safe_sscanf(const char *file, const int lineno, const char *restrict buffer,
#define SAFE_SSCANF(buffer, format, ...) \
safe_sscanf(__FILE__, __LINE__, (buffer), (format), ##__VA_ARGS__)
+int safe_prctl(const char *file, const int lineno,
+ int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5);
+#define SAFE_PRCTL(option, arg2, arg3, arg4, arg5) \
+ safe_prctl(__FILE__, __LINE__, (option), (arg2), (arg3), (arg4), (arg5))
+
#endif /* TST_SAFE_MACROS_H__ */
diff --git a/lib/tst_safe_macros.c b/lib/tst_safe_macros.c
index 4e48c427b..9301f3dd2 100644
--- a/lib/tst_safe_macros.c
+++ b/lib/tst_safe_macros.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include <sched.h>
#include <sys/ptrace.h>
+#include <sys/prctl.h>
#include "config.h"
#ifdef HAVE_SYS_FANOTIFY_H
# include <sys/fanotify.h>
@@ -710,3 +711,19 @@ int safe_mprotect(const char *file, const int lineno,
return rval;
}
+
+int safe_prctl(const char *file, const int lineno,
+ int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5)
+{
+ int rval;
+
+ rval = prctl(option, arg2, arg3, arg4, arg5);
+ if (rval == -1) {
+ tst_brk_(file, lineno, TBROK | TERRNO,
+ "prctl(%d, %lu, %lu, %lu, %lu)",
+ option, arg2, arg3, arg4, arg5);
+ }
+
+ return rval;
+}
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 05/11] Add landlock01 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (3 preceding siblings ...)
2024-07-10 18:01 ` [LTP] [PATCH v2 04/11] Add SAFE_PRCTL macro Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-11 3:16 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 06/11] Add landlock02 test Andrea Cervesato
` (5 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies that landlock_create_ruleset syscall fails with the
right error codes:
- EINVAL Unknown flags, or unknown access, or too small size
- E2BIG size is too big
- EFAULT attr was not a valid address
- ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 2 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/Makefile | 7 ++
testcases/kernel/syscalls/landlock/landlock01.c | 92 ++++++++++++++++++++++
.../kernel/syscalls/landlock/landlock_common.h | 74 +++++++++++++++++
5 files changed, 176 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index b6cadb2df..667e419a3 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -684,6 +684,8 @@ kill11 kill11
kill12 kill12
kill13 kill13
+landlock01 landlock01
+
lchown01 lchown01
lchown01_16 lchown01_16
lchown02 lchown02
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
new file mode 100644
index 000000000..b69f9b94a
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -0,0 +1 @@
+landlock01
diff --git a/testcases/kernel/syscalls/landlock/Makefile b/testcases/kernel/syscalls/landlock/Makefile
new file mode 100644
index 000000000..8cf1b9024
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/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/landlock/landlock01.c b/testcases/kernel/syscalls/landlock/landlock01.c
new file mode 100644
index 000000000..90f338fb0
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock01.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that landlock_create_ruleset syscall fails with the right
+ * error codes:
+ *
+ * - EINVAL Unknown flags, or unknown access, or too small size
+ * - E2BIG size is too big
+ * - EFAULT attr was not a valid address
+ * - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
+ */
+
+#include "landlock_common.h"
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static struct landlock_ruleset_attr *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;
+ uint64_t access_fs;
+ size_t *size;
+ uint32_t flags;
+ int exp_errno;
+ char *msg;
+} tcases[] = {
+ {&ruleset_attr, -1, &rule_size, 0, EINVAL, "Unknown access"},
+ {&ruleset_attr, 0, &rule_small_size, 0, EINVAL, "Size is too small"},
+ {&ruleset_attr, 0, &rule_size, -1, EINVAL, "Unknown flags"},
+ {&ruleset_attr, 0, &rule_big_size, 0, E2BIG, "Size is too big"},
+ {&null_attr, 0, &rule_size, 0, EFAULT, "Invalid attr address"},
+ {&ruleset_attr, 0, &rule_size, 0, ENOMSG, "Empty accesses"},
+};
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ if (*tc->attr)
+ (*tc->attr)->handled_access_fs = tc->access_fs;
+
+ TST_EXP_FAIL(tst_syscall(__NR_landlock_create_ruleset,
+ *tc->attr, *tc->size, tc->flags),
+ tc->exp_errno,
+ "%s",
+ tc->msg);
+
+ if (TST_RET >= 0)
+ SAFE_CLOSE(TST_RET);
+}
+
+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);
+#else
+ rule_small_size = rule_size - 1;
+#endif
+
+ rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .min_kver = "5.13",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ {}
+ },
+};
diff --git a/testcases/kernel/syscalls/landlock/landlock_common.h b/testcases/kernel/syscalls/landlock/landlock_common.h
new file mode 100644
index 000000000..66f8fd19a
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock_common.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#ifndef LANDLOCK_COMMON_H
+
+#include "tst_test.h"
+#include "lapi/prctl.h"
+#include "lapi/fcntl.h"
+#include "lapi/landlock.h"
+
+static inline void verify_landlock_is_enabled(void)
+{
+ int abi;
+
+ abi = tst_syscall(__NR_landlock_create_ruleset,
+ NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
+
+ if (abi < 0) {
+ if (errno == EOPNOTSUPP) {
+ tst_brk(TCONF, "Landlock is currently disabled. "
+ "Please enable it either via CONFIG_LSM or "
+ "'lsm' kernel parameter.");
+ }
+
+ tst_brk(TBROK | TERRNO, "landlock_create_ruleset error");
+ }
+
+ tst_res(TINFO, "Landlock ABI v%d", abi);
+}
+
+static inline void apply_landlock_rule(
+ struct landlock_path_beneath_attr *path_beneath_attr,
+ const int ruleset_fd,
+ const int access,
+ const char *path)
+{
+ path_beneath_attr->allowed_access = access;
+ path_beneath_attr->parent_fd = SAFE_OPEN(path, O_PATH | O_CLOEXEC);
+
+ SAFE_LANDLOCK_ADD_RULE(
+ ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ path_beneath_attr,
+ 0);
+
+ SAFE_CLOSE(path_beneath_attr->parent_fd);
+}
+
+static inline void enforce_ruleset(const int ruleset_fd)
+{
+ SAFE_PRCTL(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0);
+}
+
+static inline void apply_landlock_layer(
+ struct landlock_ruleset_attr *ruleset_attr,
+ 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);
+
+ apply_landlock_rule(path_beneath_attr, ruleset_fd, access, path);
+ enforce_ruleset(ruleset_fd);
+
+ SAFE_CLOSE(ruleset_fd);
+}
+
+#endif
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 06/11] Add landlock02 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (4 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 05/11] Add landlock01 test Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 07/11] Add landlock03 test Andrea Cervesato
` (4 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies that landlock_add_rule syscall fails with the
right error codes:
- EINVAL flags is not 0, or the rule accesses are inconsistent
- ENOMSG Empty accesses (i.e., rule_attr->allowed_access is 0)
- EBADF ruleset_fd is not a file descriptor for the current
thread, or a member of rule_attr is not a file descriptor as
expected
- EBADFD ruleset_fd is not a ruleset file descriptor, or a member of
rule_attr is not the expected file descriptor type
- EFAULT rule_attr was not a valid address
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/landlock02.c | 153 ++++++++++++++++++++++++
3 files changed, 155 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 667e419a3..25a99e6f1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -685,6 +685,7 @@ kill12 kill12
kill13 kill13
landlock01 landlock01
+landlock02 landlock02
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index b69f9b94a..ffed4abd2 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -1 +1,2 @@
landlock01
+landlock02
diff --git a/testcases/kernel/syscalls/landlock/landlock02.c b/testcases/kernel/syscalls/landlock/landlock02.c
new file mode 100644
index 000000000..0e2da7ef5
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock02.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that landlock_add_rule syscall fails with the right
+ * error codes:
+ *
+ * - EINVAL flags is not 0, or the rule accesses are inconsistent
+ * - ENOMSG Empty accesses (i.e., rule_attr->allowed_access is 0)
+ * - EBADF ruleset_fd is not a file descriptor for the current thread,
+ * or a member of rule_attr is not a file descriptor as expected
+ * - EBADFD ruleset_fd is not a ruleset file descriptor, or a member of
+ * rule_attr is not the expected file descriptor type
+ * - EFAULT rule_attr was not a valid address
+ */
+
+#include "landlock_common.h"
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static struct landlock_path_beneath_attr *path_beneath_attr;
+static struct landlock_path_beneath_attr *rule_null;
+static int ruleset_fd;
+static int invalid_fd = -1;
+
+static struct tcase {
+ int *fd;
+ enum landlock_rule_type rule_type;
+ struct landlock_path_beneath_attr **attr;
+ int access;
+ int parent_fd;
+ uint32_t flags;
+ int exp_errno;
+ char *msg;
+} tcases[] = {
+ {
+ &ruleset_fd,
+ 0,
+ &path_beneath_attr,
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ 0,
+ 1,
+ EINVAL,
+ "Invalid flags"
+ },
+ {
+ &ruleset_fd,
+ 0,
+ &path_beneath_attr,
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ 0,
+ 0,
+ EINVAL,
+ "Invalid rule type"
+ },
+ {
+ &ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_attr,
+ 0,
+ 0,
+ 0,
+ ENOMSG,
+ "Empty accesses"
+ },
+ {
+ &invalid_fd,
+ 0,
+ &path_beneath_attr,
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ 0,
+ 0,
+ EBADF,
+ "Invalid file descriptor"
+ },
+ {
+ &ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_attr,
+ LANDLOCK_ACCESS_FS_EXECUTE,
+ -1,
+ 0,
+ EBADF,
+ "Invalid parent fd"
+ },
+ {
+ &ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ &rule_null,
+ 0,
+ 0,
+ 0,
+ EFAULT,
+ "Invalid rule attr"
+ },
+};
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ if (*tc->attr) {
+ (*tc->attr)->allowed_access = tc->access;
+ (*tc->attr)->parent_fd = tc->parent_fd;
+ }
+
+ TST_EXP_FAIL(tst_syscall(__NR_landlock_add_rule,
+ *tc->fd, tc->rule_type, *tc->attr, tc->flags),
+ tc->exp_errno,
+ "%s",
+ tc->msg);
+}
+
+static void setup(void)
+{
+ verify_landlock_is_enabled();
+
+ 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));
+}
+
+static void cleanup(void)
+{
+ if (ruleset_fd != -1)
+ SAFE_CLOSE(ruleset_fd);
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .min_kver = "5.13",
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ {}
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 07/11] Add landlock03 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (5 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 06/11] Add landlock02 test Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h Andrea Cervesato
` (3 subsequent siblings)
10 siblings, 0 replies; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies that landlock_restrict_self syscall fails with the
right error codes:
- EINVAL flags is not 0
- EBADF ruleset_fd is not a file descriptor for the current thread
- EBADFD ruleset_fd is not a ruleset file descriptor
- EPERM ruleset doesn't have CAP_SYS_ADMIN in its namespace
- E2BIG The maximum number of stacked rulesets is reached for the
current thread
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/landlock03.c | 119 ++++++++++++++++++++++++
3 files changed, 121 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 25a99e6f1..269cf24b1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -686,6 +686,7 @@ kill13 kill13
landlock01 landlock01
landlock02 landlock02
+landlock03 landlock03
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index ffed4abd2..f79cd090b 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -1,2 +1,3 @@
landlock01
landlock02
+landlock03
diff --git a/testcases/kernel/syscalls/landlock/landlock03.c b/testcases/kernel/syscalls/landlock/landlock03.c
new file mode 100644
index 000000000..6511e24a7
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock03.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that landlock_restrict_self syscall fails with the right
+ * error codes:
+ *
+ * - EINVAL flags is not 0
+ * - EBADF ruleset_fd is not a file descriptor for the current thread
+ * - EBADFD ruleset_fd is not a ruleset file descriptor
+ * - EPERM ruleset doesn't have CAP_SYS_ADMIN in its namespace
+ * - E2BIG The maximum number of stacked rulesets is reached for the current
+ * thread
+ */
+
+#include "landlock_common.h"
+
+#define MAX_STACKED_RULESETS 16
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static int ruleset_fd = -1;
+static int ruleset_invalid = -1;
+static int file_fd = -1;
+
+static struct tst_cap dropadmin = {
+ .action = TST_CAP_DROP,
+ .id = CAP_SYS_ADMIN,
+ .name = "CAP_SYS_ADMIN",
+};
+
+static struct tst_cap needadmin = {
+ .action = TST_CAP_REQ,
+ .id = CAP_SYS_ADMIN,
+ .name = "CAP_SYS_ADMIN",
+};
+
+static struct tcase {
+ int *fd;
+ uint32_t flags;
+ int exp_errno;
+ char *msg;
+} tcases[] = {
+ {&ruleset_fd, -1, EINVAL, "Invalid flags"},
+ {&ruleset_invalid, 0, EBADF, "Invalid file descriptor"},
+ {&file_fd, 0, EBADFD, "Not a ruleset file descriptor"},
+ {&ruleset_fd, 0, EPERM, "File descriptor doesn't have CAP_SYS_ADMIN"},
+ {&ruleset_fd, 0, E2BIG, "Maximum number of stacked rulesets is reached"},
+};
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+
+ if (tc->exp_errno == EPERM)
+ tst_cap_action(&dropadmin);
+
+ if (tc->exp_errno == E2BIG) {
+ for (int i = 0; i < MAX_STACKED_RULESETS; i++) {
+ TST_EXP_PASS_SILENT(tst_syscall(__NR_landlock_restrict_self,
+ *tc->fd, tc->flags));
+ if (TST_RET == -1)
+ return;
+ }
+ }
+
+ TST_EXP_FAIL(tst_syscall(__NR_landlock_restrict_self, *tc->fd, tc->flags),
+ tc->exp_errno,
+ "%s", tc->msg);
+
+ if (tc->exp_errno == EPERM)
+ tst_cap_action(&needadmin);
+}
+
+static void setup(void)
+{
+ verify_landlock_is_enabled();
+
+ 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));
+
+ file_fd = SAFE_OPEN("junk.bin", O_CREAT, 0777);
+}
+
+static void cleanup(void)
+{
+ if (ruleset_fd != -1)
+ SAFE_CLOSE(ruleset_fd);
+
+ if (file_fd != -1)
+ SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .min_kver = "5.13",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ {}
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (6 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 07/11] Add landlock03 test Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-11 3:49 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 09/11] Add landlock04 test Andrea Cervesato
` (2 subsequent siblings)
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
include/lapi/capability.h | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/include/lapi/capability.h b/include/lapi/capability.h
index 2b593797c..0f317d6d7 100644
--- a/include/lapi/capability.h
+++ b/include/lapi/capability.h
@@ -44,14 +44,18 @@
# define CAP_SYS_TIME 25
#endif
-#ifndef CAP_AUDIT_READ
-# define CAP_AUDIT_READ 37
-#endif
-
#ifndef CAP_SYS_RESOURCE
# define CAP_SYS_RESOURCE 24
#endif
+#ifndef CAP_MKNOD
+# define CAP_MKNOD 27
+#endif
+
+#ifndef CAP_AUDIT_READ
+# define CAP_AUDIT_READ 37
+#endif
+
#ifndef CAP_BPF
# define CAP_BPF 39
#endif
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 09/11] Add landlock04 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (7 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-11 9:33 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 10/11] Add landlock05 test Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 11/11] Add landlock06 test Andrea Cervesato
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies that all landlock rules are working properly.
The way we do it is to verify that all disabled syscalls are not
working but the one we enabled via specifc landlock rules.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 2 +
testcases/kernel/syscalls/landlock/landlock04.c | 176 +++++++++++
testcases/kernel/syscalls/landlock/landlock_exec.c | 9 +
.../kernel/syscalls/landlock/landlock_tester.h | 350 +++++++++++++++++++++
5 files changed, 538 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 269cf24b1..10b54ae84 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -687,6 +687,7 @@ kill13 kill13
landlock01 landlock01
landlock02 landlock02
landlock03 landlock03
+landlock04 landlock04
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index f79cd090b..4fe8d7cba 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -1,3 +1,5 @@
+landlock_exec
landlock01
landlock02
landlock03
+landlock04
diff --git a/testcases/kernel/syscalls/landlock/landlock04.c b/testcases/kernel/syscalls/landlock/landlock04.c
new file mode 100644
index 000000000..1567328bb
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock04.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies that all landlock rules are working properly. The way we
+ * do it is to verify that all disabled syscalls are not working but the one we
+ * enabled via specifc landlock rules.
+ */
+
+#include "landlock_common.h"
+#include "landlock_tester.h"
+
+#define ACCESS_NAME(x) #x
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static struct landlock_path_beneath_attr *path_beneath_attr;
+
+struct rule_access {
+ char *path;
+ int access;
+};
+
+static struct tvariant {
+ int access;
+ char *desc;
+} tvariants[] = {
+ {
+ LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_EXECUTE,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_EXECUTE)
+ },
+ {
+ LANDLOCK_ACCESS_FS_WRITE_FILE,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_WRITE_FILE)
+ },
+ {
+ LANDLOCK_ACCESS_FS_READ_FILE,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_FILE)
+ },
+ {
+ LANDLOCK_ACCESS_FS_READ_DIR,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_DIR)
+ },
+ {
+ LANDLOCK_ACCESS_FS_REMOVE_DIR,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_DIR)
+ },
+ {
+ LANDLOCK_ACCESS_FS_REMOVE_FILE,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_FILE)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_CHAR,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_CHAR)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_BLOCK,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_BLOCK)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_REG,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_REG)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_SOCK,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SOCK)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_FIFO,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_FIFO)
+ },
+ {
+ LANDLOCK_ACCESS_FS_MAKE_SYM,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SYM)
+ },
+ {
+ LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_TRUNCATE,
+ ACCESS_NAME(LANDLOCK_ACCESS_FS_TRUNCATE)
+ },
+};
+
+static void run(void)
+{
+ if (!SAFE_FORK()) {
+ struct tvariant variant = tvariants[tst_variant];
+
+ tester_run_all_rules(variant.access);
+ _exit(0);
+ }
+}
+
+static void setup(void)
+{
+ struct tvariant variant = tvariants[tst_variant];
+ int ruleset_fd;
+
+ verify_landlock_is_enabled();
+ tester_create_tree();
+
+ tst_res(TINFO, "Testing %s", variant.desc);
+
+ ruleset_attr->handled_access_fs = tester_get_all_rules();
+
+ ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
+ ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
+
+ /* since our binary is dynamically linked, we need to enable libraries
+ * to be read and executed
+ */
+ struct rule_access rules[] = {
+ {"/lib", LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_EXECUTE},
+ {"/lib64", LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_EXECUTE},
+ {SANDBOX_FOLDER, variant.access}
+ };
+ int num_of_rules = ARRAY_SIZE(rules);
+
+ for (int i = 0; i < num_of_rules; i++) {
+ if (access(rules[i].path, F_OK) == -1)
+ continue;
+
+ path_beneath_attr->allowed_access = rules[i].access;
+ path_beneath_attr->parent_fd = SAFE_OPEN(rules[i].path, O_PATH | O_CLOEXEC);
+
+ SAFE_LANDLOCK_ADD_RULE(
+ ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ path_beneath_attr,
+ 0);
+
+ SAFE_CLOSE(path_beneath_attr->parent_fd);
+ }
+
+ enforce_ruleset(ruleset_fd);
+ SAFE_CLOSE(ruleset_fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .min_kver = "5.13",
+ .forks_child = 1,
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .test_variants = ARRAY_SIZE(tvariants),
+ .resource_files = (const char *[]) {
+ TESTAPP,
+ NULL,
+ },
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ TST_CAP(TST_CAP_REQ, CAP_MKNOD),
+ {}
+ },
+ .format_device = 1,
+ .mount_device = 1,
+ .mntpoint = SANDBOX_FOLDER,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *[]) {
+ "vfat",
+ "exfat",
+ NULL
+ },
+ .max_runtime = 3600,
+};
diff --git a/testcases/kernel/syscalls/landlock/landlock_exec.c b/testcases/kernel/syscalls/landlock/landlock_exec.c
new file mode 100644
index 000000000..aae5c76b2
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock_exec.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+int main(void)
+{
+ return 0;
+}
diff --git a/testcases/kernel/syscalls/landlock/landlock_tester.h b/testcases/kernel/syscalls/landlock/landlock_tester.h
new file mode 100644
index 000000000..89ca085d7
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock_tester.h
@@ -0,0 +1,350 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+#ifndef LANDLOCK_TESTER_H
+
+#include "tst_test.h"
+#include "lapi/landlock.h"
+#include <sys/sysmacros.h>
+
+#define PERM_MODE 0700
+
+#define SANDBOX_FOLDER "sandbox"
+#define TESTAPP "landlock_exec"
+
+#define FILE_EXEC SANDBOX_FOLDER"/"TESTAPP
+#define FILE_READ SANDBOX_FOLDER"/file_read"
+#define FILE_WRITE SANDBOX_FOLDER"/file_write"
+#define FILE_REMOVE SANDBOX_FOLDER"/file_remove"
+#define FILE_UNLINK SANDBOX_FOLDER"/file_unlink"
+#define FILE_UNLINKAT SANDBOX_FOLDER"/file_unlinkat"
+#define FILE_TRUNCATE SANDBOX_FOLDER"/file_truncate"
+#define FILE_REGULAR SANDBOX_FOLDER"/regular0"
+#define FILE_SOCKET SANDBOX_FOLDER"/socket0"
+#define FILE_FIFO SANDBOX_FOLDER"/fifo0"
+#define FILE_SYM0 SANDBOX_FOLDER"/symbolic0"
+#define FILE_SYM1 SANDBOX_FOLDER"/symbolic1"
+#define DIR_READDIR SANDBOX_FOLDER"/dir_readdir"
+#define DIR_RMDIR SANDBOX_FOLDER"/dir_rmdir"
+#define DEV_CHAR0 SANDBOX_FOLDER"/chardev0"
+#define DEV_BLK0 SANDBOX_FOLDER"/blkdev0"
+
+#define ALL_RULES (\
+ LANDLOCK_ACCESS_FS_EXECUTE | \
+ LANDLOCK_ACCESS_FS_WRITE_FILE | \
+ LANDLOCK_ACCESS_FS_READ_FILE | \
+ LANDLOCK_ACCESS_FS_READ_DIR | \
+ LANDLOCK_ACCESS_FS_REMOVE_DIR | \
+ LANDLOCK_ACCESS_FS_REMOVE_FILE | \
+ LANDLOCK_ACCESS_FS_MAKE_CHAR | \
+ LANDLOCK_ACCESS_FS_MAKE_DIR | \
+ LANDLOCK_ACCESS_FS_MAKE_REG | \
+ LANDLOCK_ACCESS_FS_MAKE_SOCK | \
+ LANDLOCK_ACCESS_FS_MAKE_FIFO | \
+ LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
+ LANDLOCK_ACCESS_FS_MAKE_SYM | \
+ LANDLOCK_ACCESS_FS_REFER | \
+ LANDLOCK_ACCESS_FS_TRUNCATE | \
+ LANDLOCK_ACCESS_NET_BIND_TCP | \
+ LANDLOCK_ACCESS_NET_CONNECT_TCP | \
+ LANDLOCK_ACCESS_FS_IOCTL_DEV)
+
+static char *readdir_files[] = {
+ DIR_READDIR"/file0",
+ DIR_READDIR"/file1",
+ DIR_READDIR"/file2",
+};
+
+static int dev_chr;
+static int dev_blk;
+
+static int tester_get_all_rules(void)
+{
+ int abi;
+ int all_rules = ALL_RULES;
+
+ abi = SAFE_LANDLOCK_CREATE_RULESET(
+ NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
+
+ if (abi < 2)
+ all_rules &= ~LANDLOCK_ACCESS_FS_REFER;
+
+ if (abi < 3)
+ all_rules &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
+
+ if (abi < 4) {
+ all_rules &= ~(LANDLOCK_ACCESS_NET_BIND_TCP |
+ LANDLOCK_ACCESS_NET_CONNECT_TCP);
+ }
+
+ if (abi < 5)
+ all_rules &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
+
+ return all_rules;
+}
+
+static void tester_create_tree(void)
+{
+ if (access(SANDBOX_FOLDER, F_OK) == -1)
+ SAFE_MKDIR(SANDBOX_FOLDER, PERM_MODE);
+
+ /* folders */
+ SAFE_MKDIR(DIR_RMDIR, PERM_MODE);
+ SAFE_MKDIR(DIR_READDIR, PERM_MODE);
+ for (size_t i = 0; i < ARRAY_SIZE(readdir_files); i++)
+ SAFE_TOUCH(readdir_files[i], PERM_MODE, NULL);
+
+ /* files */
+ tst_fill_file(FILE_READ, 'a', getpagesize(), 1);
+ SAFE_TOUCH(FILE_WRITE, PERM_MODE, NULL);
+ SAFE_TOUCH(FILE_REMOVE, PERM_MODE, NULL);
+ SAFE_TOUCH(FILE_UNLINK, PERM_MODE, NULL);
+ SAFE_TOUCH(FILE_UNLINKAT, PERM_MODE, NULL);
+ SAFE_TOUCH(FILE_TRUNCATE, PERM_MODE, NULL);
+ SAFE_TOUCH(FILE_SYM0, PERM_MODE, NULL);
+ SAFE_CP(TESTAPP, FILE_EXEC);
+
+ /* devices */
+ dev_chr = makedev(1, 3);
+ dev_blk = makedev(7, 0);
+}
+
+static void _test_exec(const int result)
+{
+ int status;
+ pid_t pid;
+ char *const args[] = {(char *)FILE_EXEC, NULL};
+
+ tst_res(TINFO, "Test binary execution");
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ int rval;
+
+ if (result == TPASS) {
+ rval = execve(FILE_EXEC, args, NULL);
+ if (rval == -1)
+ tst_res(TFAIL | TERRNO, "Failed to execute test binary");
+ } else {
+ TST_EXP_FAIL(execve(FILE_EXEC, args, NULL), EACCES);
+ }
+
+ _exit(1);
+ }
+
+ SAFE_WAITPID(pid, &status, 0);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+ return;
+
+ tst_res(result, "Test binary has been executed");
+}
+
+static void _test_write(const int result)
+{
+ tst_res(TINFO, "Test writing file");
+
+ if (result == TPASS)
+ TST_EXP_FD(open(FILE_WRITE, O_WRONLY, PERM_MODE));
+ else
+ TST_EXP_FAIL(open(FILE_WRITE, O_WRONLY, PERM_MODE), EACCES);
+
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
+}
+
+static void _test_read(const int result)
+{
+ tst_res(TINFO, "Test reading file");
+
+ if (result == TPASS)
+ TST_EXP_FD(open(FILE_READ, O_RDONLY, PERM_MODE));
+ else
+ TST_EXP_FAIL(open(FILE_READ, O_RDONLY, PERM_MODE), EACCES);
+
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
+}
+
+static void _test_readdir(const int result)
+{
+ tst_res(TINFO, "Test reading directory");
+
+ DIR *dir;
+ struct dirent *de;
+ int files_counted = 0;
+
+ dir = opendir(DIR_READDIR);
+ if (!dir) {
+ tst_res(result == TPASS ? TFAIL : TPASS,
+ "Can't read '%s' directory", DIR_READDIR);
+
+ return;
+ }
+
+ tst_res(result, "Can read '%s' directory", DIR_READDIR);
+ if (result == TFAIL)
+ return;
+
+ while ((de = readdir(dir)) != NULL) {
+ if (de->d_type != DT_REG)
+ continue;
+
+ for (size_t i = 0; i < ARRAY_SIZE(readdir_files); i++) {
+ if (readdir_files[i] == NULL)
+ continue;
+
+ if (strstr(readdir_files[i], de->d_name) != NULL)
+ files_counted++;
+ }
+ }
+
+ SAFE_CLOSEDIR(dir);
+
+ TST_EXP_EQ_LI(files_counted, ARRAY_SIZE(readdir_files));
+}
+
+static void _test_rmdir(const int result)
+{
+ tst_res(TINFO, "Test removing directory");
+
+ if (result == TPASS)
+ TST_EXP_PASS(rmdir(DIR_RMDIR));
+ else
+ TST_EXP_FAIL(rmdir(DIR_RMDIR), EACCES);
+}
+
+static void _test_rmfile(const int result)
+{
+ tst_res(TINFO, "Test removing file");
+
+ if (result == TPASS) {
+ TST_EXP_PASS(unlink(FILE_UNLINK));
+ TST_EXP_PASS(remove(FILE_REMOVE));
+ } else {
+ TST_EXP_FAIL(unlink(FILE_UNLINK), EACCES);
+ TST_EXP_FAIL(remove(FILE_REMOVE), EACCES);
+ }
+}
+
+static void _test_make(
+ const char *path,
+ const int type,
+ const int dev,
+ const int result)
+{
+ tst_res(TINFO, "Test normal or special files creation");
+
+ if (result == TPASS)
+ TST_EXP_PASS(mknod(path, type | 0400, dev));
+ else
+ TST_EXP_FAIL(mknod(path, type | 0400, dev), EACCES);
+}
+
+static void _test_symbolic(const int result)
+{
+ tst_res(TINFO, "Test symbolic links");
+
+ if (result == TPASS)
+ TST_EXP_PASS(symlink(FILE_SYM0, FILE_SYM1));
+ else
+ TST_EXP_FAIL(symlink(FILE_SYM0, FILE_SYM1), EACCES);
+}
+
+static void _test_truncate(const int result)
+{
+ int fd;
+
+ tst_res(TINFO, "Test truncating file");
+
+ if (result == TPASS) {
+ TST_EXP_PASS(truncate(FILE_TRUNCATE, 10));
+
+ fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY, PERM_MODE));
+ if (fd != -1) {
+ TST_EXP_PASS(ftruncate(fd, 10));
+ SAFE_CLOSE(fd);
+ }
+
+ fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY | O_TRUNC, PERM_MODE));
+ if (fd != -1)
+ SAFE_CLOSE(fd);
+ } else {
+ TST_EXP_FAIL(truncate(FILE_TRUNCATE, 10), EACCES);
+
+ fd = open(FILE_TRUNCATE, O_WRONLY, PERM_MODE);
+ if (fd != -1) {
+ TST_EXP_FAIL(ftruncate(fd, 10), EACCES);
+ SAFE_CLOSE(fd);
+ }
+
+ TST_EXP_FAIL(open(FILE_TRUNCATE, O_WRONLY | O_TRUNC, PERM_MODE),
+ EACCES);
+
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
+ }
+}
+
+static void tester_run_rules(const int rules, const int result)
+{
+ if (rules & LANDLOCK_ACCESS_FS_EXECUTE)
+ _test_exec(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_WRITE_FILE)
+ _test_write(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_READ_FILE)
+ _test_read(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_READ_DIR)
+ _test_readdir(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_REMOVE_DIR)
+ _test_rmdir(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_REMOVE_FILE)
+ _test_rmfile(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_CHAR)
+ _test_make(DEV_CHAR0, S_IFCHR, dev_chr, result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_BLOCK)
+ _test_make(DEV_BLK0, S_IFBLK, dev_blk, result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_REG)
+ _test_make(FILE_REGULAR, S_IFREG, 0, result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_SOCK)
+ _test_make(FILE_SOCKET, S_IFSOCK, 0, result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_FIFO)
+ _test_make(FILE_FIFO, S_IFIFO, 0, result);
+
+ if (rules & LANDLOCK_ACCESS_FS_MAKE_SYM)
+ _test_symbolic(result);
+
+ if (rules & LANDLOCK_ACCESS_FS_TRUNCATE) {
+ if ((tst_kvercmp(6, 2, 0)) < 0) {
+ tst_res(TINFO, "Skip truncate test. Minimum kernel version is 6.2");
+ return;
+ }
+
+ _test_truncate(result);
+ }
+}
+
+static inline void tester_run_all_rules(const int pass_rules)
+{
+ int fail_rules;
+ int all_rules;
+
+ all_rules = tester_get_all_rules();
+ fail_rules = all_rules & ~pass_rules;
+
+ tester_run_rules(pass_rules, TPASS);
+ tester_run_rules(fail_rules, TFAIL);
+}
+
+#endif
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 10/11] Add landlock05 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (8 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 09/11] Add landlock04 test Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 11/11] Add landlock06 test Andrea Cervesato
10 siblings, 0 replies; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies LANDLOCK_ACCESS_FS_REFER access in the
landlock sandbox. The feature is available since kernel 5.19.
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/landlock05.c | 114 ++++++++++++++++++++++++
3 files changed, 116 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index 10b54ae84..bb54538ed 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -688,6 +688,7 @@ landlock01 landlock01
landlock02 landlock02
landlock03 landlock03
landlock04 landlock04
+landlock05 landlock05
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index 4fe8d7cba..a7ea6be2e 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -3,3 +3,4 @@ landlock01
landlock02
landlock03
landlock04
+landlock05
diff --git a/testcases/kernel/syscalls/landlock/landlock05.c b/testcases/kernel/syscalls/landlock/landlock05.c
new file mode 100644
index 000000000..0ab93efbd
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock05.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies LANDLOCK_ACCESS_FS_REFER access in the
+ * landlock sandbox.
+ *
+ * [Algorithm]
+ *
+ * - apply LANDLOCK_ACCESS_FS_REFER in the folder1
+ * - apply LANDLOCK_ACCESS_FS_REFER in the folder2
+ * - create folder3
+ * - verify that file can be moved from folder1 to folder2
+ * - verify that file can't be moved from folder1 to folder3
+ */
+
+#include "landlock_common.h"
+
+#define MNTPOINT "sandbox"
+#define DIR1 MNTPOINT"/folder1"
+#define DIR2 MNTPOINT"/folder2"
+#define DIR3 MNTPOINT"/folder3"
+#define FILENAME1 DIR1"/file"
+#define FILENAME2 DIR2"/file"
+#define FILENAME3 DIR3"/file"
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static struct landlock_path_beneath_attr *path_beneath_attr;
+
+static void run(void)
+{
+ if (!SAFE_FORK()) {
+ TST_EXP_PASS(rename(FILENAME1, FILENAME2));
+ if (TST_RET == -1)
+ return;
+
+ TST_EXP_FAIL(rename(FILENAME2, FILENAME3), EXDEV);
+ TST_EXP_PASS(rename(FILENAME2, FILENAME1));
+
+ _exit(0);
+ }
+}
+
+static void setup(void)
+{
+ int ruleset_fd;
+
+ verify_landlock_is_enabled();
+
+ SAFE_MKDIR(DIR1, 0640);
+ SAFE_MKDIR(DIR2, 0640);
+ SAFE_MKDIR(DIR3, 0640);
+ SAFE_TOUCH(FILENAME1, 0640, NULL);
+
+ tst_res(TINFO, "Applying LANDLOCK_ACCESS_FS_REFER");
+
+ ruleset_attr->handled_access_fs =
+ LANDLOCK_ACCESS_FS_READ_FILE |
+ LANDLOCK_ACCESS_FS_WRITE_FILE |
+ LANDLOCK_ACCESS_FS_REFER;
+
+ ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
+ ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
+
+ apply_landlock_rule(
+ path_beneath_attr,
+ ruleset_fd,
+ LANDLOCK_ACCESS_FS_REFER,
+ DIR1);
+
+ apply_landlock_rule(
+ path_beneath_attr,
+ ruleset_fd,
+ LANDLOCK_ACCESS_FS_REFER,
+ DIR2);
+
+ enforce_ruleset(ruleset_fd);
+
+ SAFE_CLOSE(ruleset_fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .min_kver = "5.19",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ {}
+ },
+ .format_device = 1,
+ .mount_device = 1,
+ .mntpoint = MNTPOINT,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *[]) {
+ "vfat",
+ NULL
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [LTP] [PATCH v2 11/11] Add landlock06 test
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
` (9 preceding siblings ...)
2024-07-10 18:02 ` [LTP] [PATCH v2 10/11] Add landlock05 test Andrea Cervesato
@ 2024-07-10 18:02 ` Andrea Cervesato
2024-07-11 8:45 ` Petr Vorel
10 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato @ 2024-07-10 18:02 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies LANDLOCK_ACCESS_FS_IOCTL_DEV access in the
landlock sandbox by creating a pipe and testing that ioctl() can
be executed on it. The test is also verifying that some of the I/O
operations can be always executed no matter the sandbox rules.
This feature is available since kernel 6.10.
Reviewed-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/landlock/.gitignore | 1 +
testcases/kernel/syscalls/landlock/landlock06.c | 110 ++++++++++++++++++++++++
3 files changed, 112 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index bb54538ed..e2d32895e 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -689,6 +689,7 @@ landlock02 landlock02
landlock03 landlock03
landlock04 landlock04
landlock05 landlock05
+landlock06 landlock06
lchown01 lchown01
lchown01_16 lchown01_16
diff --git a/testcases/kernel/syscalls/landlock/.gitignore b/testcases/kernel/syscalls/landlock/.gitignore
index a7ea6be2e..315ac1dca 100644
--- a/testcases/kernel/syscalls/landlock/.gitignore
+++ b/testcases/kernel/syscalls/landlock/.gitignore
@@ -4,3 +4,4 @@ landlock02
landlock03
landlock04
landlock05
+landlock06
diff --git a/testcases/kernel/syscalls/landlock/landlock06.c b/testcases/kernel/syscalls/landlock/landlock06.c
new file mode 100644
index 000000000..3281c2d2d
--- /dev/null
+++ b/testcases/kernel/syscalls/landlock/landlock06.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test verifies LANDLOCK_ACCESS_FS_IOCTL_DEV access in the
+ * landlock sandbox by creating a pipe and testing that ioctl() can be executed
+ * on it. The test is also verifying that some of the I/O operations can be
+ * always executed no matter the sandbox rules.
+ */
+
+#include "landlock_common.h"
+#include <sys/ioctl.h>
+
+#define MNTPOINT "sandbox"
+#define FILENAME MNTPOINT"/fifo"
+
+static struct landlock_ruleset_attr *ruleset_attr;
+static struct landlock_path_beneath_attr *path_beneath_attr;
+static int file_fd;
+static int dev_fd;
+
+static void run(void)
+{
+ if (!SAFE_FORK()) {
+ int flag;
+ size_t sz = 0;
+
+ TST_EXP_PASS(ioctl(file_fd, FIONREAD, &sz));
+
+ /* check unrestrictable commands */
+ TST_EXP_PASS(ioctl(dev_fd, FIOCLEX));
+ TST_EXP_PASS(ioctl(dev_fd, FIONCLEX));
+ TST_EXP_PASS(ioctl(dev_fd, FIONBIO, &flag));
+ TST_EXP_PASS(ioctl(dev_fd, FIOASYNC, &flag));
+
+ _exit(0);
+ }
+}
+
+static void setup(void)
+{
+ int ruleset_fd;
+
+ verify_landlock_is_enabled();
+
+ SAFE_MKFIFO(FILENAME, 0640);
+
+ file_fd = SAFE_OPEN(FILENAME, O_RDONLY | O_NONBLOCK, 0640);
+ dev_fd = SAFE_OPEN("/dev/zero", O_RDONLY | O_NONBLOCK, 0640);
+
+ tst_res(TINFO, "Applying LANDLOCK_ACCESS_FS_IOCTL_DEV");
+
+ 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(
+ ruleset_attr,
+ path_beneath_attr,
+ MNTPOINT,
+ LANDLOCK_ACCESS_FS_IOCTL_DEV
+ );
+
+ SAFE_CLOSE(ruleset_fd);
+}
+
+static void cleanup(void)
+{
+ if (dev_fd != -1)
+ SAFE_CLOSE(dev_fd);
+
+ if (file_fd != -1)
+ SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .min_kver = "6.10",
+ .needs_tmpdir = 1,
+ .needs_root = 1,
+ .forks_child = 1,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_SECURITY_LANDLOCK=y",
+ NULL
+ },
+ .bufs = (struct tst_buffers []) {
+ {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)},
+ {&path_beneath_attr, .size = sizeof(struct landlock_path_beneath_attr)},
+ {},
+ },
+ .caps = (struct tst_cap []) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
+ {}
+ },
+ .format_device = 1,
+ .mount_device = 1,
+ .mntpoint = MNTPOINT,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *[]) {
+ "vfat",
+ NULL
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 01/11] Add landlock syscalls definitions
2024-07-10 18:01 ` [LTP] [PATCH v2 01/11] Add landlock syscalls definitions Andrea Cervesato
@ 2024-07-11 1:16 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 1:16 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Reviewed-by: Li Wang <liwang@redhat.com>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback
2024-07-10 18:01 ` [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback Andrea Cervesato
@ 2024-07-11 1:30 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 1:30 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Reviewed-by: Li Wang <liwang@redhat.com>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 05/11] Add landlock01 test
2024-07-10 18:02 ` [LTP] [PATCH v2 05/11] Add landlock01 test Andrea Cervesato
@ 2024-07-11 3:16 ` Li Wang
2024-07-11 7:06 ` Andrea Cervesato via ltp
0 siblings, 1 reply; 24+ messages in thread
From: Li Wang @ 2024-07-11 3:16 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
On Thu, Jul 11, 2024 at 2:02 AM Andrea Cervesato <andrea.cervesato@suse.de>
wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> This test verifies that landlock_create_ruleset syscall fails with the
> right error codes:
>
> - EINVAL Unknown flags, or unknown access, or too small size
> - E2BIG size is too big
> - EFAULT attr was not a valid address
> - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
>
> Reviewed-by: Li Wang <liwang@redhat.com>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> runtest/syscalls | 2 +
> testcases/kernel/syscalls/landlock/.gitignore | 1 +
> testcases/kernel/syscalls/landlock/Makefile | 7 ++
> testcases/kernel/syscalls/landlock/landlock01.c | 92
> ++++++++++++++++++++++
> .../kernel/syscalls/landlock/landlock_common.h | 74 +++++++++++++++++
> 5 files changed, 176 insertions(+)
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index b6cadb2df..667e419a3 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -684,6 +684,8 @@ kill11 kill11
> kill12 kill12
> kill13 kill13
>
> +landlock01 landlock01
> +
> lchown01 lchown01
> lchown01_16 lchown01_16
> lchown02 lchown02
> diff --git a/testcases/kernel/syscalls/landlock/.gitignore
> b/testcases/kernel/syscalls/landlock/.gitignore
> new file mode 100644
> index 000000000..b69f9b94a
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/.gitignore
> @@ -0,0 +1 @@
> +landlock01
> diff --git a/testcases/kernel/syscalls/landlock/Makefile
> b/testcases/kernel/syscalls/landlock/Makefile
> new file mode 100644
> index 000000000..8cf1b9024
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/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/landlock/landlock01.c
> b/testcases/kernel/syscalls/landlock/landlock01.c
> new file mode 100644
> index 000000000..90f338fb0
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock01.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
> andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This test verifies that landlock_create_ruleset syscall fails with the
> right
> + * error codes:
> + *
> + * - EINVAL Unknown flags, or unknown access, or too small size
> + * - E2BIG size is too big
> + * - EFAULT attr was not a valid address
> + * - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
> + */
> +
> +#include "landlock_common.h"
> +
> +static struct landlock_ruleset_attr *ruleset_attr;
> +static struct landlock_ruleset_attr *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;
> + uint64_t access_fs;
> + size_t *size;
> + uint32_t flags;
> + int exp_errno;
> + char *msg;
> +} tcases[] = {
> + {&ruleset_attr, -1, &rule_size, 0, EINVAL, "Unknown access"},
> + {&ruleset_attr, 0, &rule_small_size, 0, EINVAL, "Size is too
> small"},
> + {&ruleset_attr, 0, &rule_size, -1, EINVAL, "Unknown flags"},
> + {&ruleset_attr, 0, &rule_big_size, 0, E2BIG, "Size is too big"},
> + {&null_attr, 0, &rule_size, 0, EFAULT, "Invalid attr address"},
> + {&ruleset_attr, 0, &rule_size, 0, ENOMSG, "Empty accesses"},
> +};
> +
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> +
> + if (*tc->attr)
> + (*tc->attr)->handled_access_fs = tc->access_fs;
> +
> + TST_EXP_FAIL(tst_syscall(__NR_landlock_create_ruleset,
> + *tc->attr, *tc->size, tc->flags),
> + tc->exp_errno,
> + "%s",
> + tc->msg);
> +
> + if (TST_RET >= 0)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +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);
>
This is incorrect, at least decrease 1 more number:
rule_small_size = rule_size - sizeof(uint64_t) - 1;
But, those are quite unnecessary to add the if macro conditions,
as the kernel code explicitly compares the minimal struct with
handled_access_fs via:
offsetofend(typeof(ruleset_attr), handled_access_fs)
(and Mickael said it should never change for backward compatibility reason)
So it should be just simple like:
--- a/testcases/kernel/syscalls/landlock/landlock01.c
+++ b/testcases/kernel/syscalls/landlock/landlock01.c
@@ -62,11 +62,15 @@ static void setup(void)
rule_size = sizeof(struct landlock_ruleset_attr);
-#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET
- rule_small_size = rule_size - sizeof(uint64_t);
-#else
- rule_small_size = rule_size - 1;
-#endif
+ /*
+ * The new kernel introduces a new field 'handled_access_net' in the
+ * structure 'landlock_ruleset_attr'. However, in the function
+ * 'landlock_create_ruleset()', it still uses the first field
+ * 'handled_access_fs' to calculate the minimal size for backward
+ * compatibility reason. Therefore, here test 'sizeof(__u64) - 1' is
+ * sufficient to determine the minimum size for 'rule_small_size'.
+ */
+ rule_small_size = sizeof(__u64) - 1;
rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
}
> +#else
> + rule_small_size = rule_size - 1;
> +#endif
> +
> + rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
> +}
> +
> +static struct tst_test test = {
> + .test = run,
> + .tcnt = ARRAY_SIZE(tcases),
> + .setup = setup,
> + .min_kver = "5.13",
> + .needs_root = 1,
> + .needs_kconfigs = (const char *[]) {
> + "CONFIG_SECURITY_LANDLOCK=y",
> + NULL
> + },
> + .bufs = (struct tst_buffers []) {
> + {&ruleset_attr, .size = sizeof(struct
> landlock_ruleset_attr)},
> + {},
> + },
> + .caps = (struct tst_cap []) {
> + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
> + {}
> + },
> +};
> diff --git a/testcases/kernel/syscalls/landlock/landlock_common.h
> b/testcases/kernel/syscalls/landlock/landlock_common.h
> new file mode 100644
> index 000000000..66f8fd19a
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_common.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
> andrea.cervesato@suse.com>
> + */
> +
> +#ifndef LANDLOCK_COMMON_H
> +
> +#include "tst_test.h"
> +#include "lapi/prctl.h"
> +#include "lapi/fcntl.h"
> +#include "lapi/landlock.h"
> +
> +static inline void verify_landlock_is_enabled(void)
> +{
> + int abi;
> +
> + abi = tst_syscall(__NR_landlock_create_ruleset,
> + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
> +
> + if (abi < 0) {
> + if (errno == EOPNOTSUPP) {
> + tst_brk(TCONF, "Landlock is currently disabled. "
> + "Please enable it either via CONFIG_LSM or
> "
> + "'lsm' kernel parameter.");
> + }
> +
> + tst_brk(TBROK | TERRNO, "landlock_create_ruleset error");
> + }
> +
> + tst_res(TINFO, "Landlock ABI v%d", abi);
> +}
> +
> +static inline void apply_landlock_rule(
> + struct landlock_path_beneath_attr *path_beneath_attr,
> + const int ruleset_fd,
> + const int access,
> + const char *path)
> +{
> + path_beneath_attr->allowed_access = access;
> + path_beneath_attr->parent_fd = SAFE_OPEN(path, O_PATH | O_CLOEXEC);
> +
> + SAFE_LANDLOCK_ADD_RULE(
> + ruleset_fd,
> + LANDLOCK_RULE_PATH_BENEATH,
> + path_beneath_attr,
> + 0);
> +
> + SAFE_CLOSE(path_beneath_attr->parent_fd);
> +}
> +
> +static inline void enforce_ruleset(const int ruleset_fd)
> +{
> + SAFE_PRCTL(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
> + SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0);
> +}
> +
> +static inline void apply_landlock_layer(
> + struct landlock_ruleset_attr *ruleset_attr,
> + 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);
> +
> + apply_landlock_rule(path_beneath_attr, ruleset_fd, access, path);
> + enforce_ruleset(ruleset_fd);
> +
> + SAFE_CLOSE(ruleset_fd);
> +}
> +
> +#endif
>
> --
> 2.43.0
>
>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox:
2024-07-10 18:01 ` [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox: Andrea Cervesato
@ 2024-07-11 3:47 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 3:47 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Reviewed-by: Li Wang <liwang@redhat.com>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h
2024-07-10 18:02 ` [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h Andrea Cervesato
@ 2024-07-11 3:49 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 3:49 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Reviewed-by: Li Wang <liwang@redhat.com>
On Thu, Jul 11, 2024 at 2:04 AM Andrea Cervesato <andrea.cervesato@suse.de>
wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> include/lapi/capability.h | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/include/lapi/capability.h b/include/lapi/capability.h
> index 2b593797c..0f317d6d7 100644
> --- a/include/lapi/capability.h
> +++ b/include/lapi/capability.h
> @@ -44,14 +44,18 @@
> # define CAP_SYS_TIME 25
> #endif
>
> -#ifndef CAP_AUDIT_READ
> -# define CAP_AUDIT_READ 37
> -#endif
> -
> #ifndef CAP_SYS_RESOURCE
> # define CAP_SYS_RESOURCE 24
> #endif
>
> +#ifndef CAP_MKNOD
> +# define CAP_MKNOD 27
> +#endif
> +
> +#ifndef CAP_AUDIT_READ
> +# define CAP_AUDIT_READ 37
> +#endif
> +
> #ifndef CAP_BPF
> # define CAP_BPF 39
> #endif
>
> --
> 2.43.0
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 05/11] Add landlock01 test
2024-07-11 3:16 ` Li Wang
@ 2024-07-11 7:06 ` Andrea Cervesato via ltp
2024-07-11 7:30 ` Li Wang
0 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato via ltp @ 2024-07-11 7:06 UTC (permalink / raw)
To: Li Wang, Andrea Cervesato; +Cc: ltp
Hi,
On 7/11/24 05:16, Li Wang wrote:
> Hi Andrea,
>
> On Thu, Jul 11, 2024 at 2:02 AM Andrea Cervesato
> <andrea.cervesato@suse.de> wrote:
>
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> This test verifies that landlock_create_ruleset syscall fails with the
> right error codes:
>
> - EINVAL Unknown flags, or unknown access, or too small size
> - E2BIG size is too big
> - EFAULT attr was not a valid address
> - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
>
> Reviewed-by: Li Wang <liwang@redhat.com>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> runtest/syscalls | 2 +
> testcases/kernel/syscalls/landlock/.gitignore | 1 +
> testcases/kernel/syscalls/landlock/Makefile | 7 ++
> testcases/kernel/syscalls/landlock/landlock01.c | 92
> ++++++++++++++++++++++
> .../kernel/syscalls/landlock/landlock_common.h | 74
> +++++++++++++++++
> 5 files changed, 176 insertions(+)
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index b6cadb2df..667e419a3 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -684,6 +684,8 @@ kill11 kill11
> kill12 kill12
> kill13 kill13
>
> +landlock01 landlock01
> +
> lchown01 lchown01
> lchown01_16 lchown01_16
> lchown02 lchown02
> diff --git a/testcases/kernel/syscalls/landlock/.gitignore
> b/testcases/kernel/syscalls/landlock/.gitignore
> new file mode 100644
> index 000000000..b69f9b94a
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/.gitignore
> @@ -0,0 +1 @@
> +landlock01
> diff --git a/testcases/kernel/syscalls/landlock/Makefile
> b/testcases/kernel/syscalls/landlock/Makefile
> new file mode 100644
> index 000000000..8cf1b9024
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/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 <http://testcases.mk>
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> <http://generic_leaf_target.mk>
> diff --git a/testcases/kernel/syscalls/landlock/landlock01.c
> b/testcases/kernel/syscalls/landlock/landlock01.c
> new file mode 100644
> index 000000000..90f338fb0
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock01.c
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato
> <andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This test verifies that landlock_create_ruleset syscall fails
> with the right
> + * error codes:
> + *
> + * - EINVAL Unknown flags, or unknown access, or too small size
> + * - E2BIG size is too big
> + * - EFAULT attr was not a valid address
> + * - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
> + */
> +
> +#include "landlock_common.h"
> +
> +static struct landlock_ruleset_attr *ruleset_attr;
> +static struct landlock_ruleset_attr *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;
> + uint64_t access_fs;
> + size_t *size;
> + uint32_t flags;
> + int exp_errno;
> + char *msg;
> +} tcases[] = {
> + {&ruleset_attr, -1, &rule_size, 0, EINVAL, "Unknown access"},
> + {&ruleset_attr, 0, &rule_small_size, 0, EINVAL, "Size is
> too small"},
> + {&ruleset_attr, 0, &rule_size, -1, EINVAL, "Unknown flags"},
> + {&ruleset_attr, 0, &rule_big_size, 0, E2BIG, "Size is too
> big"},
> + {&null_attr, 0, &rule_size, 0, EFAULT, "Invalid attr
> address"},
> + {&ruleset_attr, 0, &rule_size, 0, ENOMSG, "Empty accesses"},
> +};
> +
> +static void run(unsigned int n)
> +{
> + struct tcase *tc = &tcases[n];
> +
> + if (*tc->attr)
> + (*tc->attr)->handled_access_fs = tc->access_fs;
> +
> + TST_EXP_FAIL(tst_syscall(__NR_landlock_create_ruleset,
> + *tc->attr, *tc->size, tc->flags),
> + tc->exp_errno,
> + "%s",
> + tc->msg);
> +
> + if (TST_RET >= 0)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +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);
>
>
> This is incorrect, at least decrease 1 more number:
> rule_small_size = rule_size - sizeof(uint64_t) - 1;
>
> But, those are quite unnecessary to add the if macro conditions,
> as the kernel code explicitly compares the minimal struct with
> handled_access_fs via:
>
> offsetofend(typeof(ruleset_attr), handled_access_fs)
>
I usually don't look at the kernel source code to write tests, because
for us it should be a black box that could have wrong documentation.
That's also the way we find bugs.
I would go for still using the macros, but removing 1 more byte from the
size when handled_access_net is defined.
> (and Mickael said it should never change for backward compatibility
> reason)
>
> So it should be just simple like:
>
> --- a/testcases/kernel/syscalls/landlock/landlock01.c
> +++ b/testcases/kernel/syscalls/landlock/landlock01.c
> @@ -62,11 +62,15 @@ static void setup(void)
>
> rule_size = sizeof(struct landlock_ruleset_attr);
>
> -#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET
> - rule_small_size = rule_size - sizeof(uint64_t);
> -#else
> - rule_small_size = rule_size - 1;
> -#endif
> + /*
> + * The new kernel introduces a new field 'handled_access_net'
> in the
> + * structure 'landlock_ruleset_attr'. However, in the function
> + * 'landlock_create_ruleset()', it still uses the first field
> + * 'handled_access_fs' to calculate the minimal size for backward
> + * compatibility reason. Therefore, here test 'sizeof(__u64) -
> 1' is
> + * sufficient to determine the minimum size for 'rule_small_size'.
> + */
> + rule_small_size = sizeof(__u64) - 1;
>
> rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
> }
>
> +#else
> + rule_small_size = rule_size - 1;
> +#endif
> +
> + rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
> +}
> +
> +static struct tst_test test = {
> + .test = run,
> + .tcnt = ARRAY_SIZE(tcases),
> + .setup = setup,
> + .min_kver = "5.13",
> + .needs_root = 1,
> + .needs_kconfigs = (const char *[]) {
> + "CONFIG_SECURITY_LANDLOCK=y",
> + NULL
> + },
> + .bufs = (struct tst_buffers []) {
> + {&ruleset_attr, .size = sizeof(struct
> landlock_ruleset_attr)},
> + {},
> + },
> + .caps = (struct tst_cap []) {
> + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
> + {}
> + },
> +};
> diff --git a/testcases/kernel/syscalls/landlock/landlock_common.h
> b/testcases/kernel/syscalls/landlock/landlock_common.h
> new file mode 100644
> index 000000000..66f8fd19a
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_common.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato
> <andrea.cervesato@suse.com>
> + */
> +
> +#ifndef LANDLOCK_COMMON_H
> +
> +#include "tst_test.h"
> +#include "lapi/prctl.h"
> +#include "lapi/fcntl.h"
> +#include "lapi/landlock.h"
> +
> +static inline void verify_landlock_is_enabled(void)
> +{
> + int abi;
> +
> + abi = tst_syscall(__NR_landlock_create_ruleset,
> + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
> +
> + if (abi < 0) {
> + if (errno == EOPNOTSUPP) {
> + tst_brk(TCONF, "Landlock is currently
> disabled. "
> + "Please enable it either via
> CONFIG_LSM or "
> + "'lsm' kernel parameter.");
> + }
> +
> + tst_brk(TBROK | TERRNO, "landlock_create_ruleset
> error");
> + }
> +
> + tst_res(TINFO, "Landlock ABI v%d", abi);
> +}
> +
> +static inline void apply_landlock_rule(
> + struct landlock_path_beneath_attr *path_beneath_attr,
> + const int ruleset_fd,
> + const int access,
> + const char *path)
> +{
> + path_beneath_attr->allowed_access = access;
> + path_beneath_attr->parent_fd = SAFE_OPEN(path, O_PATH |
> O_CLOEXEC);
> +
> + SAFE_LANDLOCK_ADD_RULE(
> + ruleset_fd,
> + LANDLOCK_RULE_PATH_BENEATH,
> + path_beneath_attr,
> + 0);
> +
> + SAFE_CLOSE(path_beneath_attr->parent_fd);
> +}
> +
> +static inline void enforce_ruleset(const int ruleset_fd)
> +{
> + SAFE_PRCTL(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
> + SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0);
> +}
> +
> +static inline void apply_landlock_layer(
> + struct landlock_ruleset_attr *ruleset_attr,
> + 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);
> +
> + apply_landlock_rule(path_beneath_attr, ruleset_fd, access,
> path);
> + enforce_ruleset(ruleset_fd);
> +
> + SAFE_CLOSE(ruleset_fd);
> +}
> +
> +#endif
>
> --
> 2.43.0
>
>
>
> --
> Regards,
> Li Wang
Andrea
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 05/11] Add landlock01 test
2024-07-11 7:06 ` Andrea Cervesato via ltp
@ 2024-07-11 7:30 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 7:30 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
On Thu, Jul 11, 2024 at 3:07 PM Andrea Cervesato <andrea.cervesato@suse.com>
wrote:
> Hi,
>
> On 7/11/24 05:16, Li Wang wrote:
>
> Hi Andrea,
>
> On Thu, Jul 11, 2024 at 2:02 AM Andrea Cervesato <andrea.cervesato@suse.de>
> wrote:
>
>> From: Andrea Cervesato <andrea.cervesato@suse.com>
>>
>> This test verifies that landlock_create_ruleset syscall fails with the
>> right error codes:
>>
>> - EINVAL Unknown flags, or unknown access, or too small size
>> - E2BIG size is too big
>> - EFAULT attr was not a valid address
>> - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
>>
>> Reviewed-by: Li Wang <liwang@redhat.com>
>> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
>> ---
>> runtest/syscalls | 2 +
>> testcases/kernel/syscalls/landlock/.gitignore | 1 +
>> testcases/kernel/syscalls/landlock/Makefile | 7 ++
>> testcases/kernel/syscalls/landlock/landlock01.c | 92
>> ++++++++++++++++++++++
>> .../kernel/syscalls/landlock/landlock_common.h | 74 +++++++++++++++++
>> 5 files changed, 176 insertions(+)
>>
>> diff --git a/runtest/syscalls b/runtest/syscalls
>> index b6cadb2df..667e419a3 100644
>> --- a/runtest/syscalls
>> +++ b/runtest/syscalls
>> @@ -684,6 +684,8 @@ kill11 kill11
>> kill12 kill12
>> kill13 kill13
>>
>> +landlock01 landlock01
>> +
>> lchown01 lchown01
>> lchown01_16 lchown01_16
>> lchown02 lchown02
>> diff --git a/testcases/kernel/syscalls/landlock/.gitignore
>> b/testcases/kernel/syscalls/landlock/.gitignore
>> new file mode 100644
>> index 000000000..b69f9b94a
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/landlock/.gitignore
>> @@ -0,0 +1 @@
>> +landlock01
>> diff --git a/testcases/kernel/syscalls/landlock/Makefile
>> b/testcases/kernel/syscalls/landlock/Makefile
>> new file mode 100644
>> index 000000000..8cf1b9024
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/landlock/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/landlock/landlock01.c
>> b/testcases/kernel/syscalls/landlock/landlock01.c
>> new file mode 100644
>> index 000000000..90f338fb0
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/landlock/landlock01.c
>> @@ -0,0 +1,92 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
>> andrea.cervesato@suse.com>
>> + */
>> +
>> +/*\
>> + * [Description]
>> + *
>> + * This test verifies that landlock_create_ruleset syscall fails with
>> the right
>> + * error codes:
>> + *
>> + * - EINVAL Unknown flags, or unknown access, or too small size
>> + * - E2BIG size is too big
>> + * - EFAULT attr was not a valid address
>> + * - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0)
>> + */
>> +
>> +#include "landlock_common.h"
>> +
>> +static struct landlock_ruleset_attr *ruleset_attr;
>> +static struct landlock_ruleset_attr *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;
>> + uint64_t access_fs;
>> + size_t *size;
>> + uint32_t flags;
>> + int exp_errno;
>> + char *msg;
>> +} tcases[] = {
>> + {&ruleset_attr, -1, &rule_size, 0, EINVAL, "Unknown access"},
>> + {&ruleset_attr, 0, &rule_small_size, 0, EINVAL, "Size is too
>> small"},
>> + {&ruleset_attr, 0, &rule_size, -1, EINVAL, "Unknown flags"},
>> + {&ruleset_attr, 0, &rule_big_size, 0, E2BIG, "Size is too big"},
>> + {&null_attr, 0, &rule_size, 0, EFAULT, "Invalid attr address"},
>> + {&ruleset_attr, 0, &rule_size, 0, ENOMSG, "Empty accesses"},
>> +};
>> +
>> +static void run(unsigned int n)
>> +{
>> + struct tcase *tc = &tcases[n];
>> +
>> + if (*tc->attr)
>> + (*tc->attr)->handled_access_fs = tc->access_fs;
>> +
>> + TST_EXP_FAIL(tst_syscall(__NR_landlock_create_ruleset,
>> + *tc->attr, *tc->size, tc->flags),
>> + tc->exp_errno,
>> + "%s",
>> + tc->msg);
>> +
>> + if (TST_RET >= 0)
>> + SAFE_CLOSE(TST_RET);
>> +}
>> +
>> +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);
>>
>
> This is incorrect, at least decrease 1 more number:
> rule_small_size = rule_size - sizeof(uint64_t) - 1;
>
> But, those are quite unnecessary to add the if macro conditions,
> as the kernel code explicitly compares the minimal struct with
> handled_access_fs via:
>
> offsetofend(typeof(ruleset_attr), handled_access_fs)
>
> I usually don't look at the kernel source code to write tests, because for
> us it should be a black box that could have wrong documentation.
> That's also the way we find bugs.
>
> I would go for still using the macros, but removing 1 more byte from the
> size when handled_access_net is defined.
>
Okay, fine.
We still have to adjust the case if someone introduces one more
new field similar to 'handled_access_net' to the structure in the future.
> (and Mickael said it should never change for backward compatibility reason)
>
> So it should be just simple like:
>
> --- a/testcases/kernel/syscalls/landlock/landlock01.c
> +++ b/testcases/kernel/syscalls/landlock/landlock01.c
> @@ -62,11 +62,15 @@ static void setup(void)
>
> rule_size = sizeof(struct landlock_ruleset_attr);
>
> -#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET
> - rule_small_size = rule_size - sizeof(uint64_t);
> -#else
> - rule_small_size = rule_size - 1;
> -#endif
> + /*
> + * The new kernel introduces a new field 'handled_access_net' in
> the
> + * structure 'landlock_ruleset_attr'. However, in the function
> + * 'landlock_create_ruleset()', it still uses the first field
> + * 'handled_access_fs' to calculate the minimal size for backward
> + * compatibility reason. Therefore, here test 'sizeof(__u64) - 1'
> is
> + * sufficient to determine the minimum size for 'rule_small_size'.
> + */
> + rule_small_size = sizeof(__u64) - 1;
>
> rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
> }
>
>
>
>> +#else
>> + rule_small_size = rule_size - 1;
>> +#endif
>> +
>> + rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1;
>> +}
>> +
>> +static struct tst_test test = {
>> + .test = run,
>> + .tcnt = ARRAY_SIZE(tcases),
>> + .setup = setup,
>> + .min_kver = "5.13",
>> + .needs_root = 1,
>> + .needs_kconfigs = (const char *[]) {
>> + "CONFIG_SECURITY_LANDLOCK=y",
>> + NULL
>> + },
>> + .bufs = (struct tst_buffers []) {
>> + {&ruleset_attr, .size = sizeof(struct
>> landlock_ruleset_attr)},
>> + {},
>> + },
>> + .caps = (struct tst_cap []) {
>> + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
>> + {}
>> + },
>> +};
>> diff --git a/testcases/kernel/syscalls/landlock/landlock_common.h
>> b/testcases/kernel/syscalls/landlock/landlock_common.h
>> new file mode 100644
>> index 000000000..66f8fd19a
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/landlock/landlock_common.h
>> @@ -0,0 +1,74 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
>> andrea.cervesato@suse.com>
>> + */
>> +
>> +#ifndef LANDLOCK_COMMON_H
>> +
>> +#include "tst_test.h"
>> +#include "lapi/prctl.h"
>> +#include "lapi/fcntl.h"
>> +#include "lapi/landlock.h"
>> +
>> +static inline void verify_landlock_is_enabled(void)
>> +{
>> + int abi;
>> +
>> + abi = tst_syscall(__NR_landlock_create_ruleset,
>> + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
>> +
>> + if (abi < 0) {
>> + if (errno == EOPNOTSUPP) {
>> + tst_brk(TCONF, "Landlock is currently disabled. "
>> + "Please enable it either via CONFIG_LSM
>> or "
>> + "'lsm' kernel parameter.");
>> + }
>> +
>> + tst_brk(TBROK | TERRNO, "landlock_create_ruleset error");
>> + }
>> +
>> + tst_res(TINFO, "Landlock ABI v%d", abi);
>> +}
>> +
>> +static inline void apply_landlock_rule(
>> + struct landlock_path_beneath_attr *path_beneath_attr,
>> + const int ruleset_fd,
>> + const int access,
>> + const char *path)
>> +{
>> + path_beneath_attr->allowed_access = access;
>> + path_beneath_attr->parent_fd = SAFE_OPEN(path, O_PATH |
>> O_CLOEXEC);
>> +
>> + SAFE_LANDLOCK_ADD_RULE(
>> + ruleset_fd,
>> + LANDLOCK_RULE_PATH_BENEATH,
>> + path_beneath_attr,
>> + 0);
>> +
>> + SAFE_CLOSE(path_beneath_attr->parent_fd);
>> +}
>> +
>> +static inline void enforce_ruleset(const int ruleset_fd)
>> +{
>> + SAFE_PRCTL(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
>> + SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0);
>> +}
>> +
>> +static inline void apply_landlock_layer(
>> + struct landlock_ruleset_attr *ruleset_attr,
>> + 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);
>> +
>> + apply_landlock_rule(path_beneath_attr, ruleset_fd, access, path);
>> + enforce_ruleset(ruleset_fd);
>> +
>> + SAFE_CLOSE(ruleset_fd);
>> +}
>> +
>> +#endif
>>
>> --
>> 2.43.0
>>
>>
>
> --
> Regards,
> Li Wang
>
> Andrea
>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 11/11] Add landlock06 test
2024-07-10 18:02 ` [LTP] [PATCH v2 11/11] Add landlock06 test Andrea Cervesato
@ 2024-07-11 8:45 ` Petr Vorel
0 siblings, 0 replies; 24+ messages in thread
From: Petr Vorel @ 2024-07-11 8:45 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
...
> +static void run(void)
> +{
> + if (!SAFE_FORK()) {
> + int flag;
> + size_t sz = 0;
> +
> + TST_EXP_PASS(ioctl(file_fd, FIONREAD, &sz));
> +
> + /* check unrestrictable commands */
> + TST_EXP_PASS(ioctl(dev_fd, FIOCLEX));
> + TST_EXP_PASS(ioctl(dev_fd, FIONCLEX));
> + TST_EXP_PASS(ioctl(dev_fd, FIONBIO, &flag));
> + TST_EXP_PASS(ioctl(dev_fd, FIOASYNC, &flag));
> +
> + _exit(0);
> + }
nit: I would avoid indentation with return:
if (SAFE_FORK())
return;
int flag;
size_t sz = 0;
TST_EXP_PASS(ioctl(file_fd, FIONREAD, &sz));
/* check unrestrictable commands */
TST_EXP_PASS(ioctl(dev_fd, FIOCLEX));
TST_EXP_PASS(ioctl(dev_fd, FIONCLEX));
TST_EXP_PASS(ioctl(dev_fd, FIONBIO, &flag));
TST_EXP_PASS(ioctl(dev_fd, FIOASYNC, &flag));
_exit(0);
(minor detail, I can change it during merge)
...
> + .format_device = 1,
> + .mount_device = 1,
> + .mntpoint = MNTPOINT,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *[]) {
> + "vfat",
Unfortunately also exfat needs to be skipped (can be done during merge).
> + NULL
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Thanks!
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 09/11] Add landlock04 test
2024-07-10 18:02 ` [LTP] [PATCH v2 09/11] Add landlock04 test Andrea Cervesato
@ 2024-07-11 9:33 ` Li Wang
2024-07-11 10:33 ` Andrea Cervesato via ltp
0 siblings, 1 reply; 24+ messages in thread
From: Li Wang @ 2024-07-11 9:33 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
On Thu, Jul 11, 2024 at 2:05 AM Andrea Cervesato <andrea.cervesato@suse.de>
wrote:
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> This test verifies that all landlock rules are working properly.
> The way we do it is to verify that all disabled syscalls are not
> working but the one we enabled via specifc landlock rules.
>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> runtest/syscalls | 1 +
> testcases/kernel/syscalls/landlock/.gitignore | 2 +
> testcases/kernel/syscalls/landlock/landlock04.c | 176 +++++++++++
> testcases/kernel/syscalls/landlock/landlock_exec.c | 9 +
> .../kernel/syscalls/landlock/landlock_tester.h | 350
> +++++++++++++++++++++
> 5 files changed, 538 insertions(+)
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 269cf24b1..10b54ae84 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -687,6 +687,7 @@ kill13 kill13
> landlock01 landlock01
> landlock02 landlock02
> landlock03 landlock03
> +landlock04 landlock04
>
> lchown01 lchown01
> lchown01_16 lchown01_16
> diff --git a/testcases/kernel/syscalls/landlock/.gitignore
> b/testcases/kernel/syscalls/landlock/.gitignore
> index f79cd090b..4fe8d7cba 100644
> --- a/testcases/kernel/syscalls/landlock/.gitignore
> +++ b/testcases/kernel/syscalls/landlock/.gitignore
> @@ -1,3 +1,5 @@
> +landlock_exec
> landlock01
> landlock02
> landlock03
> +landlock04
> diff --git a/testcases/kernel/syscalls/landlock/landlock04.c
> b/testcases/kernel/syscalls/landlock/landlock04.c
> new file mode 100644
> index 000000000..1567328bb
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock04.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
> andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This test verifies that all landlock rules are working properly. The
> way we
> + * do it is to verify that all disabled syscalls are not working but the
> one we
> + * enabled via specifc landlock rules.
> + */
> +
> +#include "landlock_common.h"
> +#include "landlock_tester.h"
> +
> +#define ACCESS_NAME(x) #x
> +
> +static struct landlock_ruleset_attr *ruleset_attr;
> +static struct landlock_path_beneath_attr *path_beneath_attr;
> +
> +struct rule_access {
> + char *path;
> + int access;
> +};
> +
> +static struct tvariant {
> + int access;
> + char *desc;
> +} tvariants[] = {
> + {
> + LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_EXECUTE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_EXECUTE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_WRITE_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_WRITE_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_READ_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_READ_DIR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_DIR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_REMOVE_DIR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_DIR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_REMOVE_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_CHAR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_CHAR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_BLOCK,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_BLOCK)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_REG,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_REG)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_SOCK,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SOCK)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_FIFO,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_FIFO)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_SYM,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SYM)
> + },
> + {
> + LANDLOCK_ACCESS_FS_WRITE_FILE |
> LANDLOCK_ACCESS_FS_TRUNCATE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_TRUNCATE)
> + },
> +};
> +
> +static void run(void)
> +{
> + if (!SAFE_FORK()) {
> + struct tvariant variant = tvariants[tst_variant];
> +
> + tester_run_all_rules(variant.access);
> + _exit(0);
> + }
> +}
> +
> +static void setup(void)
> +{
> + struct tvariant variant = tvariants[tst_variant];
> + int ruleset_fd;
> +
> + verify_landlock_is_enabled();
> + tester_create_tree();
> +
> + tst_res(TINFO, "Testing %s", variant.desc);
> +
> + ruleset_attr->handled_access_fs = tester_get_all_rules();
> +
> + ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
> + ruleset_attr, sizeof(struct landlock_ruleset_attr), 0);
> +
> + /* since our binary is dynamically linked, we need to enable
> libraries
> + * to be read and executed
> + */
> + struct rule_access rules[] = {
> + {"/lib", LANDLOCK_ACCESS_FS_READ_FILE |
> LANDLOCK_ACCESS_FS_EXECUTE},
> + {"/lib64", LANDLOCK_ACCESS_FS_READ_FILE |
> LANDLOCK_ACCESS_FS_EXECUTE},
> + {SANDBOX_FOLDER, variant.access}
> + };
>
Good method, but can we find a way to get the lib-shared path automatically
but not hard coding?
Some platforms may have another configuration on the shared-lib path.
> + int num_of_rules = ARRAY_SIZE(rules);
> +
> + for (int i = 0; i < num_of_rules; i++) {
> + if (access(rules[i].path, F_OK) == -1)
> + continue;
> +
> + path_beneath_attr->allowed_access = rules[i].access;
> + path_beneath_attr->parent_fd = SAFE_OPEN(rules[i].path,
> O_PATH | O_CLOEXEC);
> +
> + SAFE_LANDLOCK_ADD_RULE(
> + ruleset_fd,
> + LANDLOCK_RULE_PATH_BENEATH,
> + path_beneath_attr,
> + 0);
> +
> + SAFE_CLOSE(path_beneath_attr->parent_fd);
> + }
> +
> + enforce_ruleset(ruleset_fd);
> + SAFE_CLOSE(ruleset_fd);
> +}
> +
> +static struct tst_test test = {
> + .test_all = run,
> + .setup = setup,
> + .min_kver = "5.13",
> + .forks_child = 1,
> + .needs_tmpdir = 1,
> + .needs_root = 1,
> + .test_variants = ARRAY_SIZE(tvariants),
> + .resource_files = (const char *[]) {
> + TESTAPP,
> + NULL,
> + },
> + .needs_kconfigs = (const char *[]) {
> + "CONFIG_SECURITY_LANDLOCK=y",
> + NULL
> + },
> + .bufs = (struct tst_buffers []) {
> + {&ruleset_attr, .size = sizeof(struct
> landlock_ruleset_attr)},
> + {&path_beneath_attr, .size = sizeof(struct
> landlock_path_beneath_attr)},
> + {},
> + },
> + .caps = (struct tst_cap []) {
> + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
> + TST_CAP(TST_CAP_REQ, CAP_MKNOD),
> + {}
> + },
> + .format_device = 1,
> + .mount_device = 1,
> + .mntpoint = SANDBOX_FOLDER,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *[]) {
> + "vfat",
> + "exfat",
> + NULL
> + },
> + .max_runtime = 3600,
> +};
> diff --git a/testcases/kernel/syscalls/landlock/landlock_exec.c
> b/testcases/kernel/syscalls/landlock/landlock_exec.c
> new file mode 100644
> index 000000000..aae5c76b2
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_exec.c
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
> andrea.cervesato@suse.com>
> + */
> +
> +int main(void)
> +{
> + return 0;
> +}
> diff --git a/testcases/kernel/syscalls/landlock/landlock_tester.h
> b/testcases/kernel/syscalls/landlock/landlock_tester.h
> new file mode 100644
> index 000000000..89ca085d7
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_tester.h
> @@ -0,0 +1,350 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <
> andrea.cervesato@suse.com>
> + */
> +
> +#ifndef LANDLOCK_TESTER_H
> +
> +#include "tst_test.h"
> +#include "lapi/landlock.h"
> +#include <sys/sysmacros.h>
> +
> +#define PERM_MODE 0700
> +
> +#define SANDBOX_FOLDER "sandbox"
> +#define TESTAPP "landlock_exec"
> +
> +#define FILE_EXEC SANDBOX_FOLDER"/"TESTAPP
> +#define FILE_READ SANDBOX_FOLDER"/file_read"
> +#define FILE_WRITE SANDBOX_FOLDER"/file_write"
> +#define FILE_REMOVE SANDBOX_FOLDER"/file_remove"
> +#define FILE_UNLINK SANDBOX_FOLDER"/file_unlink"
> +#define FILE_UNLINKAT SANDBOX_FOLDER"/file_unlinkat"
> +#define FILE_TRUNCATE SANDBOX_FOLDER"/file_truncate"
> +#define FILE_REGULAR SANDBOX_FOLDER"/regular0"
> +#define FILE_SOCKET SANDBOX_FOLDER"/socket0"
> +#define FILE_FIFO SANDBOX_FOLDER"/fifo0"
> +#define FILE_SYM0 SANDBOX_FOLDER"/symbolic0"
> +#define FILE_SYM1 SANDBOX_FOLDER"/symbolic1"
> +#define DIR_READDIR SANDBOX_FOLDER"/dir_readdir"
> +#define DIR_RMDIR SANDBOX_FOLDER"/dir_rmdir"
> +#define DEV_CHAR0 SANDBOX_FOLDER"/chardev0"
> +#define DEV_BLK0 SANDBOX_FOLDER"/blkdev0"
> +
> +#define ALL_RULES (\
> + LANDLOCK_ACCESS_FS_EXECUTE | \
> + LANDLOCK_ACCESS_FS_WRITE_FILE | \
> + LANDLOCK_ACCESS_FS_READ_FILE | \
> + LANDLOCK_ACCESS_FS_READ_DIR | \
> + LANDLOCK_ACCESS_FS_REMOVE_DIR | \
> + LANDLOCK_ACCESS_FS_REMOVE_FILE | \
> + LANDLOCK_ACCESS_FS_MAKE_CHAR | \
> + LANDLOCK_ACCESS_FS_MAKE_DIR | \
> + LANDLOCK_ACCESS_FS_MAKE_REG | \
> + LANDLOCK_ACCESS_FS_MAKE_SOCK | \
> + LANDLOCK_ACCESS_FS_MAKE_FIFO | \
> + LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
> + LANDLOCK_ACCESS_FS_MAKE_SYM | \
> + LANDLOCK_ACCESS_FS_REFER | \
> + LANDLOCK_ACCESS_FS_TRUNCATE | \
> + LANDLOCK_ACCESS_NET_BIND_TCP | \
> + LANDLOCK_ACCESS_NET_CONNECT_TCP | \
> + LANDLOCK_ACCESS_FS_IOCTL_DEV)
> +
> +static char *readdir_files[] = {
> + DIR_READDIR"/file0",
> + DIR_READDIR"/file1",
> + DIR_READDIR"/file2",
> +};
> +
> +static int dev_chr;
> +static int dev_blk;
> +
> +static int tester_get_all_rules(void)
> +{
> + int abi;
> + int all_rules = ALL_RULES;
> +
> + abi = SAFE_LANDLOCK_CREATE_RULESET(
> + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
> +
> + if (abi < 2)
> + all_rules &= ~LANDLOCK_ACCESS_FS_REFER;
> +
> + if (abi < 3)
> + all_rules &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
> +
> + if (abi < 4) {
> + all_rules &= ~(LANDLOCK_ACCESS_NET_BIND_TCP |
> + LANDLOCK_ACCESS_NET_CONNECT_TCP);
> + }
> +
> + if (abi < 5)
> + all_rules &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
> +
> + return all_rules;
> +}
> +
> +static void tester_create_tree(void)
> +{
> + if (access(SANDBOX_FOLDER, F_OK) == -1)
> + SAFE_MKDIR(SANDBOX_FOLDER, PERM_MODE);
> +
> + /* folders */
> + SAFE_MKDIR(DIR_RMDIR, PERM_MODE);
> + SAFE_MKDIR(DIR_READDIR, PERM_MODE);
> + for (size_t i = 0; i < ARRAY_SIZE(readdir_files); i++)
> + SAFE_TOUCH(readdir_files[i], PERM_MODE, NULL);
> +
> + /* files */
> + tst_fill_file(FILE_READ, 'a', getpagesize(), 1);
> + SAFE_TOUCH(FILE_WRITE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_REMOVE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_UNLINK, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_UNLINKAT, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_TRUNCATE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_SYM0, PERM_MODE, NULL);
> + SAFE_CP(TESTAPP, FILE_EXEC);
> +
> + /* devices */
> + dev_chr = makedev(1, 3);
> + dev_blk = makedev(7, 0);
> +}
> +
> +static void _test_exec(const int result)
> +{
> + int status;
> + pid_t pid;
> + char *const args[] = {(char *)FILE_EXEC, NULL};
> +
> + tst_res(TINFO, "Test binary execution");
> +
> + pid = SAFE_FORK();
> + if (!pid) {
> + int rval;
> +
> + if (result == TPASS) {
> + rval = execve(FILE_EXEC, args, NULL);
> + if (rval == -1)
> + tst_res(TFAIL | TERRNO, "Failed to execute
> test binary");
> + } else {
> + TST_EXP_FAIL(execve(FILE_EXEC, args, NULL),
> EACCES);
> + }
> +
> + _exit(1);
> + }
> +
> + SAFE_WAITPID(pid, &status, 0);
> + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
> + return;
> +
> + tst_res(result, "Test binary has been executed");
> +}
> +
> +static void _test_write(const int result)
> +{
> + tst_res(TINFO, "Test writing file");
> +
> + if (result == TPASS)
> + TST_EXP_FD(open(FILE_WRITE, O_WRONLY, PERM_MODE));
> + else
> + TST_EXP_FAIL(open(FILE_WRITE, O_WRONLY, PERM_MODE),
> EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +static void _test_read(const int result)
> +{
> + tst_res(TINFO, "Test reading file");
> +
> + if (result == TPASS)
> + TST_EXP_FD(open(FILE_READ, O_RDONLY, PERM_MODE));
> + else
> + TST_EXP_FAIL(open(FILE_READ, O_RDONLY, PERM_MODE), EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +static void _test_readdir(const int result)
> +{
> + tst_res(TINFO, "Test reading directory");
> +
> + DIR *dir;
> + struct dirent *de;
> + int files_counted = 0;
> +
> + dir = opendir(DIR_READDIR);
> + if (!dir) {
> + tst_res(result == TPASS ? TFAIL : TPASS,
> + "Can't read '%s' directory", DIR_READDIR);
> +
> + return;
> + }
> +
> + tst_res(result, "Can read '%s' directory", DIR_READDIR);
> + if (result == TFAIL)
> + return;
> +
> + while ((de = readdir(dir)) != NULL) {
> + if (de->d_type != DT_REG)
> + continue;
> +
> + for (size_t i = 0; i < ARRAY_SIZE(readdir_files); i++) {
> + if (readdir_files[i] == NULL)
> + continue;
> +
> + if (strstr(readdir_files[i], de->d_name) != NULL)
> + files_counted++;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + TST_EXP_EQ_LI(files_counted, ARRAY_SIZE(readdir_files));
> +}
> +
> +static void _test_rmdir(const int result)
> +{
> + tst_res(TINFO, "Test removing directory");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(rmdir(DIR_RMDIR));
> + else
> + TST_EXP_FAIL(rmdir(DIR_RMDIR), EACCES);
> +}
> +
> +static void _test_rmfile(const int result)
> +{
> + tst_res(TINFO, "Test removing file");
> +
> + if (result == TPASS) {
> + TST_EXP_PASS(unlink(FILE_UNLINK));
> + TST_EXP_PASS(remove(FILE_REMOVE));
> + } else {
> + TST_EXP_FAIL(unlink(FILE_UNLINK), EACCES);
> + TST_EXP_FAIL(remove(FILE_REMOVE), EACCES);
> + }
> +}
> +
> +static void _test_make(
> + const char *path,
> + const int type,
> + const int dev,
> + const int result)
> +{
> + tst_res(TINFO, "Test normal or special files creation");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(mknod(path, type | 0400, dev));
> + else
> + TST_EXP_FAIL(mknod(path, type | 0400, dev), EACCES);
> +}
> +
> +static void _test_symbolic(const int result)
> +{
> + tst_res(TINFO, "Test symbolic links");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(symlink(FILE_SYM0, FILE_SYM1));
> + else
> + TST_EXP_FAIL(symlink(FILE_SYM0, FILE_SYM1), EACCES);
> +}
> +
> +static void _test_truncate(const int result)
> +{
> + int fd;
> +
> + tst_res(TINFO, "Test truncating file");
> +
> + if (result == TPASS) {
> + TST_EXP_PASS(truncate(FILE_TRUNCATE, 10));
> +
> + fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY, PERM_MODE));
> + if (fd != -1) {
> + TST_EXP_PASS(ftruncate(fd, 10));
> + SAFE_CLOSE(fd);
> + }
> +
> + fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY | O_TRUNC,
> PERM_MODE));
> + if (fd != -1)
> + SAFE_CLOSE(fd);
> + } else {
> + TST_EXP_FAIL(truncate(FILE_TRUNCATE, 10), EACCES);
> +
> + fd = open(FILE_TRUNCATE, O_WRONLY, PERM_MODE);
> + if (fd != -1) {
> + TST_EXP_FAIL(ftruncate(fd, 10), EACCES);
> + SAFE_CLOSE(fd);
> + }
> +
> + TST_EXP_FAIL(open(FILE_TRUNCATE, O_WRONLY | O_TRUNC,
> PERM_MODE),
> + EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> + }
> +}
> +
> +static void tester_run_rules(const int rules, const int result)
> +{
> + if (rules & LANDLOCK_ACCESS_FS_EXECUTE)
> + _test_exec(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_WRITE_FILE)
> + _test_write(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_READ_FILE)
> + _test_read(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_READ_DIR)
> + _test_readdir(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_REMOVE_DIR)
> + _test_rmdir(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_REMOVE_FILE)
> + _test_rmfile(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_CHAR)
> + _test_make(DEV_CHAR0, S_IFCHR, dev_chr, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_BLOCK)
> + _test_make(DEV_BLK0, S_IFBLK, dev_blk, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_REG)
> + _test_make(FILE_REGULAR, S_IFREG, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_SOCK)
> + _test_make(FILE_SOCKET, S_IFSOCK, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_FIFO)
> + _test_make(FILE_FIFO, S_IFIFO, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_SYM)
> + _test_symbolic(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_TRUNCATE) {
> + if ((tst_kvercmp(6, 2, 0)) < 0) {
> + tst_res(TINFO, "Skip truncate test. Minimum kernel
> version is 6.2");
> + return;
> + }
> +
> + _test_truncate(result);
> + }
> +}
> +
> +static inline void tester_run_all_rules(const int pass_rules)
> +{
> + int fail_rules;
> + int all_rules;
> +
> + all_rules = tester_get_all_rules();
> + fail_rules = all_rules & ~pass_rules;
> +
> + tester_run_rules(pass_rules, TPASS);
> + tester_run_rules(fail_rules, TFAIL);
> +}
> +
> +#endif
>
> --
> 2.43.0
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 09/11] Add landlock04 test
2024-07-11 9:33 ` Li Wang
@ 2024-07-11 10:33 ` Andrea Cervesato via ltp
2024-07-11 11:01 ` Cyril Hrubis
0 siblings, 1 reply; 24+ messages in thread
From: Andrea Cervesato via ltp @ 2024-07-11 10:33 UTC (permalink / raw)
To: Li Wang, Andrea Cervesato; +Cc: ltp
On 7/11/24 11:33, Li Wang wrote:
>
>
> On Thu, Jul 11, 2024 at 2:05 AM Andrea Cervesato
> <andrea.cervesato@suse.de> wrote:
>
> From: Andrea Cervesato <andrea.cervesato@suse.com>
>
> This test verifies that all landlock rules are working properly.
> The way we do it is to verify that all disabled syscalls are not
> working but the one we enabled via specifc landlock rules.
>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> runtest/syscalls | 1 +
> testcases/kernel/syscalls/landlock/.gitignore | 2 +
> testcases/kernel/syscalls/landlock/landlock04.c | 176 +++++++++++
> testcases/kernel/syscalls/landlock/landlock_exec.c | 9 +
> .../kernel/syscalls/landlock/landlock_tester.h | 350
> +++++++++++++++++++++
> 5 files changed, 538 insertions(+)
>
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 269cf24b1..10b54ae84 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -687,6 +687,7 @@ kill13 kill13
> landlock01 landlock01
> landlock02 landlock02
> landlock03 landlock03
> +landlock04 landlock04
>
> lchown01 lchown01
> lchown01_16 lchown01_16
> diff --git a/testcases/kernel/syscalls/landlock/.gitignore
> b/testcases/kernel/syscalls/landlock/.gitignore
> index f79cd090b..4fe8d7cba 100644
> --- a/testcases/kernel/syscalls/landlock/.gitignore
> +++ b/testcases/kernel/syscalls/landlock/.gitignore
> @@ -1,3 +1,5 @@
> +landlock_exec
> landlock01
> landlock02
> landlock03
> +landlock04
> diff --git a/testcases/kernel/syscalls/landlock/landlock04.c
> b/testcases/kernel/syscalls/landlock/landlock04.c
> new file mode 100644
> index 000000000..1567328bb
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock04.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato
> <andrea.cervesato@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This test verifies that all landlock rules are working
> properly. The way we
> + * do it is to verify that all disabled syscalls are not working
> but the one we
> + * enabled via specifc landlock rules.
> + */
> +
> +#include "landlock_common.h"
> +#include "landlock_tester.h"
> +
> +#define ACCESS_NAME(x) #x
> +
> +static struct landlock_ruleset_attr *ruleset_attr;
> +static struct landlock_path_beneath_attr *path_beneath_attr;
> +
> +struct rule_access {
> + char *path;
> + int access;
> +};
> +
> +static struct tvariant {
> + int access;
> + char *desc;
> +} tvariants[] = {
> + {
> + LANDLOCK_ACCESS_FS_READ_FILE |
> LANDLOCK_ACCESS_FS_EXECUTE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_EXECUTE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_WRITE_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_WRITE_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_READ_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_READ_DIR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_READ_DIR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_REMOVE_DIR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_DIR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_REMOVE_FILE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_REMOVE_FILE)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_CHAR,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_CHAR)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_BLOCK,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_BLOCK)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_REG,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_REG)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_SOCK,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SOCK)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_FIFO,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_FIFO)
> + },
> + {
> + LANDLOCK_ACCESS_FS_MAKE_SYM,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_MAKE_SYM)
> + },
> + {
> + LANDLOCK_ACCESS_FS_WRITE_FILE |
> LANDLOCK_ACCESS_FS_TRUNCATE,
> + ACCESS_NAME(LANDLOCK_ACCESS_FS_TRUNCATE)
> + },
> +};
> +
> +static void run(void)
> +{
> + if (!SAFE_FORK()) {
> + struct tvariant variant = tvariants[tst_variant];
> +
> + tester_run_all_rules(variant.access);
> + _exit(0);
> + }
> +}
> +
> +static void setup(void)
> +{
> + struct tvariant variant = tvariants[tst_variant];
> + int ruleset_fd;
> +
> + verify_landlock_is_enabled();
> + tester_create_tree();
> +
> + tst_res(TINFO, "Testing %s", variant.desc);
> +
> + ruleset_attr->handled_access_fs = tester_get_all_rules();
> +
> + ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET(
> + ruleset_attr, sizeof(struct
> landlock_ruleset_attr), 0);
> +
> + /* since our binary is dynamically linked, we need to
> enable libraries
> + * to be read and executed
> + */
> + struct rule_access rules[] = {
> + {"/lib", LANDLOCK_ACCESS_FS_READ_FILE |
> LANDLOCK_ACCESS_FS_EXECUTE},
> + {"/lib64", LANDLOCK_ACCESS_FS_READ_FILE |
> LANDLOCK_ACCESS_FS_EXECUTE},
> + {SANDBOX_FOLDER, variant.access}
> + };
>
>
> Good method, but can we find a way to get the lib-shared path
> automatically but not hard coding?
>
> Some platforms may have another configuration on the shared-lib path.
>
The only library we need is libc.so, which is usually installed in /lib
or /lib64. I don't really know if LTP supported distros which place libc
somewhere else.
Do you have suggestions on how to get shared-libs eventually? Because
the only way I know is to call dladdr() but it doesn't seem the way to
go (I obtain the current binary file)
>
> + int num_of_rules = ARRAY_SIZE(rules);
> +
> + for (int i = 0; i < num_of_rules; i++) {
> + if (access(rules[i].path, F_OK) == -1)
> + continue;
> +
> + path_beneath_attr->allowed_access = rules[i].access;
> + path_beneath_attr->parent_fd =
> SAFE_OPEN(rules[i].path, O_PATH | O_CLOEXEC);
> +
> + SAFE_LANDLOCK_ADD_RULE(
> + ruleset_fd,
> + LANDLOCK_RULE_PATH_BENEATH,
> + path_beneath_attr,
> + 0);
> +
> + SAFE_CLOSE(path_beneath_attr->parent_fd);
> + }
> +
> + enforce_ruleset(ruleset_fd);
> + SAFE_CLOSE(ruleset_fd);
> +}
> +
> +static struct tst_test test = {
> + .test_all = run,
> + .setup = setup,
> + .min_kver = "5.13",
> + .forks_child = 1,
> + .needs_tmpdir = 1,
> + .needs_root = 1,
> + .test_variants = ARRAY_SIZE(tvariants),
> + .resource_files = (const char *[]) {
> + TESTAPP,
> + NULL,
> + },
> + .needs_kconfigs = (const char *[]) {
> + "CONFIG_SECURITY_LANDLOCK=y",
> + NULL
> + },
> + .bufs = (struct tst_buffers []) {
> + {&ruleset_attr, .size = sizeof(struct
> landlock_ruleset_attr)},
> + {&path_beneath_attr, .size = sizeof(struct
> landlock_path_beneath_attr)},
> + {},
> + },
> + .caps = (struct tst_cap []) {
> + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN),
> + TST_CAP(TST_CAP_REQ, CAP_MKNOD),
> + {}
> + },
> + .format_device = 1,
> + .mount_device = 1,
> + .mntpoint = SANDBOX_FOLDER,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *[]) {
> + "vfat",
> + "exfat",
> + NULL
> + },
> + .max_runtime = 3600,
> +};
> diff --git a/testcases/kernel/syscalls/landlock/landlock_exec.c
> b/testcases/kernel/syscalls/landlock/landlock_exec.c
> new file mode 100644
> index 000000000..aae5c76b2
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_exec.c
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato
> <andrea.cervesato@suse.com>
> + */
> +
> +int main(void)
> +{
> + return 0;
> +}
> diff --git a/testcases/kernel/syscalls/landlock/landlock_tester.h
> b/testcases/kernel/syscalls/landlock/landlock_tester.h
> new file mode 100644
> index 000000000..89ca085d7
> --- /dev/null
> +++ b/testcases/kernel/syscalls/landlock/landlock_tester.h
> @@ -0,0 +1,350 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Copyright (C) 2024 SUSE LLC Andrea Cervesato
> <andrea.cervesato@suse.com>
> + */
> +
> +#ifndef LANDLOCK_TESTER_H
> +
> +#include "tst_test.h"
> +#include "lapi/landlock.h"
> +#include <sys/sysmacros.h>
> +
> +#define PERM_MODE 0700
> +
> +#define SANDBOX_FOLDER "sandbox"
> +#define TESTAPP "landlock_exec"
> +
> +#define FILE_EXEC SANDBOX_FOLDER"/"TESTAPP
> +#define FILE_READ SANDBOX_FOLDER"/file_read"
> +#define FILE_WRITE SANDBOX_FOLDER"/file_write"
> +#define FILE_REMOVE SANDBOX_FOLDER"/file_remove"
> +#define FILE_UNLINK SANDBOX_FOLDER"/file_unlink"
> +#define FILE_UNLINKAT SANDBOX_FOLDER"/file_unlinkat"
> +#define FILE_TRUNCATE SANDBOX_FOLDER"/file_truncate"
> +#define FILE_REGULAR SANDBOX_FOLDER"/regular0"
> +#define FILE_SOCKET SANDBOX_FOLDER"/socket0"
> +#define FILE_FIFO SANDBOX_FOLDER"/fifo0"
> +#define FILE_SYM0 SANDBOX_FOLDER"/symbolic0"
> +#define FILE_SYM1 SANDBOX_FOLDER"/symbolic1"
> +#define DIR_READDIR SANDBOX_FOLDER"/dir_readdir"
> +#define DIR_RMDIR SANDBOX_FOLDER"/dir_rmdir"
> +#define DEV_CHAR0 SANDBOX_FOLDER"/chardev0"
> +#define DEV_BLK0 SANDBOX_FOLDER"/blkdev0"
> +
> +#define ALL_RULES (\
> + LANDLOCK_ACCESS_FS_EXECUTE | \
> + LANDLOCK_ACCESS_FS_WRITE_FILE | \
> + LANDLOCK_ACCESS_FS_READ_FILE | \
> + LANDLOCK_ACCESS_FS_READ_DIR | \
> + LANDLOCK_ACCESS_FS_REMOVE_DIR | \
> + LANDLOCK_ACCESS_FS_REMOVE_FILE | \
> + LANDLOCK_ACCESS_FS_MAKE_CHAR | \
> + LANDLOCK_ACCESS_FS_MAKE_DIR | \
> + LANDLOCK_ACCESS_FS_MAKE_REG | \
> + LANDLOCK_ACCESS_FS_MAKE_SOCK | \
> + LANDLOCK_ACCESS_FS_MAKE_FIFO | \
> + LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
> + LANDLOCK_ACCESS_FS_MAKE_SYM | \
> + LANDLOCK_ACCESS_FS_REFER | \
> + LANDLOCK_ACCESS_FS_TRUNCATE | \
> + LANDLOCK_ACCESS_NET_BIND_TCP | \
> + LANDLOCK_ACCESS_NET_CONNECT_TCP | \
> + LANDLOCK_ACCESS_FS_IOCTL_DEV)
> +
> +static char *readdir_files[] = {
> + DIR_READDIR"/file0",
> + DIR_READDIR"/file1",
> + DIR_READDIR"/file2",
> +};
> +
> +static int dev_chr;
> +static int dev_blk;
> +
> +static int tester_get_all_rules(void)
> +{
> + int abi;
> + int all_rules = ALL_RULES;
> +
> + abi = SAFE_LANDLOCK_CREATE_RULESET(
> + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
> +
> + if (abi < 2)
> + all_rules &= ~LANDLOCK_ACCESS_FS_REFER;
> +
> + if (abi < 3)
> + all_rules &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
> +
> + if (abi < 4) {
> + all_rules &= ~(LANDLOCK_ACCESS_NET_BIND_TCP |
> + LANDLOCK_ACCESS_NET_CONNECT_TCP);
> + }
> +
> + if (abi < 5)
> + all_rules &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
> +
> + return all_rules;
> +}
> +
> +static void tester_create_tree(void)
> +{
> + if (access(SANDBOX_FOLDER, F_OK) == -1)
> + SAFE_MKDIR(SANDBOX_FOLDER, PERM_MODE);
> +
> + /* folders */
> + SAFE_MKDIR(DIR_RMDIR, PERM_MODE);
> + SAFE_MKDIR(DIR_READDIR, PERM_MODE);
> + for (size_t i = 0; i < ARRAY_SIZE(readdir_files); i++)
> + SAFE_TOUCH(readdir_files[i], PERM_MODE, NULL);
> +
> + /* files */
> + tst_fill_file(FILE_READ, 'a', getpagesize(), 1);
> + SAFE_TOUCH(FILE_WRITE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_REMOVE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_UNLINK, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_UNLINKAT, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_TRUNCATE, PERM_MODE, NULL);
> + SAFE_TOUCH(FILE_SYM0, PERM_MODE, NULL);
> + SAFE_CP(TESTAPP, FILE_EXEC);
> +
> + /* devices */
> + dev_chr = makedev(1, 3);
> + dev_blk = makedev(7, 0);
> +}
> +
> +static void _test_exec(const int result)
> +{
> + int status;
> + pid_t pid;
> + char *const args[] = {(char *)FILE_EXEC, NULL};
> +
> + tst_res(TINFO, "Test binary execution");
> +
> + pid = SAFE_FORK();
> + if (!pid) {
> + int rval;
> +
> + if (result == TPASS) {
> + rval = execve(FILE_EXEC, args, NULL);
> + if (rval == -1)
> + tst_res(TFAIL | TERRNO, "Failed to
> execute test binary");
> + } else {
> + TST_EXP_FAIL(execve(FILE_EXEC, args,
> NULL), EACCES);
> + }
> +
> + _exit(1);
> + }
> +
> + SAFE_WAITPID(pid, &status, 0);
> + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
> + return;
> +
> + tst_res(result, "Test binary has been executed");
> +}
> +
> +static void _test_write(const int result)
> +{
> + tst_res(TINFO, "Test writing file");
> +
> + if (result == TPASS)
> + TST_EXP_FD(open(FILE_WRITE, O_WRONLY, PERM_MODE));
> + else
> + TST_EXP_FAIL(open(FILE_WRITE, O_WRONLY,
> PERM_MODE), EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +static void _test_read(const int result)
> +{
> + tst_res(TINFO, "Test reading file");
> +
> + if (result == TPASS)
> + TST_EXP_FD(open(FILE_READ, O_RDONLY, PERM_MODE));
> + else
> + TST_EXP_FAIL(open(FILE_READ, O_RDONLY, PERM_MODE),
> EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> +}
> +
> +static void _test_readdir(const int result)
> +{
> + tst_res(TINFO, "Test reading directory");
> +
> + DIR *dir;
> + struct dirent *de;
> + int files_counted = 0;
> +
> + dir = opendir(DIR_READDIR);
> + if (!dir) {
> + tst_res(result == TPASS ? TFAIL : TPASS,
> + "Can't read '%s' directory", DIR_READDIR);
> +
> + return;
> + }
> +
> + tst_res(result, "Can read '%s' directory", DIR_READDIR);
> + if (result == TFAIL)
> + return;
> +
> + while ((de = readdir(dir)) != NULL) {
> + if (de->d_type != DT_REG)
> + continue;
> +
> + for (size_t i = 0; i < ARRAY_SIZE(readdir_files);
> i++) {
> + if (readdir_files[i] == NULL)
> + continue;
> +
> + if (strstr(readdir_files[i], de->d_name)
> != NULL)
> + files_counted++;
> + }
> + }
> +
> + SAFE_CLOSEDIR(dir);
> +
> + TST_EXP_EQ_LI(files_counted, ARRAY_SIZE(readdir_files));
> +}
> +
> +static void _test_rmdir(const int result)
> +{
> + tst_res(TINFO, "Test removing directory");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(rmdir(DIR_RMDIR));
> + else
> + TST_EXP_FAIL(rmdir(DIR_RMDIR), EACCES);
> +}
> +
> +static void _test_rmfile(const int result)
> +{
> + tst_res(TINFO, "Test removing file");
> +
> + if (result == TPASS) {
> + TST_EXP_PASS(unlink(FILE_UNLINK));
> + TST_EXP_PASS(remove(FILE_REMOVE));
> + } else {
> + TST_EXP_FAIL(unlink(FILE_UNLINK), EACCES);
> + TST_EXP_FAIL(remove(FILE_REMOVE), EACCES);
> + }
> +}
> +
> +static void _test_make(
> + const char *path,
> + const int type,
> + const int dev,
> + const int result)
> +{
> + tst_res(TINFO, "Test normal or special files creation");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(mknod(path, type | 0400, dev));
> + else
> + TST_EXP_FAIL(mknod(path, type | 0400, dev), EACCES);
> +}
> +
> +static void _test_symbolic(const int result)
> +{
> + tst_res(TINFO, "Test symbolic links");
> +
> + if (result == TPASS)
> + TST_EXP_PASS(symlink(FILE_SYM0, FILE_SYM1));
> + else
> + TST_EXP_FAIL(symlink(FILE_SYM0, FILE_SYM1), EACCES);
> +}
> +
> +static void _test_truncate(const int result)
> +{
> + int fd;
> +
> + tst_res(TINFO, "Test truncating file");
> +
> + if (result == TPASS) {
> + TST_EXP_PASS(truncate(FILE_TRUNCATE, 10));
> +
> + fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY,
> PERM_MODE));
> + if (fd != -1) {
> + TST_EXP_PASS(ftruncate(fd, 10));
> + SAFE_CLOSE(fd);
> + }
> +
> + fd = TST_EXP_FD(open(FILE_TRUNCATE, O_WRONLY |
> O_TRUNC, PERM_MODE));
> + if (fd != -1)
> + SAFE_CLOSE(fd);
> + } else {
> + TST_EXP_FAIL(truncate(FILE_TRUNCATE, 10), EACCES);
> +
> + fd = open(FILE_TRUNCATE, O_WRONLY, PERM_MODE);
> + if (fd != -1) {
> + TST_EXP_FAIL(ftruncate(fd, 10), EACCES);
> + SAFE_CLOSE(fd);
> + }
> +
> + TST_EXP_FAIL(open(FILE_TRUNCATE, O_WRONLY |
> O_TRUNC, PERM_MODE),
> + EACCES);
> +
> + if (TST_RET != -1)
> + SAFE_CLOSE(TST_RET);
> + }
> +}
> +
> +static void tester_run_rules(const int rules, const int result)
> +{
> + if (rules & LANDLOCK_ACCESS_FS_EXECUTE)
> + _test_exec(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_WRITE_FILE)
> + _test_write(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_READ_FILE)
> + _test_read(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_READ_DIR)
> + _test_readdir(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_REMOVE_DIR)
> + _test_rmdir(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_REMOVE_FILE)
> + _test_rmfile(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_CHAR)
> + _test_make(DEV_CHAR0, S_IFCHR, dev_chr, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_BLOCK)
> + _test_make(DEV_BLK0, S_IFBLK, dev_blk, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_REG)
> + _test_make(FILE_REGULAR, S_IFREG, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_SOCK)
> + _test_make(FILE_SOCKET, S_IFSOCK, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_FIFO)
> + _test_make(FILE_FIFO, S_IFIFO, 0, result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_MAKE_SYM)
> + _test_symbolic(result);
> +
> + if (rules & LANDLOCK_ACCESS_FS_TRUNCATE) {
> + if ((tst_kvercmp(6, 2, 0)) < 0) {
> + tst_res(TINFO, "Skip truncate test.
> Minimum kernel version is 6.2");
> + return;
> + }
> +
> + _test_truncate(result);
> + }
> +}
> +
> +static inline void tester_run_all_rules(const int pass_rules)
> +{
> + int fail_rules;
> + int all_rules;
> +
> + all_rules = tester_get_all_rules();
> + fail_rules = all_rules & ~pass_rules;
> +
> + tester_run_rules(pass_rules, TPASS);
> + tester_run_rules(fail_rules, TFAIL);
> +}
> +
> +#endif
>
> --
> 2.43.0
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>
>
> --
> Regards,
> Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 09/11] Add landlock04 test
2024-07-11 10:33 ` Andrea Cervesato via ltp
@ 2024-07-11 11:01 ` Cyril Hrubis
2024-07-11 11:14 ` Li Wang
0 siblings, 1 reply; 24+ messages in thread
From: Cyril Hrubis @ 2024-07-11 11:01 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi!
> The only library we need is libc.so, which is usually installed in /lib
> or /lib64. I don't really know if LTP supported distros which place libc
> somewhere else.
> Do you have suggestions on how to get shared-libs eventually? Because
> the only way I know is to call dladdr() but it doesn't seem the way to
> go (I obtain the current binary file)
I guess that you can parse /proc/self/maps to get paths to currenlty
loaded so files.
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [LTP] [PATCH v2 09/11] Add landlock04 test
2024-07-11 11:01 ` Cyril Hrubis
@ 2024-07-11 11:14 ` Li Wang
0 siblings, 0 replies; 24+ messages in thread
From: Li Wang @ 2024-07-11 11:14 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
On Thu, Jul 11, 2024 at 7:02 PM Cyril Hrubis <chrubis@suse.cz> wrote:
> Hi!
> > The only library we need is libc.so, which is usually installed in /lib
> > or /lib64. I don't really know if LTP supported distros which place libc
> > somewhere else.
> > Do you have suggestions on how to get shared-libs eventually? Because
> > the only way I know is to call dladdr() but it doesn't seem the way to
> > go (I obtain the current binary file)
>
> I guess that you can parse /proc/self/maps to get paths to currenlty
> loaded so files.
>
Yes, that will precisely show the current process load so files.
Also, we could find that via 'ldconfig -p' but that does not seem
more easier than parsing the maps.
--
Regards,
Li Wang
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2024-07-11 11:14 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-10 18:01 [LTP] [PATCH v2 00/11] landlock testing suite Andrea Cervesato
2024-07-10 18:01 ` [LTP] [PATCH v2 01/11] Add landlock syscalls definitions Andrea Cervesato
2024-07-11 1:16 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 02/11] Add lapi/landlock.h fallback Andrea Cervesato
2024-07-11 1:30 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 03/11] Added three more SAFE_* macros for landlock sandbox: Andrea Cervesato
2024-07-11 3:47 ` Li Wang
2024-07-10 18:01 ` [LTP] [PATCH v2 04/11] Add SAFE_PRCTL macro Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 05/11] Add landlock01 test Andrea Cervesato
2024-07-11 3:16 ` Li Wang
2024-07-11 7:06 ` Andrea Cervesato via ltp
2024-07-11 7:30 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 06/11] Add landlock02 test Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 07/11] Add landlock03 test Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 08/11] Add CAP_MKNOD fallback in lapi/capability.h Andrea Cervesato
2024-07-11 3:49 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 09/11] Add landlock04 test Andrea Cervesato
2024-07-11 9:33 ` Li Wang
2024-07-11 10:33 ` Andrea Cervesato via ltp
2024-07-11 11:01 ` Cyril Hrubis
2024-07-11 11:14 ` Li Wang
2024-07-10 18:02 ` [LTP] [PATCH v2 10/11] Add landlock05 test Andrea Cervesato
2024-07-10 18:02 ` [LTP] [PATCH v2 11/11] Add landlock06 test Andrea Cervesato
2024-07-11 8:45 ` Petr Vorel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox