aboutsummaryrefslogtreecommitdiff
path: root/testcases/kernel/syscalls
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-04 22:00:57 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-04 22:00:57 +0000
commit78c753a2bc1062c1fdb4c7b2e618554896827b45 (patch)
treebed7e68b13373f89a7ffd8feb37b0cc557e9da5b /testcases/kernel/syscalls
parent215bb8bdef76ef57566913dc4e9fc0bc20b0d92d (diff)
parent90164cf586a337bcb89a75f9dd92b9803e278dc1 (diff)
downloadltp-simpleperf-release.tar.gz
Snap for 11526323 from 90164cf586a337bcb89a75f9dd92b9803e278dc1 to simpleperf-releasesimpleperf-release
Change-Id: I288786e8fccc3a1f3a579fa5d8791b22977dd569
Diffstat (limited to 'testcases/kernel/syscalls')
-rw-r--r--testcases/kernel/syscalls/accept/.gitignore1
-rw-r--r--testcases/kernel/syscalls/accept/accept01.c8
-rw-r--r--testcases/kernel/syscalls/accept/accept03.c60
-rw-r--r--testcases/kernel/syscalls/acct/acct01.c11
-rw-r--r--testcases/kernel/syscalls/acct/acct02.c16
-rw-r--r--testcases/kernel/syscalls/acct/acct02_helper.c4
-rw-r--r--testcases/kernel/syscalls/adjtimex/adjtimex03.c2
-rw-r--r--testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h3
-rw-r--r--testcases/kernel/syscalls/dup/dup06.c145
-rw-r--r--testcases/kernel/syscalls/dup/dup07.c173
-rw-r--r--testcases/kernel/syscalls/eventfd2/eventfd2.h5
-rw-r--r--testcases/kernel/syscalls/execve/execve04.c4
-rw-r--r--testcases/kernel/syscalls/execve/execve05.c27
-rw-r--r--testcases/kernel/syscalls/exit_group/Makefile2
-rw-r--r--testcases/kernel/syscalls/exit_group/exit_group01.c161
-rw-r--r--testcases/kernel/syscalls/fallocate/fallocate06.c2
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify.h202
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify01.c16
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify03.c10
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify07.c3
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify09.c8
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify10.c18
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify11.c2
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify12.c5
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify13.c57
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify14.c22
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify15.c10
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify16.c27
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify20.c3
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify21.c3
-rw-r--r--testcases/kernel/syscalls/fanotify/fanotify23.c2
-rw-r--r--testcases/kernel/syscalls/fchmodat/.gitignore1
-rw-r--r--testcases/kernel/syscalls/fchmodat/fchmodat01.c108
-rw-r--r--testcases/kernel/syscalls/fchmodat/fchmodat02.c87
-rw-r--r--testcases/kernel/syscalls/fchownat/fchownat.h37
-rw-r--r--testcases/kernel/syscalls/fchownat/fchownat01.c1
-rw-r--r--testcases/kernel/syscalls/fchownat/fchownat02.c1
-rw-r--r--testcases/kernel/syscalls/fcntl/Makefile2
-rw-r--r--testcases/kernel/syscalls/fork/.gitignore4
-rw-r--r--testcases/kernel/syscalls/fork/fork04.c362
-rw-r--r--testcases/kernel/syscalls/fork/fork06.c106
-rw-r--r--testcases/kernel/syscalls/fork/fork10.c215
-rw-r--r--testcases/kernel/syscalls/fork/fork11.c97
-rw-r--r--testcases/kernel/syscalls/fork/fork12.c137
-rw-r--r--testcases/kernel/syscalls/fork/fork_procs.c55
-rw-r--r--testcases/kernel/syscalls/fsetxattr/fsetxattr01.c2
-rw-r--r--testcases/kernel/syscalls/fsetxattr/fsetxattr02.c34
-rw-r--r--testcases/kernel/syscalls/getcwd/getcwd01.c28
-rw-r--r--testcases/kernel/syscalls/getcwd/getcwd02.c12
-rw-r--r--testcases/kernel/syscalls/getcwd/getcwd03.c16
-rw-r--r--testcases/kernel/syscalls/getdtablesize/.gitignore1
-rw-r--r--testcases/kernel/syscalls/getdtablesize/Makefile8
-rw-r--r--testcases/kernel/syscalls/getdtablesize/getdtablesize01.c119
-rw-r--r--testcases/kernel/syscalls/getegid/getegid01.c95
-rw-r--r--testcases/kernel/syscalls/getegid/getegid02.c93
-rw-r--r--testcases/kernel/syscalls/getgroups/Makefile3
-rw-r--r--testcases/kernel/syscalls/getgroups/getgroups01.c5
-rw-r--r--testcases/kernel/syscalls/getgroups/getgroups03.c5
-rw-r--r--testcases/kernel/syscalls/getpid/getpid01.c16
-rw-r--r--testcases/kernel/syscalls/getppid/getppid01.c13
-rw-r--r--testcases/kernel/syscalls/getresgid/Makefile3
-rw-r--r--testcases/kernel/syscalls/getresgid/getresgid01.c5
-rw-r--r--testcases/kernel/syscalls/getresgid/getresgid02.c5
-rw-r--r--testcases/kernel/syscalls/getresgid/getresgid03.c5
-rw-r--r--testcases/kernel/syscalls/getresuid/Makefile3
-rw-r--r--testcases/kernel/syscalls/getresuid/getresuid01.c5
-rw-r--r--testcases/kernel/syscalls/getresuid/getresuid02.c5
-rw-r--r--testcases/kernel/syscalls/getresuid/getresuid03.c5
-rw-r--r--testcases/kernel/syscalls/getrlimit/getrlimit02.c13
-rw-r--r--testcases/kernel/syscalls/getsockopt/getsockopt02.c8
-rw-r--r--testcases/kernel/syscalls/gettid/.gitignore1
-rw-r--r--testcases/kernel/syscalls/gettid/Makefile4
-rw-r--r--testcases/kernel/syscalls/gettid/gettid01.c104
-rw-r--r--testcases/kernel/syscalls/gettid/gettid02.c66
-rw-r--r--testcases/kernel/syscalls/gettimeofday/gettimeofday01.c119
-rw-r--r--testcases/kernel/syscalls/gettimeofday/gettimeofday02.c12
-rw-r--r--testcases/kernel/syscalls/getxattr/getxattr02.c205
-rw-r--r--testcases/kernel/syscalls/getxattr/getxattr03.c133
-rw-r--r--testcases/kernel/syscalls/ioctl/ioctl02.c556
-rw-r--r--testcases/kernel/syscalls/ioctl/ioctl_loop06.c3
-rwxr-xr-xtestcases/kernel/syscalls/ioctl/test_ioctl2
-rw-r--r--testcases/kernel/syscalls/ipc/msgctl/msgctl06.c6
-rw-r--r--testcases/kernel/syscalls/ipc/shmget/shmget02.c7
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl01.c13
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl02.c40
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl03.c16
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl04.c5
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl05.c20
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl06.c14
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl07.c5
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl08.c10
-rw-r--r--testcases/kernel/syscalls/keyctl/keyctl09.c1
-rw-r--r--testcases/kernel/syscalls/lchown/Makefile3
-rw-r--r--testcases/kernel/syscalls/lchown/lchown01.c5
-rw-r--r--testcases/kernel/syscalls/lchown/lchown02.c5
-rw-r--r--testcases/kernel/syscalls/lchown/lchown03.c5
-rw-r--r--testcases/kernel/syscalls/link/.gitignore1
-rw-r--r--testcases/kernel/syscalls/link/link03.c167
-rw-r--r--testcases/kernel/syscalls/link/link05.c28
-rw-r--r--testcases/kernel/syscalls/link/link08.c31
-rw-r--r--testcases/kernel/syscalls/mkdirat/mkdirat01.c1
-rw-r--r--testcases/kernel/syscalls/mkdirat/mkdirat02.c1
-rw-r--r--testcases/kernel/syscalls/mknodat/mknodat.h35
-rw-r--r--testcases/kernel/syscalls/mknodat/mknodat01.c1
-rw-r--r--testcases/kernel/syscalls/mknodat/mknodat02.c2
-rw-r--r--testcases/kernel/syscalls/mmap/mmap04.c236
-rw-r--r--testcases/kernel/syscalls/mmap/mmap15.c123
-rw-r--r--testcases/kernel/syscalls/mount/mount04.c133
-rw-r--r--testcases/kernel/syscalls/mount/mount05.c159
-rw-r--r--testcases/kernel/syscalls/mount/mount06.c197
-rw-r--r--testcases/kernel/syscalls/mremap/mremap06.c27
-rw-r--r--testcases/kernel/syscalls/open/open11.c172
-rw-r--r--testcases/kernel/syscalls/pathconf/.gitignore1
-rw-r--r--testcases/kernel/syscalls/pathconf/pathconf01.c267
-rw-r--r--testcases/kernel/syscalls/pathconf/pathconf02.c98
-rw-r--r--testcases/kernel/syscalls/pipe/.gitignore1
-rw-r--r--testcases/kernel/syscalls/pipe/pipe15.c94
-rw-r--r--testcases/kernel/syscalls/preadv/preadv.h21
-rw-r--r--testcases/kernel/syscalls/preadv/preadv01.c31
-rw-r--r--testcases/kernel/syscalls/preadv/preadv02.c44
-rw-r--r--testcases/kernel/syscalls/preadv/preadv03.c7
-rw-r--r--testcases/kernel/syscalls/ptrace/.gitignore1
-rw-r--r--testcases/kernel/syscalls/ptrace/Makefile27
-rwxr-xr-xtestcases/kernel/syscalls/ptrace/make_syscall_list.sh7
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace.h35
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace01.c3
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace02.c3
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace03.c3
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace04.c6
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace05.c4
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace06.c5
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace07.c3
-rw-r--r--testcases/kernel/syscalls/ptrace/ptrace11.c3
-rw-r--r--testcases/kernel/syscalls/ptrace/simple_tracer.c144
-rw-r--r--testcases/kernel/syscalls/ptrace/syscalls.h17
-rw-r--r--testcases/kernel/syscalls/pwritev/pwritev.h21
-rw-r--r--testcases/kernel/syscalls/pwritev/pwritev01.c25
-rw-r--r--testcases/kernel/syscalls/pwritev/pwritev02.c41
-rw-r--r--testcases/kernel/syscalls/pwritev/pwritev03.c9
-rw-r--r--testcases/kernel/syscalls/readahead/readahead01.c53
-rw-r--r--testcases/kernel/syscalls/remap_file_pages/remap_file_pages01.c32
-rw-r--r--testcases/kernel/syscalls/rename/rename10.c10
-rw-r--r--testcases/kernel/syscalls/renameat/renameat01.c1
-rw-r--r--testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c10
-rw-r--r--testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c3
-rw-r--r--testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c20
-rw-r--r--testcases/kernel/syscalls/sched_setparam/sched_setparam03.c2
-rw-r--r--testcases/kernel/syscalls/sched_setparam/sched_setparam04.c11
-rw-r--r--testcases/kernel/syscalls/sched_setscheduler/.gitignore1
-rw-r--r--testcases/kernel/syscalls/sched_setscheduler/sched_setscheduler04.c78
-rw-r--r--testcases/kernel/syscalls/sendfile/sendfile09.c10
-rw-r--r--testcases/kernel/syscalls/sendmmsg/sendmmsg.h5
-rw-r--r--testcases/kernel/syscalls/setgroups/.gitignore2
-rw-r--r--testcases/kernel/syscalls/setgroups/Makefile3
-rw-r--r--testcases/kernel/syscalls/setgroups/setgroups04.c167
-rw-r--r--testcases/kernel/syscalls/setsockopt/.gitignore1
-rw-r--r--testcases/kernel/syscalls/setsockopt/setsockopt10.c205
-rw-r--r--testcases/kernel/syscalls/setuid/Makefile3
-rw-r--r--testcases/kernel/syscalls/setxattr/setxattr01.c2
-rw-r--r--testcases/kernel/syscalls/sighold/sighold02.c9
-rw-r--r--testcases/kernel/syscalls/splice/.gitignore2
-rw-r--r--testcases/kernel/syscalls/splice/splice06.c228
-rw-r--r--testcases/kernel/syscalls/splice/splice07.c72
-rw-r--r--testcases/kernel/syscalls/swapon/swapon01.c23
-rw-r--r--testcases/kernel/syscalls/swapon/swapon02.c60
-rw-r--r--testcases/kernel/syscalls/swapon/swaponoff.h10
-rw-r--r--testcases/kernel/syscalls/symlink/.gitignore1
-rw-r--r--testcases/kernel/syscalls/symlink/symlink02.c218
-rw-r--r--testcases/kernel/syscalls/symlink/symlink04.c213
-rw-r--r--testcases/kernel/syscalls/symlink/symlink05.c180
-rw-r--r--testcases/kernel/syscalls/timerfd/.gitignore1
-rw-r--r--testcases/kernel/syscalls/timerfd/timerfd02.c201
-rw-r--r--testcases/kernel/syscalls/timerfd/timerfd03.c170
-rw-r--r--testcases/kernel/syscalls/umount/umount01.c17
-rw-r--r--testcases/kernel/syscalls/umount/umount02.c34
-rw-r--r--testcases/kernel/syscalls/umount/umount03.c24
-rw-r--r--testcases/kernel/syscalls/utils/compat_16.mk2
-rw-r--r--testcases/kernel/syscalls/wait4/wait402.c105
-rw-r--r--testcases/kernel/syscalls/writev/writev07.c35
179 files changed, 3359 insertions, 5192 deletions
diff --git a/testcases/kernel/syscalls/accept/.gitignore b/testcases/kernel/syscalls/accept/.gitignore
index 5b1462699..f81d4bec9 100644
--- a/testcases/kernel/syscalls/accept/.gitignore
+++ b/testcases/kernel/syscalls/accept/.gitignore
@@ -1,2 +1,3 @@
/accept01
/accept02
+/accept03
diff --git a/testcases/kernel/syscalls/accept/accept01.c b/testcases/kernel/syscalls/accept/accept01.c
index 85af0f8af..e5db1dfec 100644
--- a/testcases/kernel/syscalls/accept/accept01.c
+++ b/testcases/kernel/syscalls/accept/accept01.c
@@ -26,7 +26,6 @@
struct sockaddr_in sin0, sin1, fsin1;
int invalid_socketfd = 400; /* anything that is not an open file */
-int devnull_fd;
int socket_fd;
int udp_fd;
@@ -46,10 +45,6 @@ static struct test_case {
"bad file descriptor"
},
{
- PF_INET, SOCK_STREAM, 0, &devnull_fd, (struct sockaddr *)&fsin1,
- sizeof(fsin1), ENOTSOCK, "fd is not socket"
- },
- {
PF_INET, SOCK_STREAM, 0, &socket_fd, (struct sockaddr *)3,
sizeof(fsin1), EINVAL, "invalid socket buffer"
},
@@ -73,8 +68,6 @@ static void test_setup(void)
sin0.sin_port = 0;
sin0.sin_addr.s_addr = INADDR_ANY;
- devnull_fd = SAFE_OPEN("/dev/null", O_WRONLY);
-
socket_fd = SAFE_SOCKET(PF_INET, SOCK_STREAM, 0);
SAFE_BIND(socket_fd, (struct sockaddr *)&sin0, sizeof(sin0));
@@ -88,7 +81,6 @@ static void test_setup(void)
static void test_cleanup(void)
{
- SAFE_CLOSE(devnull_fd);
SAFE_CLOSE(socket_fd);
SAFE_CLOSE(udp_fd);
}
diff --git a/testcases/kernel/syscalls/accept/accept03.c b/testcases/kernel/syscalls/accept/accept03.c
new file mode 100644
index 000000000..b85ec0d9b
--- /dev/null
+++ b/testcases/kernel/syscalls/accept/accept03.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2023-2024 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that accept() returns ENOTSOCK or EBADF for non-socket file
+ * descriptors. The EBADF is returned in the case that the file descriptor has
+ * not a file associated with it, which is for example in the case of O_PATH
+ * opened file.
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "tst_test.h"
+
+void check_accept(struct tst_fd *fd)
+{
+ struct sockaddr_in addr = {
+ .sin_family = AF_INET,
+ .sin_port = 0,
+ .sin_addr = {.s_addr = INADDR_ANY},
+ };
+
+ socklen_t size = sizeof(addr);
+
+ int exp_errno = ENOTSOCK;
+
+ switch (fd->type) {
+ case TST_FD_UNIX_SOCK:
+ case TST_FD_INET_SOCK:
+ return;
+ /*
+ * With these two we fail even before we get to the do_accept() because
+ * the fd does not have a struct file associated.
+ */
+ case TST_FD_OPEN_TREE:
+ case TST_FD_PATH:
+ exp_errno = EBADF;
+ default:
+ break;
+ }
+
+ TST_EXP_FAIL2(accept(fd->fd, (void*)&addr, &size),
+ exp_errno, "accept() on %s", tst_fd_desc(fd));
+}
+
+static void verify_accept(void)
+{
+ TST_FD_FOREACH(fd)
+ check_accept(&fd);
+}
+
+static struct tst_test test = {
+ .test_all = verify_accept,
+};
diff --git a/testcases/kernel/syscalls/acct/acct01.c b/testcases/kernel/syscalls/acct/acct01.c
index 52c4d41da..a05ed2ea9 100644
--- a/testcases/kernel/syscalls/acct/acct01.c
+++ b/testcases/kernel/syscalls/acct/acct01.c
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (c) International Business Machines Corp., 2002
+ * Copyright (c) Linux Test Project, 2003-2023
+ * 12/03/2002 Port to LTP robbiew@us.ibm.com
+ * 06/30/2001 Port to Linux nsharoff@us.ibm.com
*/
-/* 12/03/2002 Port to LTP robbiew@us.ibm.com */
-/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
-
/*\
- * [DOCUMENTATION]
+ * [Description]
+ *
* Verify that acct() returns proper errno on failure.
*/
diff --git a/testcases/kernel/syscalls/acct/acct02.c b/testcases/kernel/syscalls/acct/acct02.c
index b8eb1aad4..d3f3d9d04 100644
--- a/testcases/kernel/syscalls/acct/acct02.c
+++ b/testcases/kernel/syscalls/acct/acct02.c
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) SUSE LLC, 2019
- * Author: Christian Amann <camann@suse.com>
+ * Copyright (c) SUSE LLC, 2019
+ * Copyright (c) Linux Test Project, 2019-2023
+ * Author: Christian Amann <camann@suse.com>
*/
/*\
- * [DOCUMENTATION]
+ * [Description]
*
* This tests if the kernel writes correct data to the
* process accounting file.
@@ -19,8 +20,8 @@
* file, the contents get parsed until the correct entry is found, or EOF
* is reached.
*
- * This is also accidental regression test for:
- * 4d9570158b626 kernel/acct.c: fix the acct->needcheck check in check_free_space()
+ * This is also regression test for commit:
+ * 4d9570158b62 ("kernel/acct.c: fix the acct->needcheck check in check_free_space()")
*/
#include <sys/stat.h>
@@ -55,10 +56,7 @@ static union acct_union {
static int acct_version_is_3(void)
{
- struct tst_kconfig_var kconfig = {
- .id = ACCT_V3,
- .id_len = sizeof(ACCT_V3)-1,
- };
+ struct tst_kconfig_var kconfig = TST_KCONFIG_INIT(ACCT_V3);
tst_kconfig_read(&kconfig, 1);
diff --git a/testcases/kernel/syscalls/acct/acct02_helper.c b/testcases/kernel/syscalls/acct/acct02_helper.c
index 66017cb9b..0f55a6ae6 100644
--- a/testcases/kernel/syscalls/acct/acct02_helper.c
+++ b/testcases/kernel/syscalls/acct/acct02_helper.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) SUSE LLC, 2019
- * Author: Christian Amann <camann@suse.com>
+ * Copyright (c) SUSE LLC, 2019
+ * Author: Christian Amann <camann@suse.com>
*/
/*
* Dummy program used in acct02
diff --git a/testcases/kernel/syscalls/adjtimex/adjtimex03.c b/testcases/kernel/syscalls/adjtimex/adjtimex03.c
index 7056973cc..9d34235e4 100644
--- a/testcases/kernel/syscalls/adjtimex/adjtimex03.c
+++ b/testcases/kernel/syscalls/adjtimex/adjtimex03.c
@@ -23,7 +23,7 @@
* To test that, Pass struct timex buffer filled with zero with
* some INVALID mode to the system call adjtimex. Passing an invalid
* parameters will not call do_adjtimex() and before that, it shall throw
- * an error(On error test shall not break). Therefore, none of the parameters
+ * an error (on error test shall not break). Therefore, none of the parameters
* will get initialized.
*
* On reading the last attribute tai of the struct, if the attribute is non-
diff --git a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
index 7577ab24d..63ebf5295 100644
--- a/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
+++ b/testcases/kernel/syscalls/clock_adjtime/clock_adjtime.h
@@ -251,4 +251,5 @@ TIMEX_GET_SET_FIELD_TYPE(uint, uint);
TIMEX_GET_SET_FIELD_TYPE(long, long long);
#undef TIMEX_GET_SET_FIELD_TYPE
-#endif
+
+#endif /* CLOCK_ADJTIME_H__ */
diff --git a/testcases/kernel/syscalls/dup/dup06.c b/testcases/kernel/syscalls/dup/dup06.c
index e3f8070bf..cd4cb3513 100644
--- a/testcases/kernel/syscalls/dup/dup06.c
+++ b/testcases/kernel/syscalls/dup/dup06.c
@@ -1,41 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2002
- * ported from SPIE, section2/iosuite/dup1.c, by Airong Zhang
- * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2002
+ * Ported from SPIE, section2/iosuite/dup1.c, by Airong Zhang
+ * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2003-2024
*/
-/*
- WHAT: Does dup return -1 on the 21st file?
- HOW: Create up to _NFILE (20) files and check for -1 return on the
- next attempt
- Should check NOFILE as well as _NFILE. 19-Jun-84 Dale.
-*/
+/*\
+ * [Description]
+ *
+ * Test for dup(2) syscall with max open file descriptors.
+ */
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include "test.h"
+#include <stdlib.h>
+#include "tst_test.h"
-char *TCID = "dup06";
-int TST_TOTAL = 1;
+static int *pfildes;
+static int minfd, maxfd, freefds;
+static char pfilname[40];
static int cnt_free_fds(int maxfd)
{
@@ -45,70 +27,53 @@ static int cnt_free_fds(int maxfd)
if (fcntl(maxfd, F_GETFD) == -1 && errno == EBADF)
freefds++;
- return (freefds);
+ return freefds;
}
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
+static void setup(void)
{
- int *fildes, i;
- int min;
- int freefds;
- int lc;
- const char *pfilname = "dup06";
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- min = getdtablesize();
- freefds = cnt_free_fds(min);
- fildes = malloc((min + 5) * sizeof(int));
-
- for (i = 0; i < min + 5; i++)
- fildes[i] = 0;
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- unlink(pfilname);
-
- if ((fildes[0] = creat(pfilname, 0666)) == -1) {
- tst_resm(TFAIL, "Cannot open first file");
- } else {
- for (i = 1; i < min + 5; i++) {
- if ((fildes[i] = dup(fildes[i - 1])) == -1)
- break;
- }
- if (i < freefds) {
- tst_resm(TFAIL, "Not enough files duped");
- } else if (i > freefds) {
- tst_resm(TFAIL, "Too many files duped");
- } else {
- tst_resm(TPASS, "Test passed.");
- }
- }
-
- unlink(pfilname);
-
- for (i = 0; i < min + 5; i++) {
- if (fildes[i] != 0 && fildes[i] != -1)
- close(fildes[i]);
-
- fildes[i] = 0;
- }
- }
-
- cleanup();
- tst_exit();
+ minfd = getdtablesize(); /* get number of files allowed open */
+ maxfd = minfd + 5;
+ freefds = cnt_free_fds(minfd);
+ pfildes = SAFE_MALLOC(maxfd * sizeof(int));
+ memset(pfildes, -1, maxfd * sizeof(int));
+ sprintf(pfilname, "./dup06.%d\n", getpid());
}
-static void setup(void)
+static void cleanup(void)
{
- tst_tmpdir();
+ if (pfildes != NULL)
+ free(pfildes);
}
-static void cleanup(void)
+static void run(void)
{
- tst_rmdir();
+ int i;
+
+ pfildes[0] = SAFE_CREAT(pfilname, 0666);
+ for (i = 1; i < maxfd; i++) {
+ pfildes[i] = dup(pfildes[i - 1]);
+ if (pfildes[i] == -1)
+ break;
+ }
+ if (i < freefds)
+ tst_res(TFAIL, "Not enough files duped");
+ else if (i > freefds)
+ tst_res(TFAIL, "Too many files duped");
+ else
+ tst_res(TPASS, "Test passed");
+
+ SAFE_UNLINK(pfilname);
+
+ for (i = 0; i < maxfd; i++) {
+ if (pfildes[i] != 0 && pfildes[i] != -1)
+ SAFE_CLOSE(pfildes[i]);
+ }
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/dup/dup07.c b/testcases/kernel/syscalls/dup/dup07.c
index a100f5d58..688ee1989 100644
--- a/testcases/kernel/syscalls/dup/dup07.c
+++ b/testcases/kernel/syscalls/dup/dup07.c
@@ -1,142 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2002
- * ported from SPIE, section2/iosuite/dup3.c, by Airong Zhang
- * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2002
+ * Ported from SPIE, section2/iosuite/dup3.c, by Airong Zhang
+ * Copyright (c) 2013 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2006-2024
*/
-/*
- WHAT: Is the access mode the same for both file descriptors?
- 0: read only?
- 1: write only?
- 2: read/write?
- HOW: Creat a file with each access mode; dup each file descriptor;
- stat each file descriptor and compare mode of each pair
-*/
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "test.h"
+/*\
+ * [Description]
+ *
+ * Verify that the file descriptor created by dup(2) syscall has the same
+ * access mode as the old one.
+ */
-char *TCID = "dup07";
-int TST_TOTAL = 3;
+#include "tst_test.h"
static const char *testfile = "dup07";
-static void setup(void);
-static void cleanup(void);
+static struct tcase {
+ char *mode_desc;
+ int mode;
+} tcases[] = {
+ {"read only", 0444},
+ {"write only", 0222},
+ {"read/write", 0666},
+};
-int main(int ac, char **av)
+static void run(unsigned int n)
{
- struct stat retbuf;
- struct stat dupbuf;
- int rdoret, wroret, rdwret;
- int duprdo, dupwro, duprdwr;
-
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- if ((rdoret = creat(testfile, 0444)) == -1) {
- tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
- } else {
- if ((duprdo = dup(rdoret)) == -1) {
- tst_resm(TFAIL, "Unable to dup '%s'", testfile);
- } else {
- fstat(rdoret, &retbuf);
- fstat(duprdo, &dupbuf);
- if (retbuf.st_mode != dupbuf.st_mode) {
- tst_resm(TFAIL,
- "rdonly and dup do not match");
- } else {
- tst_resm(TPASS,
- "Passed in read mode.");
- }
- close(duprdo);
- }
- close(rdoret);
- }
-
- unlink(testfile);
-
- if ((wroret = creat(testfile, 0222)) == -1) {
- tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
- } else {
- if ((dupwro = dup(wroret)) == -1) {
- tst_resm(TFAIL, "Unable to dup '%s'", testfile);
- } else {
- fstat(wroret, &retbuf);
- fstat(dupwro, &dupbuf);
- if (retbuf.st_mode != dupbuf.st_mode) {
- tst_resm(TFAIL,
- "wronly and dup do not match");
- } else {
- tst_resm(TPASS,
- "Passed in write mode.");
- }
- close(dupwro);
- }
- close(wroret);
-
- }
-
- unlink(testfile);
-
- if ((rdwret = creat(testfile, 0666)) == -1) {
- tst_resm(TFAIL, "Unable to creat file '%s'", testfile);
- } else {
- if ((duprdwr = dup(rdwret)) == -1) {
- tst_resm(TFAIL, "Unable to dup '%s'", testfile);
- } else {
- fstat(rdwret, &retbuf);
- fstat(duprdwr, &dupbuf);
- if (retbuf.st_mode != dupbuf.st_mode) {
- tst_resm(TFAIL,
- "rdwr and dup do not match");
- } else {
- tst_resm(TPASS,
- "Passed in read/write mode.");
- }
- close(duprdwr);
- }
- close(rdwret);
- }
-
- unlink(testfile);
+ int oldfd, dupfd;
+ struct stat oldbuf, dupbuf;
+ struct tcase *tc = &tcases[n];
+
+ oldfd = SAFE_CREAT(testfile, tc->mode);
+ dupfd = TST_EXP_FD_SILENT(dup(oldfd), "dup() %s file", tc->mode_desc);
+ if (TST_PASS) {
+ SAFE_FSTAT(oldfd, &oldbuf);
+ SAFE_FSTAT(dupfd, &dupbuf);
+
+ if (oldbuf.st_mode != dupbuf.st_mode)
+ tst_res(TFAIL, "%s and dup do not match", tc->mode_desc);
+ else
+ tst_res(TPASS, "Passed in %s mode", tc->mode_desc);
+
+ SAFE_CLOSE(dupfd);
}
- cleanup();
- tst_exit();
+ SAFE_CLOSE(oldfd);
+ SAFE_UNLINK(testfile);
}
-static void setup(void)
-{
- tst_tmpdir();
-}
-
-static void cleanup(void)
-{
- tst_rmdir();
-}
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/eventfd2/eventfd2.h b/testcases/kernel/syscalls/eventfd2/eventfd2.h
index 5350820b8..2333d1e53 100644
--- a/testcases/kernel/syscalls/eventfd2/eventfd2.h
+++ b/testcases/kernel/syscalls/eventfd2/eventfd2.h
@@ -3,6 +3,9 @@
* Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
+#ifndef EVENTFD2_H__
+#define EVENTFD2_H__
+
#include "tst_test.h"
#include "lapi/syscalls.h"
@@ -16,3 +19,5 @@ static inline int eventfd2(unsigned int count, unsigned int flags)
return ret;
}
+
+#endif /* EVENTFD2_H__ */
diff --git a/testcases/kernel/syscalls/execve/execve04.c b/testcases/kernel/syscalls/execve/execve04.c
index 18e883ab3..3bac642e5 100644
--- a/testcases/kernel/syscalls/execve/execve04.c
+++ b/testcases/kernel/syscalls/execve/execve04.c
@@ -8,7 +8,9 @@
* 04/2008 Roy Lee <roylee@andestech.com>
*/
-/*
+/*\
+ * [Description]
+ *
* Attempt to execve(2) a file which is being opened by another process for
* writing fails with ETXTBSY.
*/
diff --git a/testcases/kernel/syscalls/execve/execve05.c b/testcases/kernel/syscalls/execve/execve05.c
index 87565d994..d87d7446d 100644
--- a/testcases/kernel/syscalls/execve/execve05.c
+++ b/testcases/kernel/syscalls/execve/execve05.c
@@ -1,32 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2018 Linux Test Project
+ * Copyright (c) 2001-2023 Linux Test Project
* Copyright (c) International Business Machines Corp., 2001
- *
+ * Copyright (c) 2008 Renaud Lottiaux <Renaud.Lottiaux@kerlabs.com>
* Ported to LTP: Wayne Boyer
- * 21/04/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
*/
-/*
- * NAME
- * execve05.c
- *
- * DESCRIPTION
- * This testcase tests the basic functionality of the execve(2) system
- * call.
+/*\
+ * [Description]
*
- * ALGORITHM
- * This tests the functionality of the execve(2) system call by spawning
- * a few children, each of which would execute "execve_child" simultaneously,
- * and finally the parent ensures that they terminated correctly.
- *
- * USAGE
- * execve05 -i 5 -n 20
+ * This tests the functionality of the execve(2) system call by spawning
+ * a few children, each of which would execute "execve_child" simultaneously,
+ * and finally the parent ensures that they terminated correctly.
*/
-#ifndef _GNU_SOURCE
#define _GNU_SOURCE
-#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
diff --git a/testcases/kernel/syscalls/exit_group/Makefile b/testcases/kernel/syscalls/exit_group/Makefile
index 1273a4e9c..adbac3c51 100644
--- a/testcases/kernel/syscalls/exit_group/Makefile
+++ b/testcases/kernel/syscalls/exit_group/Makefile
@@ -3,6 +3,8 @@
top_srcdir ?= ../../../..
+exit_group01: CFLAGS+=-pthread
+
include $(top_srcdir)/include/mk/testcases.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/exit_group/exit_group01.c b/testcases/kernel/syscalls/exit_group/exit_group01.c
index 5bf5b0218..6407a20e8 100644
--- a/testcases/kernel/syscalls/exit_group/exit_group01.c
+++ b/testcases/kernel/syscalls/exit_group/exit_group01.c
@@ -1,68 +1,127 @@
-/******************************************************************************
- * Copyright (c) Crackerjack Project., 2007 *
- * Ported to LTP by Manas Kumar Nayak <maknayak@in.ibm.com> *
- * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
- * the GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software Foundation, *
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- * *
- ******************************************************************************/
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Crackerjack Project., 2007
+ * Ported to LTP by Manas Kumar Nayak <maknayak@in.ibm.com>
+ * Copyright (c) 2015 Linux Test Project
+ * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
-#include <stdio.h>
-#include <errno.h>
-#include <linux/unistd.h>
-#include <sys/wait.h>
+/*\
+ * [Description]
+ *
+ * This test checks if exit_group() correctly ends a spawned child and all its
+ * running threads.
+ */
-#include "test.h"
-#include "safe_macros.h"
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tst_test.h"
#include "lapi/syscalls.h"
+#include "tst_safe_pthread.h"
+
+static int cpu_count;
-char *TCID = "exit_group01";
-int testno;
-int TST_TOTAL = 1;
+static struct worker_data {
+ pid_t tid;
+ int counter;
+} *workers_data;
-static void verify_exit_group(void)
+static void *worker(void *arg)
{
- pid_t cpid, w;
- int status;
+ struct worker_data *data;
- cpid = fork();
- if (cpid == -1)
- tst_brkm(TFAIL | TERRNO, NULL, "fork failed");
+ data = (struct worker_data *)arg;
+ data->tid = tst_gettid();
- if (cpid == 0) {
- TEST(tst_syscall(__NR_exit_group, 4));
- } else {
- w = SAFE_WAIT(NULL, &status);
-
- if (WIFEXITED(status) && (WEXITSTATUS(status) == 4)) {
- tst_resm(TPASS, "exit_group() succeeded");
- } else {
- tst_resm(TFAIL | TERRNO,
- "exit_group() failed (wait status = %d)", w);
+ while (1) {
+ tst_atomic_inc(&data->counter);
+ sched_yield();
+ }
+
+ return arg;
+}
+
+static void spawn_threads(void)
+{
+ pthread_t threads[cpu_count];
+
+ for (int i = 0; i < cpu_count; i++)
+ SAFE_PTHREAD_CREATE(&threads[i], NULL, worker, (void *)(workers_data + i));
+}
+
+static void check_counters(void)
+{
+ struct worker_data data_copy[cpu_count];
+
+ memset(data_copy, 0, sizeof(struct worker_data) * cpu_count);
+ memcpy(data_copy, workers_data, sizeof(struct worker_data) * cpu_count);
+
+ tst_res(TINFO, "Checking if threads are still running");
+ usleep(100000);
+
+ struct worker_data *old_data;
+ struct worker_data *new_data;
+
+ for (int i = 0; i < cpu_count; i++) {
+ old_data = data_copy + i;
+ new_data = workers_data + i;
+
+ if (old_data->counter != new_data->counter) {
+ tst_res(TFAIL, "Counter value has changed for thread[%d]", i);
+ return;
}
}
+
+ tst_res(TINFO, "Threads counters value didn't change");
}
-int main(int ac, char **av)
+static void run(void)
{
- int lc;
+ pid_t pid;
+ int status;
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ spawn_threads();
+
+ TEST(tst_syscall(__NR_exit_group, 4));
+ if (TST_RET == -1)
+ tst_brk(TBROK | TERRNO, "exit_group() error");
+
+ return;
+ }
- tst_parse_opts(ac, av, NULL, NULL);
+ SAFE_WAITPID(pid, &status, 0);
- for (lc = 0; TEST_LOOPING(lc); lc++)
- verify_exit_group();
+ TST_EXP_EXPR(WIFEXITED(status) && WEXITSTATUS(status) == 4,
+ "exit_group() succeeded");
- tst_exit();
+ check_counters();
}
+
+static void setup(void)
+{
+ cpu_count = MAX(2, tst_ncpus());
+
+ workers_data = SAFE_MMAP(
+ NULL,
+ sizeof(struct worker_data) * cpu_count,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_ANONYMOUS,
+ -1, 0);
+}
+
+static void cleanup(void)
+{
+ SAFE_MUNMAP(workers_data, sizeof(struct worker_data) * cpu_count);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/syscalls/fallocate/fallocate06.c b/testcases/kernel/syscalls/fallocate/fallocate06.c
index 124fb7eae..24f98e271 100644
--- a/testcases/kernel/syscalls/fallocate/fallocate06.c
+++ b/testcases/kernel/syscalls/fallocate/fallocate06.c
@@ -260,6 +260,8 @@ static struct tst_test test = {
.test = run,
.tcnt = ARRAY_SIZE(testcase_list),
.needs_root = 1,
+ .dev_min_size = 1024,
+ .max_runtime = 120,
.mount_device = 1,
.mntpoint = MNTPOINT,
.all_filesystems = 1,
diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h
index 75a081dc9..e0d178bcc 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify.h
+++ b/testcases/kernel/syscalls/fanotify/fanotify.h
@@ -68,19 +68,14 @@ static inline int safe_fanotify_mark(const char *file, const int lineno,
#ifdef HAVE_NAME_TO_HANDLE_AT
-#ifndef MAX_HANDLE_SZ
-#define MAX_HANDLE_SZ 128
-#endif
-
-#ifndef AT_HANDLE_FID
-#define AT_HANDLE_FID 0x200
-#endif
-
/*
* Helper function used to obtain fsid and file_handle for a given path.
* Used by test files correlated to FAN_REPORT_FID functionality.
+ *
+ * Returns 0 if normal NFS file handles are supported.
+ * Returns AT_HANDLE_FID, if only non-decodeable file handles are supported.
*/
-static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
+static inline int fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
struct file_handle *handle)
{
int mount_id;
@@ -93,6 +88,11 @@ static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) {
if (errno == EOPNOTSUPP) {
+ /* Try to request non-decodeable fid instead */
+ if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id,
+ AT_HANDLE_FID) == 0)
+ return AT_HANDLE_FID;
+
tst_brk(TCONF,
"filesystem %s does not support file handles",
tst_device->fs_type);
@@ -100,30 +100,30 @@ static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid,
tst_brk(TBROK | TERRNO,
"name_to_handle_at(AT_FDCWD, %s, ...) failed", path);
}
+ return 0;
}
-#ifndef FILEID_INVALID
-#define FILEID_INVALID 0xff
-#endif
-
struct fanotify_fid_t {
__kernel_fsid_t fsid;
struct file_handle handle;
char buf[MAX_HANDLE_SZ];
};
-static inline void fanotify_save_fid(const char *path,
+static inline int fanotify_save_fid(const char *path,
struct fanotify_fid_t *fid)
{
int *fh = (int *)(fid->handle.f_handle);
+ int ret;
fh[0] = fh[1] = fh[2] = 0;
fid->handle.handle_bytes = MAX_HANDLE_SZ;
- fanotify_get_fid(path, &fid->fsid, &fid->handle);
+ ret = fanotify_get_fid(path, &fid->fsid, &fid->handle);
tst_res(TINFO,
"fid(%s) = %x.%x.%x.%x.%x...", path, fid->fsid.val[0],
fid->fsid.val[1], fh[0], fh[1], fh[2]);
+
+ return ret;
}
#endif /* HAVE_NAME_TO_HANDLE_AT */
@@ -133,13 +133,14 @@ static inline void fanotify_save_fid(const char *path,
#define INIT_FANOTIFY_MARK_TYPE(t) \
{ FAN_MARK_ ## t, "FAN_MARK_" #t }
-static inline void require_fanotify_access_permissions_supported_by_kernel(void)
+static inline void require_fanotify_access_permissions_supported_on_fs(
+ const char *fname)
{
int fd;
fd = SAFE_FANOTIFY_INIT(FAN_CLASS_CONTENT, O_RDONLY);
- if (fanotify_mark(fd, FAN_MARK_ADD, FAN_ACCESS_PERM, AT_FDCWD, ".") < 0) {
+ if (fanotify_mark(fd, FAN_MARK_ADD, FAN_ACCESS_PERM, AT_FDCWD, fname) < 0) {
if (errno == EINVAL) {
tst_brk(TCONF | TERRNO,
"CONFIG_FANOTIFY_ACCESS_PERMISSIONS not configured in kernel?");
@@ -152,21 +153,42 @@ static inline void require_fanotify_access_permissions_supported_by_kernel(void)
SAFE_CLOSE(fd);
}
-static inline int fanotify_events_supported_by_kernel(uint64_t mask,
- unsigned int init_flags,
- unsigned int mark_flags)
+/*
+ * @return 0: fanotify flags supported both in kernel and on tested filesystem
+ * @return -1: @init_flags not supported in kernel
+ * @return -2: @mark_flags not supported on tested filesystem (tested if @fname is not NULL)
+ * @return -3: @mark_flags not supported on overlayfs (tested if @fname == OVL_MNT)
+ */
+static inline int fanotify_flags_supported_on_fs(unsigned int init_flags,
+ unsigned int mark_flags,
+ uint64_t event_flags,
+ const char *fname)
{
int fd;
int rval = 0;
- fd = SAFE_FANOTIFY_INIT(init_flags, O_RDONLY);
+ fd = fanotify_init(init_flags, O_RDONLY);
- if (fanotify_mark(fd, FAN_MARK_ADD | mark_flags, mask, AT_FDCWD, ".") < 0) {
- if (errno == EINVAL) {
- rval = -1;
- } else {
+ if (fd < 0) {
+ if (errno == ENOSYS)
+ tst_brk(TCONF, "fanotify not configured in kernel");
+ if (errno != EINVAL)
+ tst_brk(TBROK | TERRNO,
+ "fanotify_init(%x, O_RDONLY) failed",
+ init_flags);
+ return -1;
+ }
+
+ if (fname && fanotify_mark(fd, FAN_MARK_ADD | mark_flags, event_flags, AT_FDCWD, fname) < 0) {
+ if (errno == ENODEV || errno == EOPNOTSUPP || errno == EXDEV) {
+ rval = strcmp(fname, OVL_MNT) ? -2 : -3;
+ } else if (errno != EINVAL) {
tst_brk(TBROK | TERRNO,
- "fanotify_mark (%d, FAN_MARK_ADD, ..., AT_FDCWD, \".\") failed", fd);
+ "fanotify_mark (%d, FAN_MARK_ADD | %x, %llx, AT_FDCWD, %s) failed",
+ fd, mark_flags, (unsigned long long)event_flags,
+ fname);
+ } else {
+ rval = -1;
}
}
@@ -175,95 +197,85 @@ static inline int fanotify_events_supported_by_kernel(uint64_t mask,
return rval;
}
-/*
- * @return 0: fanotify supported both in kernel and on tested filesystem
- * @return -1: @flags not supported in kernel
- * @return -2: @flags not supported on tested filesystem (tested if @fname is not NULL)
- */
static inline int fanotify_init_flags_supported_on_fs(unsigned int flags, const char *fname)
{
- int fd;
- int rval = 0;
-
- fd = fanotify_init(flags, O_RDONLY);
+ return fanotify_flags_supported_on_fs(flags, FAN_MARK_INODE, FAN_ACCESS, fname);
+}
- if (fd < 0) {
- if (errno == ENOSYS)
- tst_brk(TCONF, "fanotify not configured in kernel");
+static inline int fanotify_mark_supported_on_fs(uint64_t flag, const char *fname)
+{
+ return fanotify_flags_supported_on_fs(FAN_CLASS_NOTIF, flag, FAN_ACCESS, fname);
+}
- if (errno == EINVAL)
- return -1;
+#define TST_FANOTIFY_INIT_KNOWN_FLAGS \
+ (FAN_REPORT_DFID_NAME_TARGET | FAN_REPORT_TID | FAN_REPORT_PIDFD | \
+ FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
- tst_brk(TBROK | TERRNO, "fanotify_init() failed");
+/*
+ * Check support of given init flags one by one and return those which are
+ * supported.
+ */
+static inline unsigned int fanotify_get_supported_init_flags(unsigned int flags,
+ const char *fname)
+{
+ unsigned int i, flg, arg, ret = 0;
+ static const struct { unsigned int flag, deps; } deplist[] = {
+ {FAN_REPORT_NAME, FAN_REPORT_DIR_FID},
+ {FAN_REPORT_TARGET_FID, FAN_REPORT_DFID_NAME_FID},
+ {0, 0}
+ };
+
+ if (flags & ~TST_FANOTIFY_INIT_KNOWN_FLAGS) {
+ tst_brk(TBROK, "fanotify_init() feature check called with unknown flags %x, please update flag dependency table if needed",
+ flags & ~TST_FANOTIFY_INIT_KNOWN_FLAGS);
}
- if (fname && fanotify_mark(fd, FAN_MARK_ADD, FAN_ACCESS, AT_FDCWD, fname) < 0) {
- if (errno == ENODEV || errno == EOPNOTSUPP || errno == EXDEV) {
- rval = -2;
- } else {
- tst_brk(TBROK | TERRNO,
- "fanotify_mark (%d, FAN_MARK_ADD, ..., AT_FDCWD, %s) failed",
- fd, fname);
- }
- }
+ for (flg = 1; flg; flg <<= 1) {
+ if (!(flags & flg))
+ continue;
- SAFE_CLOSE(fd);
+ arg = flg;
- return rval;
-}
+ for (i = 0; deplist[i].flag; i++) {
+ if (deplist[i].flag == flg) {
+ arg |= deplist[i].deps;
+ break;
+ }
+ }
-static inline int fanotify_init_flags_supported_by_kernel(unsigned int flags)
-{
- return fanotify_init_flags_supported_on_fs(flags, NULL);
+ if (!fanotify_init_flags_supported_on_fs(arg, fname))
+ ret |= flg;
+ }
+
+ return ret;
}
typedef void (*tst_res_func_t)(const char *file, const int lineno,
int ttype, const char *fmt, ...);
-static inline void fanotify_init_flags_err_msg(const char *flags_str,
+static inline void fanotify_flags_err_msg(const char *flags_str,
const char *file, const int lineno, tst_res_func_t res_func, int fail)
{
if (fail == -1)
res_func(file, lineno, TCONF,
"%s not supported in kernel?", flags_str);
- if (fail == -2)
+ if (fail == -2 || fail == -3)
res_func(file, lineno, TCONF,
- "%s not supported on %s filesystem",
- flags_str, tst_device->fs_type);
+ "%s not supported on %s%s filesystem",
+ flags_str, fail == -3 ? "overlayfs over " : "",
+ tst_device->fs_type);
}
#define FANOTIFY_INIT_FLAGS_ERR_MSG(flags, fail) \
- fanotify_init_flags_err_msg(#flags, __FILE__, __LINE__, tst_res_, (fail))
+ fanotify_flags_err_msg(#flags, __FILE__, __LINE__, tst_res_, (fail))
+
+#define FANOTIFY_MARK_FLAGS_ERR_MSG(mark, fail) \
+ fanotify_flags_err_msg((mark)->name, __FILE__, __LINE__, tst_res_, (fail))
#define REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(flags, fname) \
- fanotify_init_flags_err_msg(#flags, __FILE__, __LINE__, tst_brk_, \
+ fanotify_flags_err_msg(#flags, __FILE__, __LINE__, tst_brk_, \
fanotify_init_flags_supported_on_fs(flags, fname))
-#define REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_BY_KERNEL(flags) \
- fanotify_init_flags_err_msg(#flags, __FILE__, __LINE__, tst_brk_, \
- fanotify_init_flags_supported_by_kernel(flags))
-
-static inline int fanotify_mark_supported_by_kernel(uint64_t flag)
-{
- int fd;
- int rval = 0;
-
- fd = SAFE_FANOTIFY_INIT(FAN_CLASS_CONTENT, O_RDONLY);
-
- if (fanotify_mark(fd, FAN_MARK_ADD | flag, FAN_ACCESS, AT_FDCWD, ".") < 0) {
- if (errno == EINVAL) {
- rval = -1;
- } else {
- tst_brk(TBROK | TERRNO,
- "fanotify_mark (%d, FAN_MARK_ADD, ..., FAN_ACCESS, AT_FDCWD, \".\") failed", fd);
- }
- }
-
- SAFE_CLOSE(fd);
-
- return rval;
-}
-
static inline int fanotify_handle_supported_by_kernel(int flag)
{
/*
@@ -277,21 +289,21 @@ static inline int fanotify_handle_supported_by_kernel(int flag)
return 0;
}
-#define REQUIRE_MARK_TYPE_SUPPORTED_BY_KERNEL(mark_type) \
- fanotify_init_flags_err_msg(#mark_type, __FILE__, __LINE__, tst_brk_, \
- fanotify_mark_supported_by_kernel(mark_type))
+#define REQUIRE_MARK_TYPE_SUPPORTED_ON_FS(mark_type, fname) \
+ fanotify_flags_err_msg(#mark_type, __FILE__, __LINE__, tst_brk_, \
+ fanotify_mark_supported_on_fs(mark_type, fname))
#define REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(handle_type) \
- fanotify_init_flags_err_msg(#handle_type, __FILE__, __LINE__, tst_brk_, \
- fanotify_handle_supported_by_kernel(handle_type))
+ fanotify_flags_err_msg(#handle_type, __FILE__, __LINE__, tst_brk_, \
+ fanotify_handle_supported_by_kernel(handle_type))
#define REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(init_flags, mark_type, mask, fname) do { \
if (mark_type) \
- REQUIRE_MARK_TYPE_SUPPORTED_BY_KERNEL(mark_type); \
+ REQUIRE_MARK_TYPE_SUPPORTED_ON_FS(mark_type, fname); \
if (init_flags) \
REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(init_flags, fname); \
- fanotify_init_flags_err_msg(#mask, __FILE__, __LINE__, tst_brk_, \
- fanotify_events_supported_by_kernel(mask, init_flags, mark_type)); \
+ fanotify_flags_err_msg(#mask, __FILE__, __LINE__, tst_brk_, \
+ fanotify_flags_supported_on_fs(init_flags, mark_type, mask, fname)); \
} while (0)
static inline struct fanotify_event_info_header *get_event_info(
diff --git a/testcases/kernel/syscalls/fanotify/fanotify01.c b/testcases/kernel/syscalls/fanotify/fanotify01.c
index 3538335c9..e4398f236 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify01.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify01.c
@@ -76,6 +76,7 @@ static char fname[BUF_SIZE];
static char buf[BUF_SIZE];
static int fd_notify;
static int fan_report_fid_unsupported;
+static int mount_mark_fid_unsupported;
static int filesystem_mark_unsupported;
static unsigned long long event_set[EVENT_MAX];
@@ -88,16 +89,22 @@ static void test_fanotify(unsigned int n)
struct fanotify_mark_type *mark = &tc->mark;
int fd, ret, len, i = 0, test_num = 0;
int tst_count = 0;
+ int report_fid = (tc->init_flags & FAN_REPORT_FID);
tst_res(TINFO, "Test #%d: %s", n, tc->tname);
- if (fan_report_fid_unsupported && (tc->init_flags & FAN_REPORT_FID)) {
+ if (fan_report_fid_unsupported && report_fid) {
FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_FID, fan_report_fid_unsupported);
return;
}
if (filesystem_mark_unsupported && mark->flag == FAN_MARK_FILESYSTEM) {
- tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?");
+ FANOTIFY_MARK_FLAGS_ERR_MSG(mark, filesystem_mark_unsupported);
+ return;
+ }
+
+ if (mount_mark_fid_unsupported && report_fid && mark->flag != FAN_MARK_INODE) {
+ FANOTIFY_MARK_FLAGS_ERR_MSG(mark, mount_mark_fid_unsupported);
return;
}
@@ -341,7 +348,10 @@ static void setup(void)
SAFE_FILE_PRINTF(fname, "1");
fan_report_fid_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_FID, fname);
- filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM);
+ filesystem_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_FILESYSTEM, fname);
+ mount_mark_fid_unsupported = fanotify_flags_supported_on_fs(FAN_REPORT_FID,
+ FAN_MARK_MOUNT,
+ FAN_OPEN, fname);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/fanotify/fanotify03.c b/testcases/kernel/syscalls/fanotify/fanotify03.c
index 0bd61587a..028da742c 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify03.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify03.c
@@ -320,14 +320,14 @@ static void test_fanotify(unsigned int n)
static void setup(void)
{
- require_fanotify_access_permissions_supported_by_kernel();
-
- filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM);
- exec_events_unsupported = fanotify_events_supported_by_kernel(FAN_OPEN_EXEC_PERM,
- FAN_CLASS_CONTENT, 0);
sprintf(fname, MOUNT_PATH"/fname_%d", getpid());
SAFE_FILE_PRINTF(fname, "1");
+ require_fanotify_access_permissions_supported_on_fs(fname);
+ filesystem_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_FILESYSTEM, fname);
+ exec_events_unsupported = fanotify_flags_supported_on_fs(FAN_CLASS_CONTENT,
+ 0, FAN_OPEN_EXEC_PERM, fname);
+
SAFE_CP(TEST_APP, FILE_EXEC_PATH);
}
diff --git a/testcases/kernel/syscalls/fanotify/fanotify07.c b/testcases/kernel/syscalls/fanotify/fanotify07.c
index 396c8490e..34aa810c7 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify07.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify07.c
@@ -189,10 +189,9 @@ static void test_fanotify(void)
static void setup(void)
{
- require_fanotify_access_permissions_supported_by_kernel();
-
sprintf(fname, "fname_%d", getpid());
SAFE_FILE_PRINTF(fname, "%s", fname);
+ require_fanotify_access_permissions_supported_on_fs(fname);
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/fanotify/fanotify09.c b/testcases/kernel/syscalls/fanotify/fanotify09.c
index 3f2db4709..f61c4e45a 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify09.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify09.c
@@ -480,9 +480,11 @@ static void test_fanotify(unsigned int n)
static void setup(void)
{
- fan_report_dfid_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_DFID_NAME,
- MOUNT_PATH);
- ignore_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_IGNORE_SURV);
+ fan_report_dfid_unsupported = fanotify_flags_supported_on_fs(FAN_REPORT_DFID_NAME,
+ FAN_MARK_MOUNT,
+ FAN_OPEN, MOUNT_PATH);
+ ignore_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_IGNORE_SURV,
+ MOUNT_PATH);
SAFE_MKDIR(MOUNT_NAME, 0755);
SAFE_MOUNT(MOUNT_PATH, MOUNT_NAME, "none", MS_BIND, NULL);
diff --git a/testcases/kernel/syscalls/fanotify/fanotify10.c b/testcases/kernel/syscalls/fanotify/fanotify10.c
index d0e9194e7..6c89ca1d0 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify10.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify10.c
@@ -874,13 +874,17 @@ static void setup(void)
{
int i;
- exec_events_unsupported = fanotify_events_supported_by_kernel(FAN_OPEN_EXEC,
- FAN_CLASS_CONTENT, 0);
- filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM);
- evictable_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_EVICTABLE);
- ignore_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_IGNORE_SURV);
- fan_report_dfid_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_DFID_NAME,
- MOUNT_PATH);
+ exec_events_unsupported = fanotify_flags_supported_on_fs(FAN_CLASS_CONTENT,
+ 0, FAN_OPEN_EXEC, MOUNT_PATH);
+ filesystem_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_FILESYSTEM,
+ MOUNT_PATH);
+ evictable_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_EVICTABLE,
+ MOUNT_PATH);
+ ignore_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_IGNORE_SURV,
+ MOUNT_PATH);
+ fan_report_dfid_unsupported = fanotify_flags_supported_on_fs(FAN_REPORT_DFID_NAME,
+ FAN_MARK_MOUNT,
+ FAN_OPEN, MOUNT_PATH);
if (fan_report_dfid_unsupported) {
FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_DFID_NAME, fan_report_dfid_unsupported);
/* Limit tests to legacy priority classes */
diff --git a/testcases/kernel/syscalls/fanotify/fanotify11.c b/testcases/kernel/syscalls/fanotify/fanotify11.c
index 03583d84b..ce46913b1 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify11.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify11.c
@@ -94,7 +94,7 @@ static void test01(unsigned int i)
static void setup(void)
{
- fan_report_tid_unsupported = fanotify_init_flags_supported_by_kernel(FAN_REPORT_TID);
+ fan_report_tid_unsupported = fanotify_init_flags_supported_on_fs(FAN_REPORT_TID, ".");
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/fanotify/fanotify12.c b/testcases/kernel/syscalls/fanotify/fanotify12.c
index 7f8e97b17..42ba08800 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify12.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify12.c
@@ -222,11 +222,10 @@ cleanup:
static void do_setup(void)
{
- exec_events_unsupported = fanotify_events_supported_by_kernel(FAN_OPEN_EXEC,
- FAN_CLASS_NOTIF, 0);
-
sprintf(fname, "fname_%d", getpid());
SAFE_FILE_PRINTF(fname, "1");
+ exec_events_unsupported = fanotify_flags_supported_on_fs(FAN_CLASS_NOTIF,
+ 0, FAN_OPEN_EXEC, fname);
}
static void do_cleanup(void)
diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c
index a25a360fd..6086a81fc 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify13.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify13.c
@@ -91,8 +91,10 @@ static struct test_case_t {
static int ovl_mounted;
static int bind_mounted;
+static int ovl_bind_mounted;
static int nofid_fd;
static int fanotify_fd;
+static int at_handle_fid;
static int filesystem_mark_unsupported;
static char events_buf[BUF_SIZE];
static struct event_t event_set[EVENT_MAX];
@@ -113,8 +115,10 @@ static void get_object_stats(void)
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(objects); i++)
- fanotify_save_fid(objects[i].path, &objects[i].fid);
+ for (i = 0; i < ARRAY_SIZE(objects); i++) {
+ at_handle_fid |=
+ fanotify_save_fid(objects[i].path, &objects[i].fid);
+ }
}
static int setup_marks(unsigned int fd, struct test_case_t *tc)
@@ -154,8 +158,8 @@ static void do_test(unsigned int number)
return;
}
- if (filesystem_mark_unsupported && mark->flag & FAN_MARK_FILESYSTEM) {
- tst_res(TCONF, "FAN_MARK_FILESYSTEM not supported in kernel?");
+ if (filesystem_mark_unsupported && mark->flag != FAN_MARK_INODE) {
+ FANOTIFY_MARK_FLAGS_ERR_MSG(mark, filesystem_mark_unsupported);
return;
}
@@ -168,10 +172,10 @@ static void do_test(unsigned int number)
if (setup_marks(fanotify_fd, tc) != 0)
goto out;
- /* Variant #1: watching upper fs - open files on overlayfs */
- if (tst_variant == 1) {
+ /* Watching base fs - open files on overlayfs */
+ if (tst_variant && !ovl_bind_mounted) {
if (mark->flag & FAN_MARK_MOUNT) {
- tst_res(TCONF, "overlayfs upper fs cannot be watched with mount mark");
+ tst_res(TCONF, "overlayfs base fs cannot be watched with mount mark");
goto out;
}
SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
@@ -191,7 +195,7 @@ static void do_test(unsigned int number)
SAFE_CLOSE(fds[i]);
}
- if (tst_variant == 1)
+ if (tst_variant && !ovl_bind_mounted)
SAFE_UMOUNT(MOUNT_PATH);
/* Read events from event queue */
@@ -286,19 +290,27 @@ static void do_setup(void)
/*
* Bind mount to either base fs or to overlayfs over base fs:
* Variant #0: watch base fs - open files on base fs
- * Variant #1: watch upper fs - open files on overlayfs
+ * Variant #1: watch lower fs - open lower files on overlayfs
+ * Variant #2: watch upper fs - open upper files on overlayfs
+ * Variant #3: watch overlayfs - open lower files on overlayfs
+ * Variant #4: watch overlayfs - open upper files on overlayfs
*
- * Variant #1 tests a bug whose fix bc2473c90fca ("ovl: enable fsnotify
+ * Variants 1,2 test a bug whose fix bc2473c90fca ("ovl: enable fsnotify
* events on underlying real files") in kernel 6.5 is not likely to be
* backported to older kernels.
* To avoid waiting for events that won't arrive when testing old kernels,
- * require that kernel supports encoding fid with new flag AT_HADNLE_FID,
+ * require that kernel supports encoding fid with new flag AT_HANDLE_FID,
* also merged to 6.5 and not likely to be backported to older kernels.
+ * Variants 3,4 test overlayfs watch with FAN_REPORT_FID, which also
+ * requires kernel with support for AT_HANDLE_FID.
*/
if (tst_variant) {
REQUIRE_HANDLE_TYPE_SUPPORTED_BY_KERNEL(AT_HANDLE_FID);
ovl_mounted = TST_MOUNT_OVERLAY();
- mnt = OVL_UPPER;
+ if (!ovl_mounted)
+ return;
+
+ mnt = tst_variant & 1 ? OVL_LOWER : OVL_UPPER;
} else {
mnt = OVL_BASE_MNTPOINT;
@@ -308,13 +320,21 @@ static void do_setup(void)
SAFE_MOUNT(mnt, MOUNT_PATH, "none", MS_BIND, NULL);
bind_mounted = 1;
- filesystem_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_FILESYSTEM);
-
nofid_fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY);
- /* Create file and directory objects for testing */
+ /* Create file and directory objects for testing on base fs */
create_objects();
+ if (tst_variant > 2) {
+ /* Setup watches on overlayfs */
+ SAFE_MOUNT(OVL_MNT, MOUNT_PATH, "none", MS_BIND, NULL);
+ ovl_bind_mounted = 1;
+ }
+
+ filesystem_mark_unsupported =
+ fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
+ ovl_bind_mounted ? OVL_MNT : MOUNT_PATH);
+
/*
* Create a mark on first inode without FAN_REPORT_FID, to test
* uninitialized connector->fsid cache. This mark remains for all test
@@ -329,9 +349,12 @@ static void do_setup(void)
static void do_cleanup(void)
{
- SAFE_CLOSE(nofid_fd);
+ if (nofid_fd > 0)
+ SAFE_CLOSE(nofid_fd);
if (fanotify_fd > 0)
SAFE_CLOSE(fanotify_fd);
+ if (ovl_bind_mounted)
+ SAFE_UMOUNT(MOUNT_PATH);
if (bind_mounted) {
SAFE_UMOUNT(MOUNT_PATH);
SAFE_RMDIR(MOUNT_PATH);
@@ -343,7 +366,7 @@ static void do_cleanup(void)
static struct tst_test test = {
.test = do_test,
.tcnt = ARRAY_SIZE(test_cases),
- .test_variants = 2,
+ .test_variants = 5,
.setup = do_setup,
.cleanup = do_cleanup,
.needs_root = 1,
diff --git a/testcases/kernel/syscalls/fanotify/fanotify14.c b/testcases/kernel/syscalls/fanotify/fanotify14.c
index 4596511f0..0b0da89ca 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify14.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify14.c
@@ -45,8 +45,9 @@
static int pipes[2] = {-1, -1};
static int fanotify_fd;
-static int fan_report_target_fid_unsupported;
static int ignore_mark_unsupported;
+static int filesystem_mark_unsupported;
+static unsigned int supported_init_flags;
struct test_case_flags_t {
unsigned long long flags;
@@ -246,9 +247,8 @@ static void do_test(unsigned int number)
tst_res(TINFO, "Test case %d: fanotify_init(%s, O_RDONLY)", number,
tc->init.desc);
- if (fan_report_target_fid_unsupported && tc->init.flags & FAN_REPORT_TARGET_FID) {
- FANOTIFY_INIT_FLAGS_ERR_MSG(FAN_REPORT_TARGET_FID,
- fan_report_target_fid_unsupported);
+ if (tc->init.flags & ~supported_init_flags) {
+ tst_res(TCONF, "Unsupported init flags");
return;
}
@@ -300,7 +300,7 @@ static void do_test(unsigned int number)
"Adding an inode mark on directory did not fail with "
"ENOTDIR error as on non-dir inode");
- if (!(tc->mark.flags & FAN_MARK_ONLYDIR)) {
+ if (!(tc->mark.flags & FAN_MARK_ONLYDIR) && !filesystem_mark_unsupported) {
SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD | tc->mark.flags |
FAN_MARK_FILESYSTEM, tc->mask.flags,
AT_FDCWD, FILE1);
@@ -317,12 +317,18 @@ out:
static void do_setup(void)
{
+ unsigned int all_init_flags = FAN_REPORT_DFID_NAME_TARGET |
+ FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT;
+
/* Require FAN_REPORT_FID support for all tests to simplify per test case requirements */
REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, MNTPOINT);
+ supported_init_flags = fanotify_get_supported_init_flags(all_init_flags, MNTPOINT);
- fan_report_target_fid_unsupported =
- fanotify_init_flags_supported_on_fs(FAN_REPORT_DFID_NAME_TARGET, MNTPOINT);
- ignore_mark_unsupported = fanotify_mark_supported_by_kernel(FAN_MARK_IGNORE_SURV);
+ ignore_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_IGNORE_SURV,
+ MNTPOINT);
+ filesystem_mark_unsupported =
+ fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
+ MNTPOINT);
/* Create temporary test file to place marks on */
SAFE_FILE_PRINTF(FILE1, "0");
diff --git a/testcases/kernel/syscalls/fanotify/fanotify15.c b/testcases/kernel/syscalls/fanotify/fanotify15.c
index 6109d32cd..bacf05049 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify15.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify15.c
@@ -52,6 +52,7 @@ struct event_t {
};
static int fanotify_fd;
+static int filesystem_mark_unsupported;
static char events_buf[EVENT_BUF_LEN];
static struct event_t event_set[EVENT_MAX];
@@ -85,6 +86,11 @@ static void do_test(unsigned int number)
tst_res(TINFO, "Test #%d: %s", number, tc->tname);
+ if (filesystem_mark_unsupported && mark->flag != FAN_MARK_INODE) {
+ FANOTIFY_MARK_FLAGS_ERR_MSG(mark, filesystem_mark_unsupported);
+ return;
+ }
+
SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD | mark->flag, tc->mask |
FAN_CREATE | FAN_DELETE | FAN_MOVE |
FAN_MODIFY | FAN_ONDIR,
@@ -274,6 +280,10 @@ static void do_setup(void)
{
SAFE_MKDIR(TEST_DIR, 0755);
REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, TEST_DIR);
+ filesystem_mark_unsupported =
+ fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
+ MOUNT_POINT);
+
fanotify_fd = SAFE_FANOTIFY_INIT(FAN_REPORT_FID, O_RDONLY);
}
diff --git a/testcases/kernel/syscalls/fanotify/fanotify16.c b/testcases/kernel/syscalls/fanotify/fanotify16.c
index d45270a9a..6ab360984 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify16.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify16.c
@@ -70,6 +70,7 @@ static char event_buf[EVENT_BUF_LEN];
#define TEMP_DIR MOUNT_PATH "/temp_dir"
static int fan_report_target_fid_unsupported;
+static int filesystem_mark_unsupported;
static int rename_events_unsupported;
static struct test_case_t {
@@ -281,6 +282,16 @@ static void do_test(unsigned int number)
return;
}
+ if (filesystem_mark_unsupported) {
+ if (sub_mark && sub_mark->flag != FAN_MARK_INODE)
+ mark = sub_mark;
+
+ if (mark->flag != FAN_MARK_INODE) {
+ FANOTIFY_MARK_FLAGS_ERR_MSG(mark, filesystem_mark_unsupported);
+ return;
+ }
+ }
+
fd_notify = SAFE_FANOTIFY_INIT(group->flag, 0);
/*
@@ -328,7 +339,15 @@ static void do_test(unsigned int number)
tst_count++;
/* Generate modify events "on child" */
- fd = SAFE_CREAT(fname1, 0755);
+
+ /*
+ * Split SAFE_CREAT() into explicit SAFE_MKNOD() and SAFE_OPEN(),
+ * because with atomic open (e.g. fuse), SAFE_CREAT() generates
+ * FAN_OPEN before FAN_CREATE and it is inconsistent with the order
+ * of events expectated from other filesystems.
+ */
+ SAFE_MKNOD(fname1, S_IFREG | 0644, 0);
+ fd = SAFE_OPEN(fname1, O_WRONLY);
/* Save the file fid */
fanotify_save_fid(fname1, &file_fid);
@@ -765,8 +784,12 @@ static void setup(void)
REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_DIR_FID, MOUNT_PATH);
fan_report_target_fid_unsupported =
fanotify_init_flags_supported_on_fs(FAN_REPORT_DFID_NAME_TARGET, MOUNT_PATH);
+ filesystem_mark_unsupported =
+ fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
+ MOUNT_PATH);
rename_events_unsupported =
- fanotify_events_supported_by_kernel(FAN_RENAME, FAN_REPORT_DFID_NAME, 0);
+ fanotify_flags_supported_on_fs(FAN_REPORT_DFID_NAME, 0,
+ FAN_RENAME, MOUNT_PATH);
SAFE_MKDIR(TEMP_DIR, 0755);
sprintf(dname1, "%s/%s", MOUNT_PATH, DIR_NAME1);
diff --git a/testcases/kernel/syscalls/fanotify/fanotify20.c b/testcases/kernel/syscalls/fanotify/fanotify20.c
index 71310fb86..1d249ac9c 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify20.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify20.c
@@ -50,7 +50,8 @@ static void do_setup(void)
* An explicit check for FAN_REPORT_PIDFD is performed early on in the
* test initialization as it's a prerequisite for all test cases.
*/
- REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_BY_KERNEL(FAN_REPORT_PIDFD);
+ REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_PIDFD,
+ MOUNT_PATH);
}
static void do_test(unsigned int i)
diff --git a/testcases/kernel/syscalls/fanotify/fanotify21.c b/testcases/kernel/syscalls/fanotify/fanotify21.c
index 2b7202b8a..90a797fce 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify21.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify21.c
@@ -119,7 +119,8 @@ static void do_setup(void)
* on in the test initialization as it's a prerequisite for
* all test cases.
*/
- REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_BY_KERNEL(FAN_REPORT_PIDFD);
+ REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_PIDFD,
+ TEST_FILE);
fanotify_fd = SAFE_FANOTIFY_INIT(FAN_REPORT_PIDFD, O_RDONLY);
SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD, FAN_OPEN, AT_FDCWD,
diff --git a/testcases/kernel/syscalls/fanotify/fanotify23.c b/testcases/kernel/syscalls/fanotify/fanotify23.c
index fb812c51e..5a03503e9 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify23.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify23.c
@@ -230,7 +230,7 @@ static void setup(void)
{
SAFE_TOUCH(TEST_FILE, 0666, NULL);
- REQUIRE_MARK_TYPE_SUPPORTED_BY_KERNEL(FAN_MARK_EVICTABLE);
+ REQUIRE_MARK_TYPE_SUPPORTED_ON_FS(FAN_MARK_EVICTABLE, ".");
REQUIRE_FANOTIFY_EVENTS_SUPPORTED_ON_FS(FAN_CLASS_NOTIF|FAN_REPORT_FID,
FAN_MARK_FILESYSTEM,
FAN_ATTRIB, ".");
diff --git a/testcases/kernel/syscalls/fchmodat/.gitignore b/testcases/kernel/syscalls/fchmodat/.gitignore
index a9508bc5a..09d5c47d5 100644
--- a/testcases/kernel/syscalls/fchmodat/.gitignore
+++ b/testcases/kernel/syscalls/fchmodat/.gitignore
@@ -1 +1,2 @@
/fchmodat01
+/fchmodat02
diff --git a/testcases/kernel/syscalls/fchmodat/fchmodat01.c b/testcases/kernel/syscalls/fchmodat/fchmodat01.c
index 3deff0ebe..bf3812738 100644
--- a/testcases/kernel/syscalls/fchmodat/fchmodat01.c
+++ b/testcases/kernel/syscalls/fchmodat/fchmodat01.c
@@ -1,99 +1,82 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2006
- *
+ * Copyright (c) Linux Test Project, 2003-2023
* 08/28/2006 AUTHOR: Yi Yang <yyangcdl@cn.ibm.com>
*/
/*\
* [Description]
*
- * This test case will verify basic function of fchmodat.
+ * Check the basic functionality of the fchmodat() system call.
+ *
+ * - fchmodat() passes if dir_fd is file descriptor to the directory
+ * where the file is located and pathname is relative path of the file.
+ * - fchmodat() passes if pathname is absolute, then dirfd is ignored.
+ * - fchmodat() passes if dir_fd is AT_FDCWD and pathname is interpreted
+ * relative to the current working directory of the calling process.
*/
-#define _GNU_SOURCE
-
-#include <unistd.h>
-#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "tst_test.h"
-#include "lapi/syscalls.h"
-#ifndef AT_FDCWD
-#define AT_FDCWD -100
-#endif
+#define TESTDIR "fchmodatdir"
+#define TESTFILE "fchmodatfile"
+#define FILEPATH "fchmodatdir/fchmodatfile"
-static char pathname[256];
-static char testfile[256];
-static char testfile2[256];
-static char testfile3[256];
+static int dir_fd, file_fd;
+static int atcwd_fd = AT_FDCWD;
+static char *abs_path;
+static char *test_file;
+static char *file_path;
static struct tcase {
- int exp_errno;
- char *exp_errval;
+ int *fd;
+ char **filenames;
+ char **full_path;
} tcases[] = {
- { 0, NULL},
- { 0, NULL},
- { ENOTDIR, "ENOTDIR"},
- { EBADF, "EBADF"},
- { 0, NULL},
- { 0, NULL},
+ {&dir_fd, &test_file, &file_path},
+ {&file_fd, &abs_path, &abs_path},
+ {&atcwd_fd, &file_path, &file_path},
};
-static int fds[ARRAY_SIZE(tcases)];
-static char *filenames[ARRAY_SIZE(tcases)];
static void verify_fchmodat(unsigned int i)
{
struct tcase *tc = &tcases[i];
+ struct stat st;
- if (tc->exp_errno == 0)
- TST_EXP_PASS(tst_syscall(__NR_fchmodat, fds[i], filenames[i], 0600),
- "fchmodat() returned the expected errno %d: %s",
- TST_ERR, strerror(TST_ERR));
+ TST_EXP_PASS(fchmodat(*tc->fd, *tc->filenames, 0600, 0),
+ "fchmodat(%d, %s, 0600, 0)",
+ *tc->fd, *tc->filenames);
+
+ SAFE_LSTAT(*tc->full_path, &st);
+
+ if ((st.st_mode & ~S_IFREG) == 0600)
+ tst_res(TPASS, "File permission changed correctly");
else
- TST_EXP_FAIL(tst_syscall(__NR_fchmodat, fds[i], filenames[i], 0600),
- tc->exp_errno,
- "fchmodat() returned the expected errno %d: %s",
- TST_ERR, strerror(TST_ERR));
+ tst_res(TFAIL, "File permission not changed correctly");
}
static void setup(void)
{
- /* Initialize test dir and file names */
- char *abs_path = tst_get_tmpdir();
- int p = getpid();
-
- sprintf(pathname, "fchmodattestdir%d", p);
- sprintf(testfile, "fchmodattest%d.txt", p);
- sprintf(testfile2, "%s/fchmodattest%d.txt", abs_path, p);
- sprintf(testfile3, "fchmodattestdir%d/fchmodattest%d.txt", p, p);
+ char *tmpdir_path = tst_get_tmpdir();
- free(abs_path);
+ abs_path = tst_aprintf("%s/%s", tmpdir_path, FILEPATH);
+ free(tmpdir_path);
- SAFE_MKDIR(pathname, 0700);
-
- fds[0] = SAFE_OPEN(pathname, O_DIRECTORY);
- fds[1] = fds[4] = fds[0];
-
- SAFE_FILE_PRINTF(testfile, "%s", testfile);
- SAFE_FILE_PRINTF(testfile2, "%s", testfile2);
-
- fds[2] = SAFE_OPEN(testfile3, O_CREAT | O_RDWR, 0600);
- fds[3] = 100;
- fds[5] = AT_FDCWD;
-
- filenames[0] = filenames[2] = filenames[3] = filenames[4] = testfile;
- filenames[1] = testfile2;
- filenames[5] = testfile3;
+ SAFE_MKDIR(TESTDIR, 0700);
+ dir_fd = SAFE_OPEN(TESTDIR, O_DIRECTORY);
+ file_fd = SAFE_OPEN(FILEPATH, O_CREAT | O_RDWR, 0600);
}
static void cleanup(void)
{
- if (fds[0] > 0)
- close(fds[0]);
- if (fds[2] > 0)
- close(fds[2]);
+ if (dir_fd > -1)
+ SAFE_CLOSE(dir_fd);
+
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
}
static struct tst_test test = {
@@ -101,5 +84,10 @@ static struct tst_test test = {
.test = verify_fchmodat,
.setup = setup,
.cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&test_file, .str = TESTFILE},
+ {&file_path, .str = FILEPATH},
+ {},
+ },
.needs_tmpdir = 1,
};
diff --git a/testcases/kernel/syscalls/fchmodat/fchmodat02.c b/testcases/kernel/syscalls/fchmodat/fchmodat02.c
new file mode 100644
index 000000000..117865a8f
--- /dev/null
+++ b/testcases/kernel/syscalls/fchmodat/fchmodat02.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) International Business Machines Corp., 2006
+ * Copyright (c) Linux Test Project, 2003-2023
+ * Author: Yi Yang <yyangcdl@cn.ibm.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Tests basic error handling of the fchmodat() syscall.
+ *
+ * - fchmodat() fails with ENOTDIR if dir_fd is file descriptor
+ * to the file and pathname is relative path of the file.
+ * - fchmodat() fails with EBADF if dir_fd is invalid.
+ * - fchmodat() fails with EFAULT if pathname points outside
+ * the accessible address space.
+ * - fchmodat() fails with ENAMETOOLONG if path is too long.
+ * - fchmodat() fails with ENOENT if pathname does not exist.
+ * - fchmodat() fails with EINVAL if flag is invalid.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "tst_test.h"
+
+#define TESTFILE "fchmodatfile"
+
+static int file_fd;
+static int bad_fd = -1;
+static char path[PATH_MAX + 2];
+static char *long_path = path;
+static int fd_atcwd = AT_FDCWD;
+static char *bad_path;
+static char *test_path;
+static char *empty_path;
+
+static struct tcase {
+ int *fd;
+ char **filenames;
+ int flag;
+ int exp_errno;
+ const char *desc;
+} tcases[] = {
+ {&file_fd, &test_path, 0, ENOTDIR, "fd pointing to file"},
+ {&bad_fd, &test_path, 0, EBADF, "invalid fd"},
+ {&file_fd, &bad_path, 0, EFAULT, "invalid address"},
+ {&file_fd, &long_path, 0, ENAMETOOLONG, "pathname too long"},
+ {&file_fd, &empty_path, 0, ENOENT, "path is empty"},
+ {&fd_atcwd, &test_path, -1, EINVAL, "invalid flag"},
+};
+
+static void verify_fchmodat(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
+
+ TST_EXP_FAIL(fchmodat(*tc->fd, *tc->filenames, 0600, tc->flag),
+ tc->exp_errno, "fchmodat() with %s", tc->desc);
+}
+
+static void setup(void)
+{
+ file_fd = SAFE_OPEN(TESTFILE, O_CREAT | O_RDWR, 0600);
+
+ bad_path = tst_get_bad_addr(NULL);
+
+ memset(path, 'a', PATH_MAX + 2);
+}
+
+static void cleanup(void)
+{
+ if (file_fd > -1)
+ SAFE_CLOSE(file_fd);
+}
+
+static struct tst_test test = {
+ .test = verify_fchmodat,
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .cleanup = cleanup,
+ .bufs = (struct tst_buffers []) {
+ {&test_path, .str = TESTFILE},
+ {&empty_path, .str = ""},
+ {},
+ },
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/fchownat/fchownat.h b/testcases/kernel/syscalls/fchownat/fchownat.h
deleted file mode 100644
index 927cf929a..000000000
--- a/testcases/kernel/syscalls/fchownat/fchownat.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2014 Fujitsu Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef FCHOWNAT_H
-#define FCHOWNAT_H
-
-#include <sys/types.h>
-#include "config.h"
-#include "lapi/syscalls.h"
-
-
-#if !defined(HAVE_FCHOWNAT)
-static inline int fchownat(int dirfd, const char *filename, uid_t owner,
- gid_t group, int flags)
-{
- return tst_syscall(__NR_fchownat, dirfd, filename, owner, group, flags);
-}
-#endif
-
-
-#endif /* FCHOWNAT_H */
diff --git a/testcases/kernel/syscalls/fchownat/fchownat01.c b/testcases/kernel/syscalls/fchownat/fchownat01.c
index 3b29f1e75..7771c111a 100644
--- a/testcases/kernel/syscalls/fchownat/fchownat01.c
+++ b/testcases/kernel/syscalls/fchownat/fchownat01.c
@@ -34,7 +34,6 @@
#include "test.h"
#include "safe_macros.h"
-#include "fchownat.h"
#include "lapi/fcntl.h"
#define TESTFILE "testfile"
diff --git a/testcases/kernel/syscalls/fchownat/fchownat02.c b/testcases/kernel/syscalls/fchownat/fchownat02.c
index c39b0a919..6dd1e024e 100644
--- a/testcases/kernel/syscalls/fchownat/fchownat02.c
+++ b/testcases/kernel/syscalls/fchownat/fchownat02.c
@@ -31,7 +31,6 @@
#include <signal.h>
#include "test.h"
#include "safe_macros.h"
-#include "fchownat.h"
#include "lapi/fcntl.h"
#define TESTFILE "testfile"
diff --git a/testcases/kernel/syscalls/fcntl/Makefile b/testcases/kernel/syscalls/fcntl/Makefile
index df663a50a..aac774111 100644
--- a/testcases/kernel/syscalls/fcntl/Makefile
+++ b/testcases/kernel/syscalls/fcntl/Makefile
@@ -17,6 +17,6 @@ include $(abs_srcdir)/../utils/newer_64.mk
%_64: CPPFLAGS += -D_FILE_OFFSET_BITS=64
-CPPFLAGS += -D_GNU_SOURCE
+CPPFLAGS += -D_GNU_SOURCE -D_LARGEFILE64_SOURCE
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/fork/.gitignore b/testcases/kernel/syscalls/fork/.gitignore
index b817e9c05..acab5f768 100644
--- a/testcases/kernel/syscalls/fork/.gitignore
+++ b/testcases/kernel/syscalls/fork/.gitignore
@@ -2,12 +2,10 @@
/fork03
/fork04
/fork05
-/fork06
/fork07
/fork08
/fork09
/fork10
-/fork11
-/fork12
/fork13
/fork14
+/fork_procs
diff --git a/testcases/kernel/syscalls/fork/fork04.c b/testcases/kernel/syscalls/fork/fork04.c
index 5e5e42c4e..1a515987e 100644
--- a/testcases/kernel/syscalls/fork/fork04.c
+++ b/testcases/kernel/syscalls/fork/fork04.c
@@ -1,328 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2001-2023
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ *[Description]
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
- *
- * OS Test - Silicon Graphics, Inc.
- * TEST IDENTIFIER : fork04
- * TEST TITLE : Child inheritance of Environment Variables after fork()
- * PARENT DOCUMENT : frktds01
- * TEST CASE TOTAL : 3
- * WALL CLOCK TIME : 1
- * CPU TYPES : ALL
- * AUTHOR : Kathy Olmsted
- * CO-PILOT : Steve Shaw
- * DATE STARTED : 06/17/92
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- * Test these environment variables correctly inherited by child:
- * 1. TERM
- * 2. NoTSetzWq
- * 3. TESTPROG
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * DETAILED DESCRIPTION
- *
- * Setup:
- * Setup signal handling.
- * Make and change to a temporary directory.
- * Pause for SIGUSR1 if option specified.
- * Add TESTPROG variable to the environment
- *
- * Test:
- * Loop if the proper options are given.
- * fork()
- * Check return code, if system call failed (return=-1)
- * Log the errno
- * CHILD:
- * open a temp file
- * Determine environment values and write to file
- * close file containing test values.
- * exit.
- * PARENT:
- * Wait for child to exit.
- * Verify exit status
- * Open file containing test values.
- * For each test case:
- * Read the value from the file.
- * Determine and report PASS/FAIL result.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Remove the temporary directory and exit.
+ * This test verifies that parent process shares environ variables with the
+ * child and that child doesn't change parent's environ variables.
*/
#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/param.h>
-#include <signal.h>
-#include <errno.h>
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "fork04";
-
-#define KIDEXIT 42
-#define MAX_LINE_LENGTH 256
-#define OUTPUT_FILE "env.out"
-#define ENV_NOT_SET "getenv() does not find variable set"
+#include "tst_test.h"
-/* list of environment variables to test */
-char *environ_list[] = { "TERM", "NoTSetzWq", "TESTPROG" };
+#define ENV_KEY "LTP_FORK04"
+#define ENV_VAL0 "PASS"
+#define ENV_VAL1 "FAIL"
-#define NUMBER_OF_ENVIRON (sizeof(environ_list)/sizeof(char *))
-int TST_TOTAL = NUMBER_OF_ENVIRON;
-
-static void cleanup(void)
+static void run_child(void)
{
- tst_rmdir();
-}
+ const char *val;
-static void setup(void)
-{
+ val = getenv(ENV_KEY);
+ if (!val)
+ tst_brk(TBROK, "Can't find %s environ variable", ENV_KEY);
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
- tst_tmpdir();
+ TST_EXP_EXPR(strcmp(ENV_VAL0, val) == 0,
+ "%s environ variable has been inherited by the child",
+ ENV_KEY)
- /* add a variable to the environment */
- putenv("TESTPROG=FRKTCS04");
-}
+ tst_res(TINFO, "Unset %s environ variable inside child", ENV_KEY);
-static void child_environment(void)
-{
-
- int fildes;
- int index;
- char msg[MAX_LINE_LENGTH];
- char *var;
+ if (unsetenv(ENV_KEY) == -1)
+ tst_brk(TBROK, "Can't unset %s environ variable", ENV_KEY);
- fildes = creat(OUTPUT_FILE, 0700);
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
- for (index = 0; index < (int)NUMBER_OF_ENVIRON; index++) {
- memset(msg, 0, MAX_LINE_LENGTH);
+ tst_res(TINFO, "Set %s=%s environ variable inside child", ENV_KEY, ENV_VAL1);
- var = getenv(environ_list[index]);
- if (var == NULL)
- (void)sprintf(msg, "%s:%s", environ_list[index],
- ENV_NOT_SET);
- else
- (void)sprintf(msg, "%s:%s", environ_list[index], var);
- /* includes extra null chars */
- write(fildes, msg, sizeof(msg));
- }
+ SAFE_SETENV(ENV_KEY, ENV_VAL1, 0);
- close(fildes);
+ TST_CHECKPOINT_WAKE(0);
}
-/*
- * Compare parent env string to child's string.
- * Each string is in the format: <env var>:<value>
- */
-static int cmp_env_strings(char *pstring, char *cstring)
+static void run(void)
{
- char *penv, *cenv, *pvalue, *cvalue;
+ const char *val;
- /*
- * Break pstring into env and value
- */
- penv = pstring;
- pvalue = strchr(pstring, ':');
- if (pvalue == NULL) {
- tst_resm(TBROK,
- "internal error - parent's env string not in correct format:'%s'",
- pstring);
- return -1;
- } else {
- *pvalue = '\0';
- pvalue++;
- if (*pvalue == '\0') {
- tst_resm(TBROK,
- "internal error - missing parent's env value");
- return -1;
- }
- }
+ tst_res(TINFO,
+ "Set %s=%s environ variable inside parent",
+ ENV_KEY, ENV_VAL0);
- /*
- * Break cstring into env and value
- */
- cenv = cstring;
- cvalue = strchr(cstring, ':');
- if (cvalue == NULL) {
- tst_resm(TBROK,
- "internal error - parent's env string not in correct format:'%s'",
- cstring);
- return -1;
- } else {
- *cvalue = '\0';
- cvalue++;
- if (*cvalue == '\0') {
- tst_resm(TBROK,
- "internal error - missing child's env value");
- return -1;
- }
- }
+ SAFE_SETENV(ENV_KEY, ENV_VAL0, 0);
- if (strcmp(penv, cenv) != 0) {
- tst_resm(TBROK, "internal error - parent(%s) != child (%s) env",
- penv, cenv);
- return -1;
- }
+ tst_res(TINFO, "Spawning child");
- if (strcmp(pvalue, cvalue) != 0) {
- tst_resm(TFAIL,
- "Env var %s changed after fork(), parent's %s, child's %s",
- penv, pvalue, cvalue);
- } else {
- tst_resm(TPASS, "Env var %s unchanged after fork(): %s",
- penv, cvalue);
+ if (!SAFE_FORK()) {
+ run_child();
+ exit(0);
}
- return 0;
-
-}
-
-/***************************************************************
- * parent_environment - the parent side of the environment tests
- * determine values for the variables
- * read the values determined by the child
- * compare values
- ***************************************************************/
-void parent_environment(void)
-{
-
- int fildes;
- char tmp_line[MAX_LINE_LENGTH];
- char parent_value[MAX_LINE_LENGTH];
- unsigned int index;
- int ret;
- char *var;
-
- fildes = SAFE_OPEN(cleanup, OUTPUT_FILE, O_RDWR);
- for (index = 0; index < NUMBER_OF_ENVIRON; index++) {
- ret = read(fildes, tmp_line, MAX_LINE_LENGTH);
- if (ret == 0) {
- tst_resm(TBROK,
- "fork() test. parent_environment: failed to read from file with %d (%s)",
- errno, strerror(errno));
- } else {
- var = getenv(environ_list[index]);
- if (var == NULL)
- sprintf(parent_value, "%s:%s",
- environ_list[index], ENV_NOT_SET);
- else
- sprintf(parent_value, "%s:%s",
- environ_list[index], var);
+ TST_CHECKPOINT_WAIT(0);
- cmp_env_strings(parent_value, tmp_line);
-
- }
+ val = getenv(ENV_KEY);
+ if (!val) {
+ tst_res(TFAIL,
+ "%s environ variable has been unset inside parent",
+ ENV_KEY);
+ } else {
+ TST_EXP_EXPR(strcmp(ENV_VAL0, val) == 0,
+ "%s environ variable is still present inside parent",
+ ENV_KEY)
}
- close(fildes);
-}
-
-int main(int ac, char **av)
-{
- int lc;
- int kid_status;
- int wait_status;
- int fails;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- fails = 0;
-
- TEST(fork());
-
- if (TEST_RETURN == -1) {
- /* fork failed */
- tst_brkm(TFAIL, cleanup,
- "fork() failed with %d (%s)",
- TEST_ERRNO, strerror(TEST_ERRNO));
- } else if (TEST_RETURN == 0) {
- /* child */
- /* determine environment variables */
- child_environment();
- /* exit with known value */
- exit(KIDEXIT);
- } else {
- /* parent of successful fork */
- /* wait for the child to complete */
- wait_status = waitpid(TEST_RETURN, &kid_status, 0);
- /* validate the child exit status */
- if (wait_status == TEST_RETURN) {
- if (kid_status != KIDEXIT << 8) {
- tst_brkm(TBROK, cleanup,
- "fork(): Incorrect child status returned on wait(): %d",
- kid_status);
- fails++;
- }
- } else {
- tst_brkm(TBROK, cleanup,
- "fork(): wait() for child status failed with %d errno: %d : %s",
- wait_status, errno,
- strerror(errno));
- fails++;
- }
-
- if (fails == 0) {
- /* verification tests */
- parent_environment();
- }
- }
-
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ val = getenv(ENV_KEY);
+ if (!val)
+ tst_res(TFAIL,
+ "%s environ variable has been unset inside parent",
+ ENV_KEY);
+ else {
+ TST_EXP_EXPR(strcmp(ENV_VAL0, val) == 0,
+ "%s environ variable didn't change inside parent",
+ ENV_KEY)
}
-
- cleanup();
- tst_exit();
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
diff --git a/testcases/kernel/syscalls/fork/fork06.c b/testcases/kernel/syscalls/fork/fork06.c
deleted file mode 100644
index 3bc11b14b..000000000
--- a/testcases/kernel/syscalls/fork/fork06.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * NAME
- * fork06.c
- *
- * DESCRIPTION
- * Test that a process can fork children a large number of
- * times in succession
- *
- * ALGORITHM
- * Attempt to fork a child that exits immediately
- * Repeat it many times(1000), counting the number of successes and
- * failures
- *
- * USAGE
- * fork06
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include "test.h"
-
-char *TCID = "fork06";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
-
-#define NUMFORKS 1000
-
-int main(int ac, char **av)
-{
- int i, pid, status, childpid, succeed, fail;
-
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- succeed = 0;
- fail = 0;
-
- for (i = 0; i < NUMFORKS; i++) {
- pid = fork();
- if (pid == -1) {
- fail++;
- continue;
- }
-
- if (pid == 0)
- _exit(0);
-
- childpid = wait(&status);
- if (pid != childpid)
- tst_resm(TFAIL, "pid from wait %d", childpid);
- succeed++;
- }
-
- tst_resm(TINFO, "tries %d", i);
- tst_resm(TINFO, "successes %d", succeed);
- tst_resm(TINFO, "failures %d", fail);
-
- if ((wait(&status)) == -1)
- tst_resm(TINFO, "There were no children to wait for");
- else
- tst_resm(TINFO, "There were children left");
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
diff --git a/testcases/kernel/syscalls/fork/fork10.c b/testcases/kernel/syscalls/fork/fork10.c
index 815eee1f6..790e7b386 100644
--- a/testcases/kernel/syscalls/fork/fork10.c
+++ b/testcases/kernel/syscalls/fork/fork10.c
@@ -1,159 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *
- * NAME
- * fork10.c
- *
- * DESCRIPTION
- * Check inheritance of file descriptor by children, they
- * should all be refering to the same file.
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
*
- * ALGORITHM
- * Child reads several chars and exits.
- * Parent forks another child, have the child and parent attempt to use
- * that location
+ * This test verifies inheritance of file descriptors from parent to child
+ * process. We open a file from parent, then we check if file offset changes
+ * accordingly with file descriptor usage.
*
- * USAGE
- * fork10
+ * [Algorithm]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * Test steps are the following:
+ * - create a file made in three parts -> | aa..a | bb..b | cc..c |
+ * - from parent, open the file
+ * - from child, move file offset after the first part
+ * - from parent, read second part and check if it's | bb..b |
+ * - from child, read third part and check if it's | cc..c |
*
- * RESTRICTIONS
- * None
+ * Test passes if we were able to read the correct file parts from parent and
+ * child.
*/
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <errno.h>
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "fork10";
-int TST_TOTAL = 1;
+#include <stdlib.h>
+#include "tst_test.h"
-static void setup(void);
-static void cleanup(void);
+#define FILENAME "file.txt"
+#define DATASIZE 1024
-static char pidbuf[10];
-static char fnamebuf[40];
+static int fd = -1;
-int main(int ac, char **av)
+static void run(void)
{
- int status, pid, fildes;
- char parchar[2];
- char chilchar[2];
-
- int lc;
-
- fildes = -1;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- fildes = SAFE_CREAT(cleanup, fnamebuf, 0600);
- write(fildes, "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 27);
- close(fildes);
-
- fildes = SAFE_OPEN(cleanup, fnamebuf, 0);
-
- pid = fork();
- if (pid == -1)
- tst_brkm(TBROK, cleanup, "fork() #1 failed");
-
- if (pid == 0) { /* child */
- tst_resm(TINFO, "fork child A");
- if (lseek(fildes, 10L, 0) == -1L) {
- tst_resm(TFAIL, "bad lseek by child");
- exit(1);
- }
- exit(0);
- } else { /* parent */
- wait(&status);
-
- /* parent starts second child */
- pid = fork();
- if (pid == -1)
- tst_brkm(TBROK, cleanup, "fork() #2 failed");
-
- if (pid == 0) { /* child */
- if (read(fildes, chilchar, 1) <= 0) {
- tst_resm(TFAIL, "Child can't read "
- "file");
- exit(1);
- } else {
- if (chilchar[0] != 'K') {
- chilchar[1] = '\n';
- exit(1);
- } else {
- exit(0);
- }
- }
- } else { /* parent */
- (void)wait(&status);
- if (status >> 8 != 0) {
- tst_resm(TFAIL, "Bad return from "
- "second child");
- continue;
- }
- /* parent reads */
- if (read(fildes, parchar, 1) <= 0) {
- tst_resm(TFAIL, "Parent cannot read "
- "file");
- continue;
- } else {
- write(fildes, parchar, 1);
- if (parchar[0] != 'L') {
- parchar[1] = '\n';
- tst_resm(TFAIL, "Test failed");
- continue;
- }
- }
- }
- }
- tst_resm(TPASS, "test 1 PASSED");
+ int status;
+ char buff[DATASIZE];
+ char data[DATASIZE];
+
+ fd = SAFE_OPEN(FILENAME, 0);
+
+ if (!SAFE_FORK()) {
+ SAFE_LSEEK(fd, DATASIZE, SEEK_SET);
+ exit(0);
+ }
+
+ SAFE_WAIT(&status);
+
+ memset(buff, 'b', DATASIZE);
+ SAFE_READ(1, fd, data, DATASIZE);
+
+ TST_EXP_EXPR(strncmp(buff, data, DATASIZE) == 0,
+ "read first part of data from parent process");
+
+ if (!SAFE_FORK()) {
+ memset(buff, 'c', DATASIZE);
+ SAFE_READ(1, fd, data, DATASIZE);
+
+ TST_EXP_EXPR(strncmp(buff, data, DATASIZE) == 0,
+ "read second part of data from child process");
+
+ exit(0);
}
- close(fildes);
- cleanup();
- tst_exit();
+ SAFE_CLOSE(fd);
}
static void setup(void)
{
- tst_sig(FORK, DEF_HANDLER, cleanup);
- umask(0);
- TEST_PAUSE;
- tst_tmpdir();
-
- strcpy(fnamebuf, "fork10.");
- sprintf(pidbuf, "%d", getpid());
- strcat(fnamebuf, pidbuf);
+ char buff[DATASIZE];
+
+ fd = SAFE_CREAT(FILENAME, 0600);
+
+ memset(buff, 'a', DATASIZE);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
+
+ memset(buff, 'b', DATASIZE);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
+
+ memset(buff, 'c', DATASIZE);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, buff, DATASIZE);
+
+ SAFE_CLOSE(fd);
}
static void cleanup(void)
{
- tst_rmdir();
+ if (fd >= 0)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .forks_child = 1,
+ .needs_tmpdir = 1,
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/fork/fork11.c b/testcases/kernel/syscalls/fork/fork11.c
deleted file mode 100644
index 6afda3a33..000000000
--- a/testcases/kernel/syscalls/fork/fork11.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *
- * NAME
- * fork11.c
- *
- * DESCRIPTION
- * Test that parent gets a pid from each child when doing wait
- *
- * ALGORITHM
- * Fork NUMFORKS children that do nothing.
- *
- * USAGE
- * fork11
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * None
- */
-
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <errno.h>
-#include "test.h"
-
-char *TCID = "fork11";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
-
-#define NUMFORKS 100
-
-int main(int ac, char **av)
-{
- int i, pid, cpid, status;
- int fail = 0;
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- for (i = 0; i < NUMFORKS; i++) {
- pid = fork();
- if (pid == 0)
- exit(0);
-
- if (pid > 0) { /* parent */
- cpid = wait(&status);
- if (cpid != pid)
- fail++;
- } else {
- fail++;
- break;
- }
- }
- if (fail)
- tst_resm(TFAIL, "fork failed %d times", fail);
- else
- tst_resm(TPASS, "fork test passed, %d processes", i);
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
-}
diff --git a/testcases/kernel/syscalls/fork/fork12.c b/testcases/kernel/syscalls/fork/fork12.c
deleted file mode 100644
index 1c55c0c30..000000000
--- a/testcases/kernel/syscalls/fork/fork12.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *
- * NAME
- * fork12.c
- *
- * DESCRIPTION
- * Check that all children inherit parent's file descriptor
- *
- * ALGORITHM
- * Parent forks processes until -1 is returned.$
- *
- * USAGE
- * fork12
- * ** CAUTION ** Can hang your machine, esp prior to 2.4.19
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- * 07/2002 Split from fork07 as a test case to exhaust available pids.
- *
- * RESTRICTIONS
- * Should be run as root to avoid resource limits.$
- * Should not be run with other test programs because it tries to
- * use all available pids.
- */
-
-#include <stdio.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <string.h>
-#include "test.h"
-#include "safe_macros.h"
-
-char *TCID = "fork12";
-int TST_TOTAL = 1;
-
-static void setup(void);
-static void cleanup(void);
-static void fork12_sigs(int signum);
-
-int main(int ac, char **av)
-{
- int forks, pid1, fork_errno, waitstatus;
- int ret, status;
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- tst_resm(TINFO, "Forking as many kids as possible");
- forks = 0;
- while ((pid1 = fork()) != -1) {
- if (pid1 == 0) { /* child */
- /*
- * Taunt the OOM killer so that it doesn't
- * kill system processes
- */
- SAFE_FILE_PRINTF(NULL,
- "/proc/self/oom_score_adj", "500");
- pause();
- exit(0);
- }
- forks++;
- ret = SAFE_WAITPID(cleanup, -1, &status, WNOHANG);
- if (ret > 0) {
- /* a child may be killed by OOM killer */
- if (WTERMSIG(status) == SIGKILL)
- break;
- tst_brkm(TBROK, cleanup,
- "child exit with error code %d or signal %d",
- WEXITSTATUS(status), WTERMSIG(status));
- }
- }
- fork_errno = errno;
-
- /* parent */
- tst_resm(TINFO, "Number of processes forked is %d", forks);
- tst_resm(TPASS, "fork() eventually failed with %d: %s",
- fork_errno, strerror(fork_errno));
- /* collect our kids */
- /*
- * Introducing a sleep(3) to make sure all children are
- * at pause() when SIGQUIT is sent to them
- */
- sleep(3);
- kill(0, SIGQUIT);
- while (wait(&waitstatus) > 0) ;
-
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(FORK, fork12_sigs, cleanup);
- TEST_PAUSE;
-}
-
-static void cleanup(void)
-{
- int waitstatus;
-
- /* collect our kids */
- kill(0, SIGQUIT);
- while (wait(&waitstatus) > 0) ;
-}
-
-static void fork12_sigs(int signum)
-{
- if (signum == SIGQUIT) {
- /* Children will continue, parent will ignore */
- } else {
- tst_brkm(TBROK, cleanup,
- "Unexpected signal %d received.", signum);
- }
-}
diff --git a/testcases/kernel/syscalls/fork/fork_procs.c b/testcases/kernel/syscalls/fork/fork_procs.c
new file mode 100644
index 000000000..c35bb480c
--- /dev/null
+++ b/testcases/kernel/syscalls/fork/fork_procs.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ *[Description]
+ *
+ * This test spawns multiple processes using fork() and it checks if wait()
+ * returns the right PID once they end up.
+ */
+
+#include <stdlib.h>
+#include "tst_test.h"
+
+static char *str_numforks;
+static int numforks = 1000;
+
+static void run(void)
+{
+ pid_t pid;
+ int status;
+ int counter = 0;
+
+ tst_res(TINFO, "Forking %d processes", numforks);
+
+ for (int i = 0; i < numforks; i++) {
+ pid = SAFE_FORK();
+ if (!pid)
+ exit(0);
+
+ if (SAFE_WAIT(&status) == pid)
+ counter++;
+ }
+
+ TST_EXP_EXPR(numforks == counter,
+ "%d processes ended successfully",
+ counter);
+}
+
+static void setup(void)
+{
+ if (tst_parse_int(str_numforks, &numforks, 1, INT_MAX))
+ tst_brk(TBROK, "wrong number of forks '%s'", str_numforks);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .forks_child = 1,
+ .options = (struct tst_option[]) {
+ { "n:", &str_numforks, "Number of processes to spawn" },
+ {},
+ },
+};
diff --git a/testcases/kernel/syscalls/fsetxattr/fsetxattr01.c b/testcases/kernel/syscalls/fsetxattr/fsetxattr01.c
index d799e477f..b65b27bdf 100644
--- a/testcases/kernel/syscalls/fsetxattr/fsetxattr01.c
+++ b/testcases/kernel/syscalls/fsetxattr/fsetxattr01.c
@@ -140,7 +140,7 @@ static void verify_fsetxattr(unsigned int i)
{
/* some tests might require existing keys for each iteration */
if (tc[i].keyneeded) {
- SAFE_FSETXATTR(fd, tc[i].key, tc[i].value, tc[i].size,
+ SAFE_FSETXATTR(fd, tc[i].key, *tc[i].value, tc[i].size,
XATTR_CREATE);
}
diff --git a/testcases/kernel/syscalls/fsetxattr/fsetxattr02.c b/testcases/kernel/syscalls/fsetxattr/fsetxattr02.c
index 0336c964a..39265af36 100644
--- a/testcases/kernel/syscalls/fsetxattr/fsetxattr02.c
+++ b/testcases/kernel/syscalls/fsetxattr/fsetxattr02.c
@@ -1,27 +1,33 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2018 Linaro Limited. All rights reserved.
+ * Copyright (c) Linux Test Project, 2018-2023
* Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
*/
+/*\
+ * [Description]
+ *
+ * Verify basic fsetxattr(2) syscall functionality:
+ *
+ * - Set attribute to a regular file, fsetxattr(2) should succeed.
+ * - Set attribute to a directory, fsetxattr(2) should succeed.
+ * - Set attribute to a symlink which points to the regular file,
+ * fsetxattr(2) should return -1 and set errno to EEXIST.
+ * - Set attribute to a FIFO, fsetxattr(2) should return -1 and set
+ * errno to EPERM.
+ * - Set attribute to a char special file, fsetxattr(2) should
+ * return -1 and set errno to EPERM.
+ * - Set attribute to a block special file, fsetxattr(2) should
+ * return -1 and set errno to EPERM.
+ * - Set attribute to a UNIX domain socket, fsetxattr(2) should
+ * return -1 and set errno to EPERM.
+ */
+
/*
* In the user.* namespace, only regular files and directories can
* have extended attributes. Otherwise fsetxattr(2) will return -1
* and set errno to EPERM.
- *
- * There are 7 test cases:
- * 1. Set attribute to a regular file, fsetxattr(2) should succeed
- * 2. Set attribute to a directory, fsetxattr(2) should succeed
- * 3. Set attribute to a symlink which points to the regular file,
- * fsetxattr(2) should return -1 and set errno to EEXIST
- * 4. Set attribute to a FIFO, fsetxattr(2) should return -1 and set
- * errno to EPERM
- * 5. Set attribute to a char special file, fsetxattr(2) should
- * return -1 and set errno to EPERM
- * 6. Set attribute to a block special file, fsetxattr(2) should
- * return -1 and set errno to EPERM
- * 7. Set attribute to a UNIX domain socket, fsetxattr(2) should
- * return -1 and set errno to EPERM
*/
#include "config.h"
diff --git a/testcases/kernel/syscalls/getcwd/getcwd01.c b/testcases/kernel/syscalls/getcwd/getcwd01.c
index 65d827873..218bf4ef2 100644
--- a/testcases/kernel/syscalls/getcwd/getcwd01.c
+++ b/testcases/kernel/syscalls/getcwd/getcwd01.c
@@ -14,17 +14,17 @@
*
* Expected Result:
* 1) getcwd(2) should return NULL and set errno to EFAULT.
- * 2) getcwd(2) should return NULL and set errno to ENOMEM.
- * 3) getcwd(2) should return NULL and set errno to EINVAL.
+ * 2) getcwd(2) should return NULL and set errno to EFAULT.
+ * 3) getcwd(2) should return NULL and set errno to ERANGE.
* 4) getcwd(2) should return NULL and set errno to ERANGE.
* 5) getcwd(2) should return NULL and set errno to ERANGE.
- *
*/
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include "tst_test.h"
+#include "lapi/syscalls.h"
static char buffer[5];
@@ -34,32 +34,18 @@ static struct t_case {
int exp_err;
} tcases[] = {
{(void *)-1, PATH_MAX, EFAULT},
- {NULL, (size_t)-1, ENOMEM},
- {buffer, 0, EINVAL},
+ {NULL, (size_t)-1, EFAULT},
+ {buffer, 0, ERANGE},
{buffer, 1, ERANGE},
{NULL, 1, ERANGE}
};
+
static void verify_getcwd(unsigned int n)
{
struct t_case *tc = &tcases[n];
- char *res;
-
- errno = 0;
- res = getcwd(tc->buf, tc->size);
- TST_ERR = errno;
- if (res) {
- tst_res(TFAIL, "getcwd() succeeded unexpectedly");
- return;
- }
-
- if (TST_ERR != tc->exp_err) {
- tst_res(TFAIL | TTERRNO, "getcwd() failed unexpectedly, expected %s",
- tst_strerrno(tc->exp_err));
- return;
- }
- tst_res(TPASS | TTERRNO, "getcwd() failed as expected");
+ TST_EXP_FAIL2(tst_syscall(__NR_getcwd, tc->buf, tc->size), tc->exp_err);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/getcwd/getcwd02.c b/testcases/kernel/syscalls/getcwd/getcwd02.c
index cb111a698..e3df22ceb 100644
--- a/testcases/kernel/syscalls/getcwd/getcwd02.c
+++ b/testcases/kernel/syscalls/getcwd/getcwd02.c
@@ -3,12 +3,14 @@
* Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * DESCRIPTION
+/*\
+ * [Description]
+ *
* Testcase to check the basic functionality of the getcwd(2) system call.
- * 1) getcwd(2) works fine if buf and size are valid.
- * 2) getcwd(2) works fine if buf points to NULL and size is set to 0.
- * 3) getcwd(2) works fine if buf points to NULL and size is greater than strlen(path).
+ *
+ * 1. getcwd(2) works fine if buf and size are valid.
+ * 2. getcwd(2) works fine if buf points to NULL and size is set to 0.
+ * 3. getcwd(2) works fine if buf points to NULL and size is greater than strlen(path).
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/getcwd/getcwd03.c b/testcases/kernel/syscalls/getcwd/getcwd03.c
index 97f4f3a33..9e3828a93 100644
--- a/testcases/kernel/syscalls/getcwd/getcwd03.c
+++ b/testcases/kernel/syscalls/getcwd/getcwd03.c
@@ -3,18 +3,20 @@
* Copyright (c) International Business Machines Corp., 2001
*/
-/*
- * DESCRIPTION
+/*\
+ * [Description]
+ *
* Testcase to check the basic functionality of the getcwd(2)
* system call on a symbolic link.
*
- * ALGORITHM
- * 1) create a directory, and create a symbolic link to it at the
+ * [Algorithm]
+ *
+ * 1. create a directory, and create a symbolic link to it at the
* same directory level.
- * 2) get the working directory of a directory, and its pathname.
- * 3) get the working directory of a symbolic link, and its pathname,
+ * 2. get the working directory of a directory, and its pathname.
+ * 3. get the working directory of a symbolic link, and its pathname,
* and its readlink info.
- * 4) compare the working directories and link information.
+ * 4. compare the working directories and link information.
*/
#define _GNU_SOURCE 1
diff --git a/testcases/kernel/syscalls/getdtablesize/.gitignore b/testcases/kernel/syscalls/getdtablesize/.gitignore
deleted file mode 100644
index 67a71b5e2..000000000
--- a/testcases/kernel/syscalls/getdtablesize/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/getdtablesize01
diff --git a/testcases/kernel/syscalls/getdtablesize/Makefile b/testcases/kernel/syscalls/getdtablesize/Makefile
deleted file mode 100644
index 044619fb8..000000000
--- a/testcases/kernel/syscalls/getdtablesize/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) International Business Machines Corp., 2001
-
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/getdtablesize/getdtablesize01.c b/testcases/kernel/syscalls/getdtablesize/getdtablesize01.c
deleted file mode 100644
index d25cac261..000000000
--- a/testcases/kernel/syscalls/getdtablesize/getdtablesize01.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2005
- * Copyright (c) Wipro Technologies Ltd, 2005. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-/**********************************************************
- *
- * TEST IDENTIFIER : getdtablesize01
- *
- * EXECUTED BY : root / superuser
- *
- * TEST TITLE : Basic tests for getdtablesize01(2)
- *
- * TEST CASE TOTAL : 1
- *
- * AUTHOR : Prashant P Yendigeri
- * <prashant.yendigeri@wipro.com>
- * Robbie Williamson
- * <robbiew@us.ibm.com>
- *
- * DESCRIPTION
- * This is a Phase I test for the getdtablesize01(2) system call.
- * It is intended to provide a limited exposure of the system call.
- *
- **********************************************************/
-
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <unistd.h>
-#include "test.h"
-
-void setup();
-void cleanup();
-
-char *TCID = "getdtablesize01";
-int TST_TOTAL = 1;
-
-int main(void)
-{
- int table_size, fd = 0, count = 0;
- int max_val_opfiles;
- struct rlimit rlp;
-
- setup();
- table_size = getdtablesize();
- getrlimit(RLIMIT_NOFILE, &rlp);
- max_val_opfiles = (rlim_t) rlp.rlim_cur;
-
- tst_resm(TINFO,
- "Maximum number of files a process can have opened is %d",
- table_size);
- tst_resm(TINFO,
- "Checking with the value returned by getrlimit...RLIMIT_NOFILE");
-
- if (table_size == max_val_opfiles)
- tst_resm(TPASS, "got correct dtablesize, value is %d",
- max_val_opfiles);
- else {
- tst_resm(TFAIL, "got incorrect table size, value is %d",
- max_val_opfiles);
- cleanup();
- }
-
- tst_resm(TINFO,
- "Checking Max num of files that can be opened by a process.Should be: RLIMIT_NOFILE - 1");
- for (;;) {
- fd = open("/etc/hosts", O_RDONLY);
-
- if (fd == -1)
- break;
- count = fd;
-
-#ifdef DEBUG
- printf("Opened file num %d\n", fd);
-#endif
- }
-
-//Now the max files opened should be RLIMIT_NOFILE - 1 , why ? read getdtablesize man page
-
- if (count > 0)
- close(count);
- if (count == (max_val_opfiles - 1))
- tst_resm(TPASS, "%d = %d", count, (max_val_opfiles - 1));
- else if (fd < 0 && errno == ENFILE)
- tst_brkm(TCONF, cleanup, "Reached maximum number of open files for the system");
- else
- tst_resm(TFAIL, "%d != %d", count, (max_val_opfiles - 1));
-
- cleanup();
- tst_exit();
-}
-
-void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-}
-
-void cleanup(void)
-{
-}
diff --git a/testcases/kernel/syscalls/getegid/getegid01.c b/testcases/kernel/syscalls/getegid/getegid01.c
index 271fbb6b6..46cdc680b 100644
--- a/testcases/kernel/syscalls/getegid/getegid01.c
+++ b/testcases/kernel/syscalls/getegid/getegid01.c
@@ -1,87 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * William Roske, Dave Fenner
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * AUTHOR : William Roske
- * CO-PILOT : Dave Fenner
+/*\
+ * [Description]
+ *
+ * This test checks if getegid() returns the effective group id.
*/
-#include <sys/types.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-
-#include "test.h"
-#include "compat_16.h"
-
-static void setup();
-static void cleanup();
+#include "tst_test.h"
+#include "compat_tst_16.h"
-TCID_DEFINE(getegid01);
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
+static void run(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- TEST(GETEGID(cleanup));
+ gid_t gid, st_egid;
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL | TTERRNO, "getegid failed");
- continue; /* next loop for MTKERNEL */
- }
+ SAFE_FILE_LINES_SCANF("/proc/self/status", "Gid: %*d %d", &st_egid);
+ gid = getegid();
- tst_resm(TPASS, "getegid returned %ld", TEST_RETURN);
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ if (GID_SIZE_CHECK(st_egid))
+ TST_EXP_EQ_LI(gid, st_egid);
+ else
+ tst_res(TPASS, "getegid() passed");
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/getegid/getegid02.c b/testcases/kernel/syscalls/getegid/getegid02.c
index 60f09501e..2f64bd869 100644
--- a/testcases/kernel/syscalls/getegid/getegid02.c
+++ b/testcases/kernel/syscalls/getegid/getegid02.c
@@ -1,90 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2001
- * Ported by Wayne Boyer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * William Roske, Dave Fenner
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Testcase to check the basic functionality of getegid().
+/*\
+ * [Description]
*
- * For functionality test the return value from getegid() is compared to passwd
- * entry.
+ * This test checks if getegid() returns the same effective group given by
+ * passwd entry via getpwuid().
*/
#include <pwd.h>
-#include <errno.h>
-
-#include "test.h"
-#include "compat_16.h"
-static void cleanup(void);
-static void setup(void);
+#include "tst_test.h"
+#include "compat_tst_16.h"
-TCID_DEFINE(getegid02);
-int TST_TOTAL = 1;
-
-int main(int ac, char **av)
+static void run(void)
{
- int lc;
uid_t euid;
+ gid_t egid;
struct passwd *pwent;
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- TEST(GETEGID(cleanup));
+ UID16_CHECK((euid = geteuid()), "geteuid");
- if (TEST_RETURN < 0) {
- tst_brkm(TBROK, cleanup, "This should never happen");
- }
+ pwent = getpwuid(euid);
+ if (!pwent)
+ tst_brk(TBROK | TERRNO, "getpwuid() error");
- euid = geteuid();
- pwent = getpwuid(euid);
+ GID16_CHECK((egid = getegid()), "getegid");
- if (pwent == NULL)
- tst_brkm(TBROK, cleanup, "geteuid() returned "
- "unexpected value %d", euid);
-
- GID16_CHECK(pwent->pw_gid, getegid, cleanup);
-
- if (pwent->pw_gid != TEST_RETURN) {
- tst_resm(TFAIL, "getegid() return value"
- " %ld unexpected - expected %d",
- TEST_RETURN, pwent->pw_gid);
- } else {
- tst_resm(TPASS,
- "effective group id %ld "
- "is correct", TEST_RETURN);
- }
- }
-
- cleanup();
- tst_exit();
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
+ TST_EXP_EQ_LI(pwent->pw_gid, egid);
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/getgroups/Makefile b/testcases/kernel/syscalls/getgroups/Makefile
index b2bb1e005..a319acf85 100644
--- a/testcases/kernel/syscalls/getgroups/Makefile
+++ b/testcases/kernel/syscalls/getgroups/Makefile
@@ -3,6 +3,9 @@
top_srcdir ?= ../../../..
+# Remove after rewriting all tests to the new API.
+USE_LEGACY_COMPAT_16_H := 1
+
include $(top_srcdir)/include/mk/testcases.mk
include $(abs_srcdir)/../utils/compat_16.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/getgroups/getgroups01.c b/testcases/kernel/syscalls/getgroups/getgroups01.c
index cfddeb408..c253e487f 100644
--- a/testcases/kernel/syscalls/getgroups/getgroups01.c
+++ b/testcases/kernel/syscalls/getgroups/getgroups01.c
@@ -54,6 +54,11 @@
#include <sys/types.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
static void setup(void);
diff --git a/testcases/kernel/syscalls/getgroups/getgroups03.c b/testcases/kernel/syscalls/getgroups/getgroups03.c
index 5ba20ef82..fc94f0b8e 100644
--- a/testcases/kernel/syscalls/getgroups/getgroups03.c
+++ b/testcases/kernel/syscalls/getgroups/getgroups03.c
@@ -40,6 +40,11 @@
#include <pwd.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define TESTUSER "root"
diff --git a/testcases/kernel/syscalls/getpid/getpid01.c b/testcases/kernel/syscalls/getpid/getpid01.c
index ec18b67d5..495002037 100644
--- a/testcases/kernel/syscalls/getpid/getpid01.c
+++ b/testcases/kernel/syscalls/getpid/getpid01.c
@@ -6,26 +6,31 @@
/*\
* [Description]
*
- * Verify that getpid() system call returns process ID in range 2 ... PID_MAX
+ * Verify that getpid() system call returns process ID in range <2, PID_MAX>.
*/
#include <stdlib.h>
#include "tst_test.h"
+static pid_t pid_max;
+
+static void setup(void)
+{
+ SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &pid_max);
+}
+
static void verify_getpid(void)
{
- pid_t pid_max, pid;
+ pid_t pid;
int i;
- SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &pid_max);
-
for (i = 0; i < 100; i++) {
pid = SAFE_FORK();
if (pid == 0) {
pid = getpid();
/* pid should not be 1 or out of maximum */
- if (1 < pid && pid <= pid_max)
+ if (pid > 1 && pid <= pid_max)
tst_res(TPASS, "getpid() returns %d", pid);
else
tst_res(TFAIL,
@@ -38,6 +43,7 @@ static void verify_getpid(void)
}
static struct tst_test test = {
+ .setup = setup,
.forks_child = 1,
.test_all = verify_getpid,
};
diff --git a/testcases/kernel/syscalls/getppid/getppid01.c b/testcases/kernel/syscalls/getppid/getppid01.c
index f37948dd4..57efe1c1f 100644
--- a/testcases/kernel/syscalls/getppid/getppid01.c
+++ b/testcases/kernel/syscalls/getppid/getppid01.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2006-2023
*/
/*\
@@ -12,11 +13,16 @@
#include <errno.h>
#include "tst_test.h"
-static void verify_getppid(void)
-{
- pid_t ppid, pid_max;
+static pid_t pid_max;
+static void setup(void)
+{
SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &pid_max);
+}
+
+static void verify_getppid(void)
+{
+ pid_t ppid;
ppid = getppid();
if (ppid > pid_max)
@@ -26,5 +32,6 @@ static void verify_getppid(void)
}
static struct tst_test test = {
+ .setup = setup,
.test_all = verify_getppid,
};
diff --git a/testcases/kernel/syscalls/getresgid/Makefile b/testcases/kernel/syscalls/getresgid/Makefile
index b2bb1e005..a319acf85 100644
--- a/testcases/kernel/syscalls/getresgid/Makefile
+++ b/testcases/kernel/syscalls/getresgid/Makefile
@@ -3,6 +3,9 @@
top_srcdir ?= ../../../..
+# Remove after rewriting all tests to the new API.
+USE_LEGACY_COMPAT_16_H := 1
+
include $(top_srcdir)/include/mk/testcases.mk
include $(abs_srcdir)/../utils/compat_16.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/getresgid/getresgid01.c b/testcases/kernel/syscalls/getresgid/getresgid01.c
index b5fb804ee..8000200e1 100644
--- a/testcases/kernel/syscalls/getresgid/getresgid01.c
+++ b/testcases/kernel/syscalls/getresgid/getresgid01.c
@@ -73,6 +73,11 @@
#include <signal.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
char *TCID = "getresgid01";
diff --git a/testcases/kernel/syscalls/getresgid/getresgid02.c b/testcases/kernel/syscalls/getresgid/getresgid02.c
index 8bddf9824..ca4502aac 100644
--- a/testcases/kernel/syscalls/getresgid/getresgid02.c
+++ b/testcases/kernel/syscalls/getresgid/getresgid02.c
@@ -75,6 +75,11 @@
#include <pwd.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define LTPUSER "nobody"
diff --git a/testcases/kernel/syscalls/getresgid/getresgid03.c b/testcases/kernel/syscalls/getresgid/getresgid03.c
index 0785359e0..1d7bcabd2 100644
--- a/testcases/kernel/syscalls/getresgid/getresgid03.c
+++ b/testcases/kernel/syscalls/getresgid/getresgid03.c
@@ -77,6 +77,11 @@
#include <pwd.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
char *TCID = "getresgid03";
diff --git a/testcases/kernel/syscalls/getresuid/Makefile b/testcases/kernel/syscalls/getresuid/Makefile
index b2bb1e005..a319acf85 100644
--- a/testcases/kernel/syscalls/getresuid/Makefile
+++ b/testcases/kernel/syscalls/getresuid/Makefile
@@ -3,6 +3,9 @@
top_srcdir ?= ../../../..
+# Remove after rewriting all tests to the new API.
+USE_LEGACY_COMPAT_16_H := 1
+
include $(top_srcdir)/include/mk/testcases.mk
include $(abs_srcdir)/../utils/compat_16.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/getresuid/getresuid01.c b/testcases/kernel/syscalls/getresuid/getresuid01.c
index 07fed9c13..a04918d6f 100644
--- a/testcases/kernel/syscalls/getresuid/getresuid01.c
+++ b/testcases/kernel/syscalls/getresuid/getresuid01.c
@@ -72,6 +72,11 @@
#include <signal.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
char *TCID = "getresuid01";
diff --git a/testcases/kernel/syscalls/getresuid/getresuid02.c b/testcases/kernel/syscalls/getresuid/getresuid02.c
index 23f7944dd..77896a8a3 100644
--- a/testcases/kernel/syscalls/getresuid/getresuid02.c
+++ b/testcases/kernel/syscalls/getresuid/getresuid02.c
@@ -75,6 +75,11 @@
#include <pwd.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define LTPUSER "nobody"
diff --git a/testcases/kernel/syscalls/getresuid/getresuid03.c b/testcases/kernel/syscalls/getresuid/getresuid03.c
index bf117038b..34e40c45d 100644
--- a/testcases/kernel/syscalls/getresuid/getresuid03.c
+++ b/testcases/kernel/syscalls/getresuid/getresuid03.c
@@ -76,6 +76,11 @@
#include <pwd.h>
#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
char *TCID = "getresuid03";
diff --git a/testcases/kernel/syscalls/getrlimit/getrlimit02.c b/testcases/kernel/syscalls/getrlimit/getrlimit02.c
index 9b68ce20b..9f5b2bf9c 100644
--- a/testcases/kernel/syscalls/getrlimit/getrlimit02.c
+++ b/testcases/kernel/syscalls/getrlimit/getrlimit02.c
@@ -7,12 +7,13 @@
/*\
* [Description]
*
- * Test for checking error conditions for getrlimit(2)
- * 1) getrlimit(2) returns -1 and sets errno to EFAULT if an invalid
- * address is given for address parameter.
- * 2) getrlimit(2) returns -1 and sets errno to EINVAL if an invalid
- * resource type (RLIM_NLIMITS is a out of range resource type) is
- * passed.
+ * Test for checking error conditions for getrlimit(2):
+ *
+ * 1. getrlimit(2) returns -1 and sets errno to EFAULT if an invalid
+ * address is given for address parameter.
+ * 2. getrlimit(2) returns -1 and sets errno to EINVAL if an invalid
+ * resource type (RLIM_NLIMITS is a out of range resource type) is
+ * passed.
*/
#include <sys/resource.h>
diff --git a/testcases/kernel/syscalls/getsockopt/getsockopt02.c b/testcases/kernel/syscalls/getsockopt/getsockopt02.c
index 47aef32af..d24e9b693 100644
--- a/testcases/kernel/syscalls/getsockopt/getsockopt02.c
+++ b/testcases/kernel/syscalls/getsockopt/getsockopt02.c
@@ -3,9 +3,10 @@
* Copyright (C) 2017 Red Hat, Inc.
*/
-/*
- * Test description: Test retrieving of peer credentials (SO_PEERCRED)
+/*\
+ * [Description]
*
+ * Test getsockopt(2) for retrieving peer credentials (SO_PEERCRED).
*/
#define _GNU_SOURCE
@@ -53,6 +54,7 @@ static void test_function(void)
tst_res(TFAIL | TERRNO, "Error with accepting connection");
goto clean;
}
+
if (getsockopt(accepted, SOL_SOCKET,
SO_PEERCRED, &cred, &cred_len) < 0) {
tst_res(TFAIL | TERRNO, "Error while getting socket option");
@@ -67,6 +69,7 @@ static void test_function(void)
clean:
if (accepted >= 0)
SAFE_CLOSE(accepted);
+
TST_CHECKPOINT_WAKE(0);
}
@@ -74,6 +77,7 @@ static void cleanup(void)
{
if (accepted >= 0)
SAFE_CLOSE(accepted);
+
if (socket_fd >= 0)
SAFE_CLOSE(socket_fd);
}
diff --git a/testcases/kernel/syscalls/gettid/.gitignore b/testcases/kernel/syscalls/gettid/.gitignore
index 78dce3499..9014f7c3a 100644
--- a/testcases/kernel/syscalls/gettid/.gitignore
+++ b/testcases/kernel/syscalls/gettid/.gitignore
@@ -1 +1,2 @@
/gettid01
+/gettid02
diff --git a/testcases/kernel/syscalls/gettid/Makefile b/testcases/kernel/syscalls/gettid/Makefile
index 4e9982f76..5345eb0f5 100644
--- a/testcases/kernel/syscalls/gettid/Makefile
+++ b/testcases/kernel/syscalls/gettid/Makefile
@@ -10,7 +10,9 @@ top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
ifeq ($(ANDROID), 1)
-FILTER_OUT_MAKE_TARGETS += gettid01
+FILTER_OUT_MAKE_TARGETS += gettid01 gettid02
endif
+gettid02: LDLIBS += -lpthread
+
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/gettid/gettid01.c b/testcases/kernel/syscalls/gettid/gettid01.c
index 7e5b6b175..22ba15016 100644
--- a/testcases/kernel/syscalls/gettid/gettid01.c
+++ b/testcases/kernel/syscalls/gettid/gettid01.c
@@ -1,96 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Crackerjack Project
- *
* Copyright (C) 2007-2008, Hitachi, Ltd.
- * Author(s): Takahiro Yasui <takahiro.yasui.mp@hitachi.com>,
- * Yumiko Sugita <yumiko.sugita.yf@hitachi.com>,
- * Satoshi Fujiwara <sa-fuji@sdl.hitachi.co.jp>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $Id: gettid01.c,v 1.5 2009/10/26 14:55:47 subrata_modak Exp $
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+/*\
+ * [Description]
*
+ * This test checks if parent pid is equal to tid in single-threaded
+ * application.
*/
-/* Porting from Crackerjack to LTP is done
- by Masatake YAMATO <yamato@redhat.com> */
-
-#include <sys/types.h>
-#include <linux/unistd.h>
-#include <errno.h>
-
-#include "test.h"
-
-void setup();
-void cleanup();
-
-char *TCID = "gettid01";
-
-int TST_TOTAL = 1;
-
-pid_t my_gettid(void)
-{
- return (pid_t) syscall(__NR_gettid);
-}
-
-int main(int ac, char **av)
-{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- /*
- * The following loop checks looping state if -c option given
- */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
+#include "tst_test.h"
+#include "lapi/syscalls.h"
- tst_count = 0;
-
- TEST(my_gettid());
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "gettid() Failed, errno=%d: %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- } else {
- tst_resm(TPASS, "gettid() returned %ld",
- TEST_RETURN);
- }
- }
-
- cleanup();
- tst_exit();
-}
-
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+static void run(void)
{
+ long pid, tid;
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ SAFE_FILE_LINES_SCANF("/proc/self/status", "Pid: %ld", &pid);
+ SAFE_FILE_LINES_SCANF("/proc/self/status", "Tgid: %ld", &tid);
- TEST_PAUSE;
+ if (pid != tid)
+ tst_brk(TBROK, "Test function has been moved inside a thread?");
+ TST_EXP_EQ_LI(tst_syscall(__NR_gettid), tst_syscall(__NR_getpid));
+ TST_EXP_EQ_LI(tst_syscall(__NR_gettid), pid);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/gettid/gettid02.c b/testcases/kernel/syscalls/gettid/gettid02.c
new file mode 100644
index 000000000..ef44761c4
--- /dev/null
+++ b/testcases/kernel/syscalls/gettid/gettid02.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+/*\
+ * [Description]
+ *
+ * This test spawns multiple threads, then check for each one of them if the
+ * parent ID is different AND if the thread ID is different from all the other
+ * spwaned threads.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "tst_safe_pthread.h"
+
+#define THREADS_NUM 10
+
+static volatile pid_t tids[THREADS_NUM];
+
+static void *threaded(void *arg)
+{
+ int i = *(int *)arg;
+ pid_t pid, tid;
+
+ pid = tst_syscall(__NR_getpid);
+ tid = tst_syscall(__NR_gettid);
+
+ TST_EXP_EXPR(pid != tid,
+ "parent ID (%d) differs from thread[%d] ID (%d)",
+ pid, i, tid);
+ tids[i] = tid;
+ return NULL;
+}
+
+static void run(void)
+{
+ pthread_t thread[THREADS_NUM];
+ int args[THREADS_NUM];
+ int error = 0;
+
+ for (int i = 0; i < THREADS_NUM; i++) {
+ args[i] = i;
+ SAFE_PTHREAD_CREATE(&thread[i], NULL, threaded, &args[i]);
+ }
+ for (int i = 0; i < THREADS_NUM; i++)
+ SAFE_PTHREAD_JOIN(thread[i], NULL);
+
+ for (int i = 0; i < THREADS_NUM; i++) {
+ for (int j = i + 1; j < THREADS_NUM; j++) {
+ if (tids[i] == tids[j]) {
+ tst_res(TINFO, "thread[%d] and thread[%d] have the same ID %d", i, j, tids[i]);
+ error = 1;
+ }
+ }
+ }
+
+ if (error)
+ tst_res(TFAIL, "Some threads have the same TID");
+ else
+ tst_res(TPASS, "All threads have a different TID");
+}
+
+static struct tst_test test = {
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/gettimeofday/gettimeofday01.c b/testcases/kernel/syscalls/gettimeofday/gettimeofday01.c
index f9acb9665..887a36688 100644
--- a/testcases/kernel/syscalls/gettimeofday/gettimeofday01.c
+++ b/testcases/kernel/syscalls/gettimeofday/gettimeofday01.c
@@ -1,107 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Linux Test Project, 2001-2023
*/
-/*
- * NAME
- * gettimeofday01.c
- *
- * DESCRIPTION
- * Testcase to check that gettimeofday(2) sets errno to EFAULT.
- *
- * ALGORITHM
- * Call gettimeofday() with an invalid buffer, and expect EFAULT to be
- * set in errno.
+/*\
+ * [Description]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * Test for gettimeofday error.
*
- * RESTRICTIONS
- * NONE
+ * - EFAULT: tv pointed outside the accessible address space
+ * - EFAULT: tz pointed outside the accessible address space
+ * - EFAULT: both tv and tz pointed outside the accessible address space
*/
-#include <sys/time.h>
-#include <errno.h>
-#include "test.h"
-#include <unistd.h>
+#include "tst_test.h"
#include "lapi/syscalls.h"
-char *TCID = "gettimeofday01";
-int TST_TOTAL = 1;
+static struct timeval tv1;
-#if !defined UCLINUX
+static struct tcase {
+ void *tv;
+ void *tz;
+} tcases[] = {
+ /* timezone structure is obsolete, tz should be treated as null */
+ {(void *)-1, NULL},
+ {&tv1, (void *)-1},
+ {(void *)-1, (void *)-1},
+};
-void cleanup(void);
-void setup(void);
-
-int main(int ac, char **av)
+static void verify_gettimeofday(unsigned int n)
{
- int lc;
- int ret;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- TEST(tst_syscall(__NR_gettimeofday, (void *)-1, (void *)-1));
-
- /* gettimeofday returns an int, so we need to turn the long
- * TEST_RETURN into an int to test with */
- ret = TEST_RETURN;
- if (ret != -1) {
- tst_resm(TFAIL,
- "call succeeded unexpectedly (got back %i, wanted -1)",
- ret);
- continue;
- }
+ struct tcase *tc = &tcases[n];
- if (TEST_ERRNO == EFAULT)
- tst_resm(TPASS,
- "gettimeofday(2) set the errno EFAULT correctly");
- else
- tst_resm(TFAIL,
- "gettimeofday(2) didn't set errno to EFAULT, errno=%i (%s)",
- errno, strerror(errno));
- }
-
- cleanup();
- tst_exit();
-}
-
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-}
-
-void cleanup(void)
-{
-}
-#else
-
-int main(void)
-{
- tst_brkm(TCONF, "gettimeofday EFAULT check disabled on uClinux");
+ TST_EXP_FAIL(tst_syscall(__NR_gettimeofday, tc->tv, tc->tz), EFAULT);
}
-#endif
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcases),
+ .test = verify_gettimeofday,
+};
diff --git a/testcases/kernel/syscalls/gettimeofday/gettimeofday02.c b/testcases/kernel/syscalls/gettimeofday/gettimeofday02.c
index 7c462cc29..84bf1f773 100644
--- a/testcases/kernel/syscalls/gettimeofday/gettimeofday02.c
+++ b/testcases/kernel/syscalls/gettimeofday/gettimeofday02.c
@@ -4,13 +4,13 @@
* Copyright (C) 2017 Cyril Hrubis <chrubis@suse.cz>
*/
-/*
- * DESCRIPTION
- * Check if gettimeofday is monotonous
+/*\
+ * [Description]
+ *
+ * Check if gettimeofday() is monotonous during 10s:
*
- * ALGORITHM
- * Call gettimeofday() to get a t1 (fist value)
- * call it again to get t2, see if t2 < t1, set t2 = t1, repeat for 10 sec
+ * - Call gettimeofday() to get a t1 (fist value)
+ * - Call it again to get t2, see if t2 < t1, set t2 = t1, repeat for 10 sec
*/
#include <stdint.h>
diff --git a/testcases/kernel/syscalls/getxattr/getxattr02.c b/testcases/kernel/syscalls/getxattr/getxattr02.c
index a42057d0a..5a84d876c 100644
--- a/testcases/kernel/syscalls/getxattr/getxattr02.c
+++ b/testcases/kernel/syscalls/getxattr/getxattr02.c
@@ -1,64 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2011 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like. Any license provided herein, whether
- * implied or otherwise, applies only to this software file. Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (c) Linux Test Project, 2012-2022
+ * Copyright (c) 2023 Marius Kittler <mkittler@suse.de>
*/
-/*
+/*\
+ * [Description]
+ *
* In the user.* namespace, only regular files and directories can
* have extended attributes. Otherwise getxattr(2) will return -1
* and set errno to ENODATA.
*
* There are 4 test cases:
- * 1. Get attribute from a FIFO, setxattr(2) should return -1 and
+ *
+ * - Get attribute from a FIFO, setxattr(2) should return -1 and
* set errno to ENODATA
- * 2. Get attribute from a char special file, setxattr(2) should
+ * - Get attribute from a char special file, setxattr(2) should
* return -1 and set errno to ENODATA
- * 3. Get attribute from a block special file, setxattr(2) should
+ * - Get attribute from a block special file, setxattr(2) should
* return -1 and set errno to ENODATA
- * 4. Get attribute from a UNIX domain socket, setxattr(2) should
+ * - Get attribute from a UNIX domain socket, setxattr(2) should
* return -1 and set errno to ENODATA
*/
-#include "config.h"
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/sysmacros.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
+#include <sys/xattr.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_SYS_XATTR_H
-# include <sys/xattr.h>
-#endif
-#include "test.h"
-#include "safe_macros.h"
-char *TCID = "getxattr02";
+#include "tst_res_flags.h"
+#include "tst_test.h"
+#include "tst_test_macros.h"
-#ifdef HAVE_SYS_XATTR_H
+#define MNTPOINT "mntpoint"
+#define FNAME MNTPOINT"/getxattr02"
#define XATTR_TEST_KEY "user.testkey"
#define FIFO "getxattr02fifo"
@@ -66,94 +43,78 @@ char *TCID = "getxattr02";
#define BLK "getxattr02blk"
#define SOCK "getxattr02sock"
-static void setup(void);
-static void cleanup(void);
-
-static char *tc[] = {
- FIFO, /* case 00, get attr from fifo */
- CHR, /* case 01, get attr from char special */
- BLK, /* case 02, get attr from block special */
- SOCK, /* case 03, get attr from UNIX domain socket */
+static struct test_case {
+ const char *desc;
+ char *fname;
+ int mode;
+} tcases[] = {
+ {
+ .desc = "get attr from fifo",
+ .fname = FNAME FIFO,
+ .mode = S_IFIFO,
+ },
+ {
+ .desc = "get attr from char special",
+ .fname = FNAME CHR,
+ .mode = S_IFCHR,
+ },
+ {
+ .desc = "get attr from block special",
+ .fname = FNAME BLK,
+ .mode = S_IFBLK,
+ },
+ {
+ .desc = "get attr from UNIX domain socket",
+ .fname = FNAME SOCK,
+ .mode = S_IFSOCK,
+ },
};
-int TST_TOTAL = sizeof(tc) / sizeof(tc[0]);
-
-int main(int argc, char *argv[])
+static void run(unsigned int i)
{
- int lc;
- int i;
- int exp_eno;
char buf[BUFSIZ];
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- exp_eno = ENODATA;
-
- for (i = 0; i < TST_TOTAL; i++) {
- TEST(getxattr(tc[0], XATTR_TEST_KEY, buf, BUFSIZ));
-
- if (TEST_RETURN == -1 && TEST_ERRNO == exp_eno)
- tst_resm(TPASS | TTERRNO, "expected behavior");
- else
- tst_resm(TFAIL | TTERRNO, "unexpected behavior"
- " - expected errno %d - Got", exp_eno);
- }
- }
-
- cleanup();
- tst_exit();
+ struct test_case *tc = &tcases[i];
+ dev_t dev = tc->mode == S_IFCHR ? makedev(1, 3) : 0u;
+
+ if (mknod(tc->fname, tc->mode | 0777, dev) < 0)
+ tst_brk(TBROK | TERRNO, "create %s (mode %i) failed (%s)",
+ tc->fname, tc->mode, tc->desc);
+
+ TEST(getxattr(tc->fname, XATTR_TEST_KEY, buf, BUFSIZ));
+ if (TST_RET == -1 && TST_ERR == ENODATA)
+ tst_res(TPASS | TTERRNO, "%s: expected return value",
+ tc->desc);
+ else
+ tst_res(TFAIL | TTERRNO,
+ "%s: unexpected return value - expected errno %d - got",
+ tc->desc, ENODATA);
+
+ unlink(tc->fname);
}
static void setup(void)
{
- int fd;
- dev_t dev;
-
- tst_require_root();
-
- tst_tmpdir();
-
- /* Test for xattr support */
- fd = SAFE_CREAT(cleanup, "testfile", 0644);
- close(fd);
- if (setxattr("testfile", "user.test", "test", 4, XATTR_CREATE) == -1)
- if (errno == ENOTSUP)
- tst_brkm(TCONF, cleanup, "No xattr support in fs or "
- "mount without user_xattr option");
- unlink("testfile");
-
- /* Create test files */
- if (mknod(FIFO, S_IFIFO | 0777, 0) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "Create FIFO(%s) failed",
- FIFO);
-
- dev = makedev(1, 3);
- if (mknod(CHR, S_IFCHR | 0777, dev) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "Create char special(%s)"
- " failed", CHR);
-
- if (mknod(BLK, S_IFBLK | 0777, 0) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "Create block special(%s)"
- " failed", BLK);
-
- if (mknod(SOCK, S_IFSOCK | 0777, 0) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "Create socket(%s) failed",
- SOCK);
-
- TEST_PAUSE;
+ /* assert xattr support in the current filesystem */
+ SAFE_TOUCH(FNAME, 0644, NULL);
+ TEST(setxattr(FNAME, "user.test", "test", 4, XATTR_CREATE));
+ if (TST_ERR == ENOTSUP)
+ tst_brk(TCONF,
+ "No xattr support in fs or mount without user_xattr option");
+ else if (TST_RET != 0)
+ tst_brk(TBROK | TTERRNO, "setxattr failed");
}
-static void cleanup(void)
-{
- tst_rmdir();
-}
-#else /* HAVE_SYS_XATTR_H */
-int main(int argc, char *argv[])
-{
- tst_brkm(TCONF, NULL, "<sys/xattr.h> does not exist.");
-}
-#endif
+static struct tst_test test = {
+ .all_filesystems = 1,
+ .needs_root = 1,
+ .mntpoint = MNTPOINT,
+ .mount_device = 1,
+ .skip_filesystems = (const char *const []) {
+ "ramfs",
+ "nfs",
+ NULL
+ },
+ .setup = setup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases)
+};
diff --git a/testcases/kernel/syscalls/getxattr/getxattr03.c b/testcases/kernel/syscalls/getxattr/getxattr03.c
index b6ea14287..1fe4ba48f 100644
--- a/testcases/kernel/syscalls/getxattr/getxattr03.c
+++ b/testcases/kernel/syscalls/getxattr/getxattr03.c
@@ -1,117 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (C) 2012 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like. Any license provided herein, whether
- * implied or otherwise, applies only to this software file. Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (c) 2023 Marius Kittler <mkittler@suse.de>
*/
-/*
- * An empty buffer of size zero can be passed into getxattr(2) to return
- * the current size of the named extended attribute.
+/*\
+ * [Description]
+ *
+ * An empty buffer of size zero can be passed into getxattr(2) to
+ * return the current size of the named extended attribute.
*/
#include "config.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_SYS_XATTR_H
-# include <sys/xattr.h>
-#endif
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
-char *TCID = "getxattr03";
+#include <sys/xattr.h>
+#include "tst_safe_macros.h"
-#ifdef HAVE_SYS_XATTR_H
+#define MNTPOINT "mntpoint"
+#define FNAME MNTPOINT"/getxattr03testfile"
#define XATTR_TEST_KEY "user.testkey"
#define XATTR_TEST_VALUE "test value"
#define XATTR_TEST_VALUE_SIZE (sizeof(XATTR_TEST_VALUE) - 1)
-#define TESTFILE "getxattr03testfile"
-static void setup(void);
-static void cleanup(void);
-
-int TST_TOTAL = 1;
-
-int main(int argc, char *argv[])
+static void run(void)
{
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- TEST(getxattr(TESTFILE, XATTR_TEST_KEY, NULL, 0));
-
- if (TEST_RETURN == XATTR_TEST_VALUE_SIZE)
- tst_resm(TPASS, "getxattr(2) returned correct value");
- else
- tst_resm(TFAIL | TTERRNO, "getxattr(2) failed");
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_VAL(getxattr(FNAME, XATTR_TEST_KEY, NULL, 0),
+ XATTR_TEST_VALUE_SIZE);
}
static void setup(void)
{
- int fd;
-
- tst_require_root();
-
- tst_tmpdir();
-
- /* Test for xattr support and set attr value */
- fd = SAFE_CREAT(cleanup, TESTFILE, 0644);
- close(fd);
-
- if (setxattr(TESTFILE, XATTR_TEST_KEY, XATTR_TEST_VALUE,
- XATTR_TEST_VALUE_SIZE, XATTR_CREATE) == -1) {
- if (errno == ENOTSUP)
- tst_brkm(TCONF, cleanup, "No xattr support in fs or "
- "fs mounted without user_xattr option");
- else
- tst_brkm(TBROK | TERRNO, cleanup, "setxattr %s failed",
- TESTFILE);
- }
-
- TEST_PAUSE;
+ SAFE_TOUCH(FNAME, 0644, NULL);
+ SAFE_SETXATTR(FNAME, XATTR_TEST_KEY, XATTR_TEST_VALUE,
+ XATTR_TEST_VALUE_SIZE, XATTR_CREATE);
}
-static void cleanup(void)
-{
- tst_rmdir();
-}
-#else /* HAVE_SYS_XATTR_H */
-int main(int argc, char *argv[])
-{
- tst_brkm(TCONF, NULL, "<sys/xattr.h> does not exist.");
-}
-#endif
+static struct tst_test test = {
+ .all_filesystems = 1,
+ .needs_root = 1,
+ .mntpoint = MNTPOINT,
+ .mount_device = 1,
+ .skip_filesystems = (const char *const []) {
+ "exfat",
+ "tmpfs",
+ "ramfs",
+ "nfs",
+ "vfat",
+ NULL
+ },
+ .setup = setup,
+ .test_all = run,
+};
diff --git a/testcases/kernel/syscalls/ioctl/ioctl02.c b/testcases/kernel/syscalls/ioctl/ioctl02.c
index b4d4a3594..aab80b251 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl02.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl02.c
@@ -1,468 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) International Business Machines Corp., 2001
- * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
+ * Copyright (c) 2023 Marius Kittler <mkittler@suse.de>
*/
-/*
- * NAME
- * ioctl02.c
- *
- * DESCRIPTION
- * Testcase to test the TCGETA, and TCSETA ioctl implementations for
- * the tty driver
+/*\
+ * [Description]
*
- * ALGORITHM
- * In this test, the parent and child open the parentty and the childtty
- * respectively. After opening the childtty the child flushes the stream
- * and sends a SIGUSR1 to the parent (thereby asking it to continue its
- * testing). The parent, which was waiting for this signal to arrive, now
- * starts the testing. It issues a TCGETA ioctl to get all the tty
- * parameters. It then changes them to known values by issuing a TCSETA
- * ioctl. Then the parent issues a TCGETA ioctl again and compares the
- * received values with what it had set earlier. The test fails if TCGETA
- * or TCSETA fails, or if the received values don't match those that were
- * set. The parent does all the testing, the requirement of the child
- * process is to moniter the testing done by the parent, and hence the
- * child just waits for the parent.
+ * Test TCGETA/TCGETS and TCSETA/TCSETS ioctl implementations for tty driver.
*
- * USAGE: <for command-line>
- * ioctl02 -D /dev/tty[0-9] [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * test must be run with the -D option
- * test may have to be run as root depending on the tty permissions
+ * In this test, the parent and child open the parentty and the childtty
+ * respectively. After opening the childtty the child flushes the stream
+ * and wakes the parent (thereby asking it to continue its testing). The
+ * parent, then starts the testing. It issues a TCGETA/TCGETS ioctl to
+ * get all the tty parameters. It then changes them to known values by
+ * issuing a TCSETA/TCSETS ioctl. Then the parent issues a TCSETA/TCGETS
+ * ioctl again and compares the received values with what it had set
+ * earlier. The test fails if TCGETA/TCGETS or TCSETA/TCSETS fails, or if
+ * the received values don't match those that were set. The parent does
+ * all the testing, the requirement of the child process is to moniter
+ * the testing done by the parent, and hence the child just waits for the
+ * parent.
*/
#include <stdio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdlib.h>
#include <termios.h>
-#include "test.h"
-#include "safe_macros.h"
-#include "lapi/ioctl.h"
-#define CNUL 0
-
-char *TCID = "ioctl02";
-int TST_TOTAL = 1;
+#include "lapi/ioctl.h"
+#include "tst_test.h"
-static struct termio termio, save_io;
+static struct termio termio, termio_exp;
+static struct termios termios, termios_exp, termios_bak;
static char *parenttty, *childtty;
-static int parentfd, childfd;
+static int parentfd = -1;
static int parentpid, childpid;
-static volatile int sigterm, sigusr1, sigusr2;
-static int closed = 1;
-
-static int do_child_setup(void);
-static int do_parent_setup(void);
-static int run_ptest(void);
-static int run_ctest(void);
-static int chk_tty_parms();
+
+static void do_child(void);
+static void prepare_termio(void);
+static void run_ptest(void);
+static void chk_tty_parms_termio(void);
+static void chk_tty_parms_termios(void);
static void setup(void);
static void cleanup(void);
-static void help(void);
-static void do_child(void);
-void do_child_uclinux(void);
-static void sigterm_handler(void);
-static int Devflag;
-static char *devname;
-
-static option_t options[] = {
- {"D:", &Devflag, &devname},
- {NULL, NULL, NULL}
+static char *device;
+
+static struct variant {
+ const char *name;
+ void *termio, *termio_exp, *termio_bak;
+ size_t termio_size;
+ void (*check)(void);
+ int tcget, tcset;
+} variants[] = {
+ {
+ .name = "termio",
+ .termio = &termio,
+ .termio_exp = &termio_exp,
+ .termio_size = sizeof(termio),
+ .check = &chk_tty_parms_termio,
+ .tcget = TCGETA,
+ .tcset = TCSETA,
+ },
+ {
+ .name = "termios",
+ .termio = &termios,
+ .termio_exp = &termios_exp,
+ .termio_size = sizeof(termios),
+ .check = &chk_tty_parms_termios,
+ .tcget = TCGETS,
+ .tcset = TCSETS,
+ },
};
-int main(int ac, char **av)
+static void verify_ioctl(void)
{
- int lc;
- int rval;
-
- tst_parse_opts(ac, av, options, &help);
-
-#ifdef UCLINUX
- maybe_run_child(&do_child_uclinux, "dS", &parentpid, &childtty);
-#endif
-
- if (!Devflag)
- tst_brkm(TBROK, NULL, "You must specify a tty device with "
- "the -D option.");
-
- tst_require_root();
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- parenttty = devname;
- childtty = devname;
-
- parentpid = getpid();
-
- childpid = FORK_OR_VFORK();
- if (childpid < 0)
- tst_brkm(TBROK, cleanup, "fork failed");
-
- if (childpid == 0) { /* child */
-#ifdef UCLINUX
- if (self_exec(av[0], "dS", parentpid, childtty) < 0)
- tst_brkm(TBROK, cleanup, "self_exec failed");
-#else
- do_child();
-#endif
- }
-
- while (!sigusr1)
- sleep(1);
-
- sigusr1 = 0;
-
- parentfd = do_parent_setup();
- if (parentfd < 0) {
- kill(childpid, SIGTERM);
- waitpid(childpid, NULL, 0);
- cleanup();
- }
-
- /* run the parent test */
- rval = run_ptest();
- if (rval == -1) {
- /*
- * Parent cannot set/get ioctl parameters.
- * SIGTERM the child and cleanup.
- */
- kill(childpid, SIGTERM);
- waitpid(childpid, NULL, 0);
- cleanup();
- }
-
- if (rval != 0)
- tst_resm(TFAIL, "TCGETA/TCSETA tests FAILED with "
- "%d %s", rval, rval > 1 ? "errors" : "error");
- else
- tst_resm(TPASS, "TCGETA/TCSETA tests SUCCEEDED");
-
- /* FIXME: check return codes. */
- (void)kill(childpid, SIGTERM);
- (void)waitpid(childpid, NULL, 0);
-
- /*
- * Clean up things from the parent by restoring the
- * tty device information that was saved in setup()
- * and closing the tty file descriptor.
- */
- if (ioctl(parentfd, TCSETA, &save_io) == -1)
- tst_resm(TINFO, "ioctl restore failed in main");
- SAFE_CLOSE(cleanup, parentfd);
-
- closed = 1;
- }
- cleanup();
+ tst_res(TINFO, "Testing %s variant", variants[tst_variant].name);
- tst_exit();
-}
+ parenttty = device;
+ childtty = device;
-static void do_child(void)
-{
- childfd = do_child_setup();
- if (childfd < 0)
- _exit(1);
- run_ctest();
- _exit(0);
-}
+ parentpid = getpid();
+ childpid = SAFE_FORK();
+ if (!childpid) {
+ do_child();
+ exit(EXIT_SUCCESS);
+ }
-void do_child_uclinux(void)
-{
- struct sigaction act;
+ TST_CHECKPOINT_WAIT(0);
+
+ parentfd = SAFE_OPEN(parenttty, O_RDWR, 0777);
+ SAFE_IOCTL(parentfd, TCFLSH, TCIOFLUSH);
- /* Set up the signal handlers again */
- act.sa_handler = (void *)sigterm_handler;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
- (void)sigaction(SIGTERM, &act, 0);
+ run_ptest();
- /* Run the normal child */
- do_child();
+ TST_CHECKPOINT_WAKE(0);
+ SAFE_CLOSE(parentfd);
}
-/*
- * run_ptest() - setup the various termio structure values and issue
- * the TCSETA ioctl call with the TEST macro.
- */
-static int run_ptest(void)
+static void prepare_termio(void)
{
- int i, rval;
-
/* Use "old" line discipline */
- termio.c_line = 0;
+ termios_exp.c_line = termio_exp.c_line = 0;
/* Set control modes */
- termio.c_cflag = B50 | CS7 | CREAD | PARENB | PARODD | CLOCAL;
+ termios_exp.c_cflag = termio_exp.c_cflag = B50 | CS7 | CREAD | PARENB | PARODD | CLOCAL;
/* Set control chars. */
- for (i = 0; i < NCC; i++) {
- if (i == VEOL2)
- continue;
- termio.c_cc[i] = CSTART;
- }
+ for (int i = 0; i < NCC; i++)
+ termio_exp.c_cc[i] = CSTART;
+ for (int i = 0; i < VEOL2; i++)
+ termios_exp.c_cc[i] = CSTART;
/* Set local modes. */
- termio.c_lflag =
+ termios_exp.c_lflag = termio_exp.c_lflag =
((unsigned short)(ISIG | ICANON | XCASE | ECHO | ECHOE | NOFLSH));
/* Set input modes. */
- termio.c_iflag =
+ termios_exp.c_iflag = termio_exp.c_iflag =
BRKINT | IGNPAR | INPCK | ISTRIP | ICRNL | IUCLC | IXON | IXANY |
IXOFF;
/* Set output modes. */
- termio.c_oflag = OPOST | OLCUC | ONLCR | ONOCR;
-
- TEST(ioctl(parentfd, TCSETA, &termio));
-
- if (TEST_RETURN < 0) {
- tst_resm(TFAIL, "ioctl TCSETA failed : "
- "errno = %d", TEST_ERRNO);
- return -1;
- }
-
- /* Get termio and see if all parameters actually got set */
- rval = ioctl(parentfd, TCGETA, &termio);
- if (rval < 0) {
- tst_resm(TFAIL, "ioctl TCGETA failed. Ending test.");
- return -1;
- }
-
- return chk_tty_parms();
+ termios_exp.c_oflag = termio_exp.c_oflag = OPOST | OLCUC | ONLCR | ONOCR;
}
-static int run_ctest(void)
+/*
+ * run_ptest() - setup the various termio/termios structure values and issue
+ * the TCSETA/TCSETS ioctl call with the TEST macro.
+ */
+static void run_ptest(void)
{
- /*
- * Wait till the parent has finished testing.
- */
- while (!sigterm)
- sleep(1);
+ struct variant *v = &variants[tst_variant];
- sigterm = 0;
+ /* Init termio/termios structures used to check if all params got set */
+ memset(v->termio, 0, v->termio_size);
- tst_resm(TINFO, "child: Got SIGTERM from parent.");
+ SAFE_IOCTL(parentfd, v->tcset, v->termio_exp);
- if (close(childfd) == -1)
- tst_resm(TINFO, "close() in run_ctest() failed");
- return 0;
+ /* Get termio and see if all parameters actually got set */
+ SAFE_IOCTL(parentfd, v->tcget, v->termio);
+ v->check();
}
-static int chk_tty_parms(void)
+static int cmp_attr(unsigned long long exp, unsigned long long act, const char *attr)
{
- int i, flag = 0;
-
- if (termio.c_line != 0) {
- tst_resm(TINFO, "line discipline has incorrect value %o",
- termio.c_line);
- flag++;
- }
- /*
- * The following Code Sniffet is disabled to check the value of c_cflag
- * as it seems that due to some changes from 2.6.24 onwards, this
- * setting is not done properly for either of (B50|CS7|CREAD|PARENB|
- * PARODD|CLOCAL|(CREAD|HUPCL|CLOCAL).
- * However, it has been observed that other flags are properly set.
- */
-#if 0
- if (termio.c_cflag != (B50 | CS7 | CREAD | PARENB | PARODD | CLOCAL)) {
- tst_resm(TINFO, "cflag has incorrect value. %o",
- termio.c_cflag);
- flag++;
- }
-#endif
-
- for (i = 0; i < NCC; i++) {
- if (i == VEOL2) {
- if (termio.c_cc[VEOL2] == CNUL) {
- continue;
- } else {
- tst_resm(TINFO, "control char %d has "
- "incorrect value %d %d", i,
- termio.c_cc[i], CNUL);
- flag++;
- continue;
- }
- }
-
- if (termio.c_cc[i] != CSTART) {
- tst_resm(TINFO, "control char %d has incorrect "
- "value %d.", i, termio.c_cc[i]);
- flag++;
- }
- }
+ if (act == exp)
+ return 0;
+ tst_res(TFAIL, "%s has incorrect value %llu, expected %llu",
+ attr, act, exp);
+ return 1;
+}
- if (!
- (termio.c_lflag
- && (ISIG | ICANON | XCASE | ECHO | ECHOE | NOFLSH))) {
- tst_resm(TINFO, "lflag has incorrect value. %o",
- termio.c_lflag);
- flag++;
- }
+static int cmp_c_cc(unsigned char *exp_c_cc, unsigned char *act_c_cc, int ncc)
+{
+ int i, fails = 0;
+ char what[32];
- if (!
- (termio.c_iflag
- && (BRKINT | IGNPAR | INPCK | ISTRIP | ICRNL | IUCLC | IXON | IXANY
- | IXOFF))) {
- tst_resm(TINFO, "iflag has incorrect value. %o",
- termio.c_iflag);
- flag++;
+ for (i = 0; i < ncc; ++i) {
+ sprintf(what, "control char %d", i);
+ fails += cmp_attr(exp_c_cc[i], act_c_cc[i], what);
}
+ return fails;
+}
- if (!(termio.c_oflag && (OPOST | OLCUC | ONLCR | ONOCR))) {
- tst_resm(TINFO, "oflag has incorrect value. %o",
- termio.c_oflag);
- flag++;
- }
+#define CMP_ATTR(term_exp, term, attr, flag) \
+({ \
+ flag += cmp_attr((term_exp).attr, (term).attr, #attr); \
+ flag; \
+})
- if (!flag)
- tst_resm(TINFO, "termio values are set as expected");
+#define CMP_C_CC(term_exp, term, flag) \
+({ \
+ flag += cmp_c_cc(term_exp.c_cc, term.c_cc, sizeof(term.c_cc)); \
+ flag; \
+})
- return flag;
-}
-
-static int do_parent_setup(void)
+static void chk_tty_parms_termio(void)
{
- int pfd;
-
- pfd = SAFE_OPEN(cleanup, parenttty, O_RDWR, 0777);
+ int flag = 0;
- /* unset the closed flag */
- closed = 0;
+ flag = CMP_ATTR(termio_exp, termio, c_line, flag);
+ flag = CMP_C_CC(termio_exp, termio, flag);
+ flag = CMP_ATTR(termio_exp, termio, c_lflag, flag);
+ flag = CMP_ATTR(termio_exp, termio, c_iflag, flag);
+ flag = CMP_ATTR(termio_exp, termio, c_oflag, flag);
- /* flush tty queues to remove old output */
- SAFE_IOCTL(cleanup, pfd, TCFLSH, 2);
- return pfd;
+ if (!flag)
+ tst_res(TPASS, "TCGETA/TCSETA tests");
}
-static int do_child_setup(void)
+static void chk_tty_parms_termios(void)
{
- int cfd;
-
- cfd = open(childtty, O_RDWR, 0777);
- if (cfd < 0) {
- tst_resm(TINFO, "Could not open %s in do_child_setup(), errno "
- "= %d", childtty, errno);
- /* signal the parent so we don't hang the test */
- kill(parentpid, SIGUSR1);
- return -1;
- }
+ int flag = 0;
- /* flush tty queues to remove old output */
- if (ioctl(cfd, TCFLSH, 2) < 0) {
- tst_resm(TINFO, "ioctl TCFLSH failed. : errno = %d", errno);
- /* signal the parent so we don't hang the test */
- kill(parentpid, SIGUSR1);
- return -1;
- }
+ flag = CMP_ATTR(termios_exp, termios, c_line, flag);
+ flag = CMP_C_CC(termios_exp, termios, flag);
+ flag = CMP_ATTR(termios_exp, termios, c_lflag, flag);
+ flag = CMP_ATTR(termios_exp, termios, c_iflag, flag);
+ flag = CMP_ATTR(termios_exp, termios, c_oflag, flag);
- /* tell the parent that we're done */
- kill(parentpid, SIGUSR1);
-
- return cfd;
+ if (!flag)
+ tst_res(TPASS, "TCGETS/TCSETS tests");
}
-/*
- * Define the signals handlers here.
- */
-static void sigterm_handler(void)
+static void do_child(void)
{
- sigterm = 1;
-}
+ int cfd = SAFE_OPEN(childtty, O_RDWR, 0777);
-static void sigusr1_handler(void)
-{
- sigusr1 = 1;
-}
+ SAFE_IOCTL(cfd, TCFLSH, TCIOFLUSH);
-static void sigusr2_handler(void)
-{
- sigusr2 = 1;
-}
+ /* tell the parent that we're done */
+ TST_CHECKPOINT_WAKE(0);
-static void help(void)
-{
- printf(" -D <tty device> : for example, /dev/tty[0-9]\n");
+ TST_CHECKPOINT_WAIT(0);
+ tst_res(TINFO, "child: parent has finished testing");
+ SAFE_CLOSE(cfd);
}
static void setup(void)
{
- int fd;
- struct sigaction act;
+ if (!device)
+ tst_brk(TBROK, "You must specify a tty device with -d option");
- /* XXX: TERRNO required all over the place */
- fd = SAFE_OPEN(NULL, devname, O_RDWR, 0777);
+ int fd = SAFE_OPEN(device, O_RDWR, 0777);
- /* Save the current device information - to be restored in cleanup() */
- SAFE_IOCTL(cleanup, fd, TCGETA, &save_io);
+ SAFE_IOCTL(fd, TCGETS, &termios_bak);
+ SAFE_CLOSE(fd);
- /* Close the device */
- SAFE_CLOSE(cleanup, fd);
-
- /* Set up the signal handlers */
- act.sa_handler = (void *)sigterm_handler;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
- (void)sigaction(SIGTERM, &act, 0);
-
- act.sa_handler = (void *)sigusr1_handler;
- act.sa_flags = 0;
- (void)sigaction(SIGUSR1, &act, 0);
-
- act.sa_handler = (void *)sigusr2_handler;
- act.sa_flags = 0;
- (void)sigaction(SIGUSR2, &act, 0);
-
- act.sa_handler = SIG_IGN;
- act.sa_flags = 0;
- (void)sigaction(SIGTTOU, &act, 0);
-
- sigterm = sigusr1 = sigusr2 = 0;
-
- TEST_PAUSE;
+ prepare_termio();
}
static void cleanup(void)
{
- if (!closed) {
- if (ioctl(parentfd, TCSETA, &save_io) == -1)
- tst_resm(TINFO, "ioctl restore failed in cleanup()");
- if (close(parentfd) == -1)
- tst_resm(TINFO, "close() failed in cleanup()");
+ if (parentfd >= 0) {
+ SAFE_IOCTL(parentfd, TCSETS, &termios_bak);
+ SAFE_CLOSE(parentfd);
}
}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .forks_child = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = verify_ioctl,
+ .test_variants = 2,
+ .options = (struct tst_option[]) {
+ {"d:", &device, "Tty device. For example, /dev/tty[0-9]"},
+ {}
+ }
+};
diff --git a/testcases/kernel/syscalls/ioctl/ioctl_loop06.c b/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
index 6d009af6a..64800b4ee 100644
--- a/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
+++ b/testcases/kernel/syscalls/ioctl/ioctl_loop06.c
@@ -109,8 +109,9 @@ static void setup(void)
unalign_value = pg_size - 1;
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
+ ret = ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 512);
- if (ioctl(dev_fd, LOOP_SET_BLOCK_SIZE, 512) && errno == EINVAL)
+ if (ret && (errno == EINVAL || errno == ENOTTY))
tst_brk(TCONF, "LOOP_SET_BLOCK_SIZE is not supported");
file_fd = SAFE_OPEN("test.img", O_RDWR);
diff --git a/testcases/kernel/syscalls/ioctl/test_ioctl b/testcases/kernel/syscalls/ioctl/test_ioctl
index 43836a229..8549e5608 100755
--- a/testcases/kernel/syscalls/ioctl/test_ioctl
+++ b/testcases/kernel/syscalls/ioctl/test_ioctl
@@ -45,7 +45,7 @@ case "$device_no" in
continue
fi
tst_resm TINFO "Testing ioctl02 with $tttype"
- ioctl02 -D $tttype
+ ioctl02 -d $tttype
RC=$?
if [ $RC -eq 0 ]
then
diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl06.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl06.c
index 6f5476383..c1264b71e 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl06.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl06.c
@@ -139,12 +139,16 @@ static void verify_msgctl(unsigned int n)
static void setup(void)
{
struct msqid_ds temp_buf;
+ struct buf {
+ long type;
+ char text[5];
+ } msgbuf = {MSGTYPE, "abcd"};
ltpuser = SAFE_GETPWNAM("nobody");
nobody_uid = ltpuser->pw_uid;
root_uid = 0;
msg_id = SAFE_MSGGET(IPC_PRIVATE, IPC_CREAT | MSG_RW);
- SAFE_MSGSND(msg_id, "abcd", 4, 0);
+ SAFE_MSGSND(msg_id, &msgbuf, sizeof(msgbuf.text), 0);
TEST(msgctl(msg_id, MSG_STAT_ANY, &temp_buf));
if (TST_RET == -1) {
diff --git a/testcases/kernel/syscalls/ipc/shmget/shmget02.c b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
index 8168803a5..10b8c9292 100644
--- a/testcases/kernel/syscalls/ipc/shmget/shmget02.c
+++ b/testcases/kernel/syscalls/ipc/shmget/shmget02.c
@@ -37,8 +37,6 @@
#include "libnewipc.h"
#include "lapi/shm.h"
-#define CONFIG_HUGETLBFS "CONFIG_HUGETLBFS"
-
static int shm_id = -1;
static key_t shmkey, shmkey1;
static struct passwd *pw;
@@ -66,10 +64,7 @@ static struct tcase {
static int get_hugetlb_exp_error(void)
{
long tmp;
- struct tst_kconfig_var kconfig = {
- .id = CONFIG_HUGETLBFS,
- .id_len = sizeof(CONFIG_HUGETLBFS)-1,
- };
+ struct tst_kconfig_var kconfig = TST_KCONFIG_INIT("CONFIG_HUGETLBFS");
tst_kconfig_read(&kconfig, 1);
diff --git a/testcases/kernel/syscalls/keyctl/keyctl01.c b/testcases/kernel/syscalls/keyctl/keyctl01.c
index 55e069c68..674094eec 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl01.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl01.c
@@ -2,14 +2,17 @@
/*
* Copyright (c) Crackerjack Project., 2007
* Copyright (c) 2017 Fujitsu Ltd.
+ * Copyright (c) Linux Test Project, 2009-2024
+ * Ported by Manas Kumar Nayak maknayak@in.ibm.com>
+ * Modified by Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
*/
-/*
- * Description: This tests the keyctl() syscall
- * Manipulate the kernel's key management facility
+/*\
+ * [Description]
*
- * Ported by Manas Kumar Nayak maknayak@in.ibm.com>
- * Modified by Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ * Tests the keyctl(2) syscall.
+ *
+ * Manipulate the kernel's key management facility.
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/keyctl/keyctl02.c b/testcases/kernel/syscalls/keyctl/keyctl02.c
index 35cc2838d..fd3f86bbc 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl02.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl02.c
@@ -1,11 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Fujitsu Ltd.
- * Ported: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2017-2024
+ * Ported: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
*/
-/*
- * This is a regression test for the race between keyctl_read() and
+/*\
+ * [Description]
+ *
+ * Regression test for the race between keyctl_read() and
* keyctl_revoke(), if the revoke happens between keyctl_read()
* checking the validity of a key and the key's semaphore being taken,
* then the key type read method will see a revoked key.
@@ -14,13 +17,8 @@
* assumes in its read method that there will always be a payload
* in a non-revoked key and doesn't check for a NULL pointer.
*
- * This test can crash the buggy kernel, and the bug was fixed in:
- *
- * commit b4a1b4f5047e4f54e194681125c74c0aa64d637d
- * Author: David Howells <dhowells@redhat.com>
- * Date: Fri Dec 18 01:34:26 2015 +0000
- *
- * KEYS: Fix race between read and revoke
+ * Bug was fixed in commit
+ * b4a1b4f5047e ("KEYS: Fix race between read and revoke")
*/
#include <errno.h>
@@ -29,6 +27,7 @@
#include "tst_safe_pthread.h"
#include "tst_test.h"
+#include "tst_kconfig.h"
#include "lapi/keyctl.h"
#define LOOPS 20000
@@ -36,6 +35,7 @@
#define PATH_KEY_COUNT_QUOTA "/proc/sys/kernel/keys/root_maxkeys"
static int orig_maxkeys;
+static int realtime_kernel;
static void *do_read(void *arg)
{
@@ -86,6 +86,15 @@ static void do_test(void)
tst_res(TINFO, "Runtime exhausted, exiting after %d loops", i);
break;
}
+
+ /*
+ * Realtime kernel has deferred post-join thread cleanup which
+ * may result in exhaustion of cgroup thread limit. Add delay
+ * to limit the maximum number of stale threads to 4000
+ * even with CONFIG_HZ=100.
+ */
+ if (realtime_kernel)
+ usleep(100);
}
/*
@@ -126,8 +135,19 @@ static void do_test(void)
static void setup(void)
{
+ unsigned int i;
+ struct tst_kconfig_var rt_kconfigs[] = {
+ TST_KCONFIG_INIT("CONFIG_PREEMPT_RT"),
+ TST_KCONFIG_INIT("CONFIG_PREEMPT_RT_FULL")
+ };
+
SAFE_FILE_SCANF(PATH_KEY_COUNT_QUOTA, "%d", &orig_maxkeys);
SAFE_FILE_PRINTF(PATH_KEY_COUNT_QUOTA, "%d", orig_maxkeys + LOOPS + 1);
+
+ tst_kconfig_read(rt_kconfigs, ARRAY_SIZE(rt_kconfigs));
+
+ for (i = 0; i < ARRAY_SIZE(rt_kconfigs); i++)
+ realtime_kernel |= rt_kconfigs[i].choice == 'y';
}
static void cleanup(void)
diff --git a/testcases/kernel/syscalls/keyctl/keyctl03.c b/testcases/kernel/syscalls/keyctl/keyctl03.c
index 9d7b9a0b5..563ee96a9 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl03.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl03.c
@@ -1,19 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Fujitsu Ltd.
- * Ported: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2017-2024
+ * Ported: Guangwen Feng <fenggw-fnst@cn.fujitsu.com>
*/
-/*
- * This regression test can crash the buggy kernel,
- * and the bug was fixed in:
- *
- * commit f05819df10d7b09f6d1eb6f8534a8f68e5a4fe61
- * Author: David Howells <dhowells@redhat.com>
- * Date: Thu Oct 15 17:21:37 2015 +0100
+/*\
+ * [Description]
*
- * KEYS: Fix crash when attempt to garbage collect
- * an uninstantiated keyring
+ * Regression test for commit
+ * f05819df10d7 ("KEYS: Fix crash when attempt to garbage collect an uninstantiated keyring")
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/keyctl/keyctl04.c b/testcases/kernel/syscalls/keyctl/keyctl04.c
index 1fed23ca6..50c9244de 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl04.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl04.c
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Google, Inc.
+ * Copyright (c) Linux Test Project, 2017-2024
*/
-/*
+/*\
+ * [Description]
+ *
* Regression test for commit c9f838d104fe ("KEYS: fix
* keyctl_set_reqkey_keyring() to not leak thread keyrings"), a.k.a.
* CVE-2017-7472. This bug could be used to exhaust kernel memory, though it
diff --git a/testcases/kernel/syscalls/keyctl/keyctl05.c b/testcases/kernel/syscalls/keyctl/keyctl05.c
index 7d7c076c0..0ad106774 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl05.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl05.c
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Google, Inc.
+ * Copyright (c) Linux Test Project, 2017-2024
*/
-/*
+/*\
+ * [Description]
+ *
* Regression test for commit 63a0b0509e70 ("KEYS: fix freeing uninitialized
* memory in key_update()"). Try to reproduce the crash in two different ways:
*
@@ -31,6 +34,8 @@
#include "tst_test.h"
#include "lapi/keyctl.h"
+#define MODULE "dns_resolver"
+
/*
* A valid payload for the "asymmetric" key type. This is an x509 certificate
* in DER format, generated using:
@@ -190,6 +195,9 @@ static void test_update_setperm_race(void)
static void setup(void)
{
+ /* There is no way to trigger automatic dns_resolver module loading. */
+ tst_cmd((const char*[]){"modprobe", MODULE, NULL}, NULL, NULL, 0);
+
fips_enabled = tst_fips_enabled();
}
@@ -198,8 +206,12 @@ static void do_test(unsigned int i)
/*
* We need to pass check in dns_resolver_preparse(),
* give it dummy server list request.
+ * From v6.8-rc1 commit acc657692aed438e9931438f8c923b2b107aebf9:
+ * the incoming data for add_key() sysdall should be not less than 6
+ * bytes, because struct dns_server_list_v1_header is 6 bytes.
+ * The minimum payload will be tested here for boundary testing.
*/
- static char dns_res_payload[] = { 0x00, 0x00, 0x01, 0xff, 0x00 };
+ static char dns_res_payload[] = { 0x00, 0x00, 0x01, 0xff, 0x00, 0x00 };
switch (i) {
case 0:
@@ -207,7 +219,7 @@ static void do_test(unsigned int i)
x509_cert, sizeof(x509_cert));
break;
case 1:
- test_update_nonupdatable("dns_resolver", dns_res_payload,
+ test_update_nonupdatable(MODULE, dns_res_payload,
sizeof(dns_res_payload));
break;
case 2:
@@ -217,12 +229,14 @@ static void do_test(unsigned int i)
}
static struct tst_test test = {
+ .needs_root = 1,
.tcnt = 3,
.setup = setup,
.test = do_test,
.forks_child = 1,
.tags = (const struct tst_tag[]) {
{"linux-git", "63a0b0509e70"},
+ {"linux-git", "acc657692aed"},
{}
}
};
diff --git a/testcases/kernel/syscalls/keyctl/keyctl06.c b/testcases/kernel/syscalls/keyctl/keyctl06.c
index f76a85ff2..4564601d1 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl06.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl06.c
@@ -1,19 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Google, Inc.
+ * Copyright (c) Linux Test Project, 2017-2024
*/
-/*
- * Regression test for:
+/*\
+ * [Description]
*
- * commit e645016abc80 ("KEYS: fix writing past end of user-supplied buffer
- * in keyring_read()").
+ * Regression test for commit:
*
- * as well as its follow-on fix:
+ * e645016abc80 ("KEYS: fix writing past end of user-supplied buffer in keyring_read()")
*
- * commit 3239b6f29bdf ("KEYS: return full count in keyring_read() if
- * buffer is too small")
+ * as well as its follow-on fix:
*
+ * commit 3239b6f29bdf ("KEYS: return full count in keyring_read() if buffer is too small")
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/keyctl/keyctl07.c b/testcases/kernel/syscalls/keyctl/keyctl07.c
index d9e20db5f..8b10ee803 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl07.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl07.c
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Google, Inc.
+ * Copyright (c) Linux Test Project, 2018-2024
*/
-/*
+/*\
+ * [Description]
+ *
* Regression test for commit 37863c43b2c6 ("KEYS: prevent KEYCTL_READ on
* negative key"). This is CVE-2017-12192.
*/
diff --git a/testcases/kernel/syscalls/keyctl/keyctl08.c b/testcases/kernel/syscalls/keyctl/keyctl08.c
index be4b23b14..30e077c50 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl08.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl08.c
@@ -1,10 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2017 Richard Palethorpe <rpalethorpe@suse.com>
+ * Copyright (c) Linux Test Project, 2019-2024
*/
-/* Check for CVE-2016-9604; that keys beginning with "." are disallowed.
+
+/*\
+ * [Description]
+ *
+ * Test for CVE-2016-9604, checks that keys beginning with "." are disallowed.
*
- * See commit ee8f844e3c5a73b999edf733df1c529d6503ec2f
+ * See commit
+ * ee8f844e3c5a ("KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings")
*/
#include <errno.h>
diff --git a/testcases/kernel/syscalls/keyctl/keyctl09.c b/testcases/kernel/syscalls/keyctl/keyctl09.c
index cfd5f7e5f..1f24f804a 100644
--- a/testcases/kernel/syscalls/keyctl/keyctl09.c
+++ b/testcases/kernel/syscalls/keyctl/keyctl09.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2022 Google, Inc.
+ * Copyright (c) Linux Test Project, 2023
*/
/*\
diff --git a/testcases/kernel/syscalls/lchown/Makefile b/testcases/kernel/syscalls/lchown/Makefile
index 305fee281..7c76afea5 100644
--- a/testcases/kernel/syscalls/lchown/Makefile
+++ b/testcases/kernel/syscalls/lchown/Makefile
@@ -3,6 +3,9 @@
top_srcdir ?= ../../../..
+# Remove after rewriting all tests to the new API.
+USE_LEGACY_COMPAT_16_H := 1
+
include $(top_srcdir)/include/mk/testcases.mk
SRCS := $(sort $(wildcard $(abs_srcdir)/lchown*.c))
diff --git a/testcases/kernel/syscalls/lchown/lchown01.c b/testcases/kernel/syscalls/lchown/lchown01.c
index 4e6076e1f..aaa0ef403 100644
--- a/testcases/kernel/syscalls/lchown/lchown01.c
+++ b/testcases/kernel/syscalls/lchown/lchown01.c
@@ -41,6 +41,11 @@
#include "test.h"
#include "safe_macros.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define FILE_MODE (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
diff --git a/testcases/kernel/syscalls/lchown/lchown02.c b/testcases/kernel/syscalls/lchown/lchown02.c
index 97966f6be..c0932fb7a 100644
--- a/testcases/kernel/syscalls/lchown/lchown02.c
+++ b/testcases/kernel/syscalls/lchown/lchown02.c
@@ -58,6 +58,11 @@
#include "test.h"
#include "safe_macros.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define TEST_USER "nobody"
diff --git a/testcases/kernel/syscalls/lchown/lchown03.c b/testcases/kernel/syscalls/lchown/lchown03.c
index c26f54c21..ecb6ed64d 100644
--- a/testcases/kernel/syscalls/lchown/lchown03.c
+++ b/testcases/kernel/syscalls/lchown/lchown03.c
@@ -39,6 +39,11 @@
#include "test.h"
#include "safe_macros.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting all tests to the new API.
+ */
#include "compat_16.h"
#define DIR_MODE (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP| \
diff --git a/testcases/kernel/syscalls/link/.gitignore b/testcases/kernel/syscalls/link/.gitignore
index e5d7f1bbc..b2b9db632 100644
--- a/testcases/kernel/syscalls/link/.gitignore
+++ b/testcases/kernel/syscalls/link/.gitignore
@@ -1,5 +1,4 @@
/link02
-/link03
/link04
/link05
/link08
diff --git a/testcases/kernel/syscalls/link/link03.c b/testcases/kernel/syscalls/link/link03.c
deleted file mode 100644
index 1f45240ae..000000000
--- a/testcases/kernel/syscalls/link/link03.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : Richard Logan
- * CO-PILOT : William Roske
- * Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
- */
-
- /*
- * Tests that link(2) succeds with creating n links.
- */
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-#include "safe_macros.h"
-
-static void setup(void);
-static void help(void);
-static void cleanup(void);
-
-char *TCID = "link03";
-int TST_TOTAL = 2;
-
-#define BASENAME "lkfile"
-
-static char fname[255];
-static int nlinks = 0;
-static char *links_arg;
-
-option_t options[] = {
- {"N:", NULL, &links_arg},
- {NULL, NULL, NULL}
-};
-
-int main(int ac, char **av)
-{
- int lc;
- struct stat buf;
- int i, links;
- char lname[255];
-
- tst_parse_opts(ac, av, options, &help);
-
- if (links_arg) {
- nlinks = atoi(links_arg);
-
- if (nlinks == 0) {
- tst_brkm(TBROK, NULL,
- "nlinks is not a positive number");
- }
-
- if (nlinks > 1000) {
- tst_resm(TINFO,
- "nlinks > 1000 - may get errno:%d (EMLINK)",
- EMLINK);
- }
- }
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- if (nlinks)
- links = nlinks;
- else
- links = (lc % 90) + 10;
-
- /* Create links - 1 hardlinks so that the st_nlink == links */
- for (i = 1; i < links; i++) {
- sprintf(lname, "%s%d", fname, i);
- TEST(link(fname, lname));
-
- if (TEST_RETURN == -1) {
- tst_brkm(TFAIL | TTERRNO, cleanup,
- "link(%s, %s) Failed", fname, lname);
- }
- }
-
- SAFE_STAT(cleanup, fname, &buf);
-
- if (buf.st_nlink != (nlink_t)links) {
- tst_resm(TFAIL, "Wrong number of links for "
- "'%s' have %i, should be %i",
- fname, (int)buf.st_nlink, links);
- goto unlink;
- }
-
- for (i = 1; i < links; i++) {
- sprintf(lname, "%s%d", fname, i);
- SAFE_STAT(cleanup, lname, &buf);
- if (buf.st_nlink != (nlink_t)links) {
- tst_resm(TFAIL,
- "Wrong number of links for "
- "'%s' have %i, should be %i",
- lname, (int)buf.st_nlink, links);
- goto unlink;
- }
- }
-
- tst_resm(TPASS, "link() passed and linkcounts=%d match", links);
-
-unlink:
- for (i = 1; i < links; i++) {
- sprintf(lname, "%s%d", fname, i);
- SAFE_UNLINK(cleanup, lname);
- }
- }
-
- cleanup();
- tst_exit();
-}
-
-static void help(void)
-{
- printf(" -N #links : create #links hard links every iteration\n");
-}
-
-static void setup(void)
-{
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- sprintf(fname, "%s_%d", BASENAME, getpid());
- SAFE_TOUCH(cleanup, fname, 0700, NULL);
-}
-
-static void cleanup(void)
-{
- tst_rmdir();
-}
diff --git a/testcases/kernel/syscalls/link/link05.c b/testcases/kernel/syscalls/link/link05.c
index 95787ec24..dfef3d458 100644
--- a/testcases/kernel/syscalls/link/link05.c
+++ b/testcases/kernel/syscalls/link/link05.c
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : Richard Logan
- * CO-PILOT : William Roske
+ * Authors: Richard Logan, William Roske
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2001-2023
*/
-/*
- * Test if link(2) fails with EMLINK.
+/*\
+ * [Description]
+ *
+ * Tests that link(2) succeeds with creating 1000 links.
*/
#include <stdio.h>
@@ -41,10 +43,8 @@ static void verify_link(void)
(fbuf.st_nlink != lbuf.st_nlink)) {
tst_res(TFAIL,
- "link(%s, %s[1-%d]) ret %ld for %d "
- "files, stat values do not match %d %d",
- fname, fname, nlinks,
- TST_RET, nlinks,
+ "link(%s, %s[1-%d]) ret %ld for %d files, stat values do not match %d %d",
+ fname, fname, nlinks, TST_RET, nlinks,
(int)fbuf.st_nlink, (int)lbuf.st_nlink);
break;
}
@@ -52,10 +52,8 @@ static void verify_link(void)
if (cnt >= nlinks) {
tst_res(TPASS,
- "link(%s, %s[1-%d]) ret %ld for %d files, "
- "stat linkcounts match %d",
- fname, fname, nlinks, TST_RET,
- nlinks, (int)fbuf.st_nlink);
+ "link(%s, %s[1-%d]) ret %ld for %d files, stat linkcounts match %d",
+ fname, fname, nlinks, TST_RET, nlinks, (int)fbuf.st_nlink);
}
for (cnt = 1; cnt < nlinks; cnt++) {
@@ -71,7 +69,7 @@ static void setup(void)
}
static struct tst_test test = {
- .test_all = verify_link,
- .setup = setup,
- .needs_tmpdir = 1,
+ .test_all = verify_link,
+ .setup = setup,
+ .needs_tmpdir = 1,
};
diff --git a/testcases/kernel/syscalls/link/link08.c b/testcases/kernel/syscalls/link/link08.c
index d3e33d077..92d507489 100644
--- a/testcases/kernel/syscalls/link/link08.c
+++ b/testcases/kernel/syscalls/link/link08.c
@@ -1,23 +1,26 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2014 Fujitsu Ltd.
+ * Copyright (c) Linux Test Project, 2014-2023
* Author: Zeng Linggang <zenglg.jy@cn.fujitsu.com>
*/
-/*
- * Test Description:
- * Verify that,
- * 1. link() fails with -1 return value and sets errno to EPERM
- * if oldpath is a directory.
- * 2. link() fails with -1 return value and sets errno to EXDEV
- * if oldpath and newpath are not on the same mounted file system( Linux
- * permits a file system to be mounted at multiple points, but link()
- * does not work across different mount points, even if the same
- * file system is mounted on both. ).
- * 3. link() fails with -1 return value and sets errno to EROFS
- * if the file is on a read-only file system.
- * 4. link() fails with -1 return value and sets errno to ELOOP
- * if too many symbolic links were encountered in resolving path.
+
+/*\
+ * [Description]
+ *
+ * Verify that:
+ *
+ * - link() fails with EPERM if the old path is a directory.
+ * - link() fails with EXDEV if the old path and the new path
+ * are not on the same mounted file system(Linux permits
+ * a file system to be mounted at multiple points, but link()
+ * does not work across different mount points, even if the same
+ * file system is mounted on both).
+ * - link() fails with EROFS if the file is on a read-only file system.
+ * - link() fails with ELOOP if too many symbolic links were encountered
+ * in resolving path.
*/
+
#include <errno.h>
#include "tst_test.h"
diff --git a/testcases/kernel/syscalls/mkdirat/mkdirat01.c b/testcases/kernel/syscalls/mkdirat/mkdirat01.c
index a323ed5b3..ca536bdab 100644
--- a/testcases/kernel/syscalls/mkdirat/mkdirat01.c
+++ b/testcases/kernel/syscalls/mkdirat/mkdirat01.c
@@ -35,7 +35,6 @@
#include <string.h>
#include <signal.h>
#include "test.h"
-#include "lapi/mkdirat.h"
#include "safe_macros.h"
static void setup(void);
diff --git a/testcases/kernel/syscalls/mkdirat/mkdirat02.c b/testcases/kernel/syscalls/mkdirat/mkdirat02.c
index ebc0ed16b..2bd8fe9c0 100644
--- a/testcases/kernel/syscalls/mkdirat/mkdirat02.c
+++ b/testcases/kernel/syscalls/mkdirat/mkdirat02.c
@@ -11,7 +11,6 @@
#define _GNU_SOURCE
#include "tst_test.h"
-#include "lapi/mkdirat.h"
#define MNT_POINT "mntpoint"
#define TEST_DIR "mntpoint/test_dir"
diff --git a/testcases/kernel/syscalls/mknodat/mknodat.h b/testcases/kernel/syscalls/mknodat/mknodat.h
deleted file mode 100644
index 8f3a1f007..000000000
--- a/testcases/kernel/syscalls/mknodat/mknodat.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2007
- * Copyright (c) 2014 Fujitsu Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef MKNODAT_H
-#define MKNODAT_H
-
-#include <sys/types.h>
-#include "config.h"
-#include "lapi/syscalls.h"
-
-#if !defined(HAVE_MKNODAT)
-int mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
-{
- return tst_syscall(__NR_mknodat, dirfd, filename, mode, dev);
-}
-#endif
-
-#endif /* MKNODAT_H */
diff --git a/testcases/kernel/syscalls/mknodat/mknodat01.c b/testcases/kernel/syscalls/mknodat/mknodat01.c
index 6500ca362..3be0a4f87 100644
--- a/testcases/kernel/syscalls/mknodat/mknodat01.c
+++ b/testcases/kernel/syscalls/mknodat/mknodat01.c
@@ -35,7 +35,6 @@
#include "test.h"
#include "safe_macros.h"
#include "lapi/fcntl.h"
-#include "mknodat.h"
#define PATHNAME "mknodattestdir"
diff --git a/testcases/kernel/syscalls/mknodat/mknodat02.c b/testcases/kernel/syscalls/mknodat/mknodat02.c
index eda247fda..fdac5db15 100644
--- a/testcases/kernel/syscalls/mknodat/mknodat02.c
+++ b/testcases/kernel/syscalls/mknodat/mknodat02.c
@@ -37,7 +37,7 @@
#include "test.h"
#include "safe_macros.h"
#include "lapi/fcntl.h"
-#include "mknodat.h"
+#include "lapi/syscalls.h"
static void setup(void);
static void cleanup(void);
diff --git a/testcases/kernel/syscalls/mmap/mmap04.c b/testcases/kernel/syscalls/mmap/mmap04.c
index 43f7b7525..fa85deed1 100644
--- a/testcases/kernel/syscalls/mmap/mmap04.c
+++ b/testcases/kernel/syscalls/mmap/mmap04.c
@@ -1,185 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
*/
-/*
- * Test Description:
- * Call mmap() to map a file creating a mapped region with read/exec access
- * under the following conditions -
- * - The prot parameter is set to PROT_READ|PROT_EXEC
- * - The file descriptor is open for read
- * - The file being mapped has read and execute permission bit set.
- * - The minimum file permissions should be 0555.
- *
- * The call should succeed to map the file creating mapped memory with the
- * required attributes.
- *
- * Expected Result:
- * mmap() should succeed returning the address of the mapped region,
- * and the mapped region should contain the contents of the mapped file.
+/*\
+ * [Description]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * Verify that, after a successful mmap() call, permission bits of the new
+ * mapping in /proc/pid/maps file matches the prot and flags arguments in
+ * mmap() call.
*/
+#include <inttypes.h>
+#include "tst_test.h"
#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include "test.h"
-
-#define TEMPFILE "mmapfile"
-
-char *TCID = "mmap04";
-int TST_TOTAL = 1;
-
-static size_t page_sz;
-static char *addr;
-static char *dummy;
-static int fildes;
-
-static void setup(void);
-static void cleanup(void);
-
-int main(int ac, char **av)
+static char *addr1;
+static char *addr2;
+
+static struct tcase {
+ int prot;
+ int flags;
+ char *exp_perms;
+} tcases[] = {
+ {PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, "---p"},
+ {PROT_NONE, MAP_ANONYMOUS | MAP_SHARED, "---s"},
+ {PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, "r--p"},
+ {PROT_READ, MAP_ANONYMOUS | MAP_SHARED, "r--s"},
+ {PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, "-w-p"},
+ {PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, "-w-s"},
+ {PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, "rw-p"},
+ {PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, "rw-s"},
+ {PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, "r-xp"},
+ {PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED, "r-xs"},
+ {PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, "-wxp"},
+ {PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED, "-wxs"},
+ {PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, "rwxp"},
+ {PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_SHARED, "rwxs"}
+};
+
+static void run(unsigned int i)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with read and execute access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_READ | PROT_EXEC,
- MAP_FILE | MAP_SHARED, fildes, 0);
-
- /* Check for the return value of mmap() */
- if (addr == MAP_FAILED) {
- tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE);
- continue;
- }
-
- /*
- * Read the file contents into the dummy
- * variable.
- */
- if (read(fildes, dummy, page_sz) < 0) {
- tst_brkm(TFAIL, cleanup, "reading %s failed",
- TEMPFILE);
- }
-
- /*
- * Check whether the mapped memory region
- * has the file contents.
- */
- if (memcmp(dummy, addr, page_sz)) {
- tst_resm(TFAIL,
- "mapped memory region contains invalid "
- "data");
- } else {
- tst_resm(TPASS,
- "Functionality of mmap() successful");
- }
-
- /* Clean up things in case we are looping. */
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_brkm(TFAIL, cleanup, "munmapping failed");
- }
+ struct tcase *tc = &tcases[i];
+ char perms[8];
+ char fmt[1024];
+ unsigned int pagesize;
+ int flag;
+
+ pagesize = SAFE_SYSCONF(_SC_PAGESIZE);
+
+ /* To avoid new mapping getting merged with existing mappings, we first
+ * create a 2-page mapping with the different permissions, and then remap
+ * the 2nd page with the perms being tested.
+ */
+ flag = (tc->flags & MAP_PRIVATE) ? MAP_SHARED : MAP_PRIVATE;
+ addr1 = SAFE_MMAP(NULL, pagesize * 2, PROT_NONE, MAP_ANONYMOUS | flag, -1, 0);
+
+ addr2 = SAFE_MMAP(addr1 + pagesize, pagesize, tc->prot, tc->flags | MAP_FIXED, -1, 0);
+
+ sprintf(fmt, "%" PRIxPTR "-%%*x %%s", (uintptr_t)addr2);
+ SAFE_FILE_LINES_SCANF("/proc/self/maps", fmt, perms);
+
+ if (!strcmp(perms, tc->exp_perms)) {
+ tst_res(TPASS, "mapping permissions in /proc matched: %s", perms);
+ } else {
+ tst_res(TFAIL, "mapping permissions in /proc mismatched, expected: %s, found: %s",
+ tc->exp_perms, perms);
}
- cleanup();
- tst_exit();
+ SAFE_MUNMAP(addr1, pagesize * 2);
}
-static void setup(void)
-{
- char *tst_buff;
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- page_sz = getpagesize();
-
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
-
- tst_tmpdir();
-
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE);
- }
-
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) < (ssize_t)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL, cleanup, "writing to %s failed", TEMPFILE);
- }
-
- /* Free the memory allocated for test buffer */
- free(tst_buff);
-
- /* Make sure proper permissions set on file */
- if (fchmod(fildes, 0555) < 0) {
- tst_brkm(TFAIL, cleanup, "fchmod of %s failed", TEMPFILE);
- }
-
- /* Close the temporary file opened for write */
- if (close(fildes) < 0) {
- tst_brkm(TFAIL, cleanup, "closing %s failed", TEMPFILE);
- }
-
- /* Allocate and initialize dummy string of system page size bytes */
- if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
- }
-
- /* Open the temporary file again for reading */
- if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
- tst_brkm(TFAIL, cleanup,
- "opening %s read-only failed", TEMPFILE);
- }
-}
-
-static void cleanup(void)
-{
- close(fildes);
- free(dummy);
- tst_rmdir();
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+};
diff --git a/testcases/kernel/syscalls/mmap/mmap15.c b/testcases/kernel/syscalls/mmap/mmap15.c
index 443a37eb8..71c18a10a 100644
--- a/testcases/kernel/syscalls/mmap/mmap15.c
+++ b/testcases/kernel/syscalls/mmap/mmap15.c
@@ -1,113 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2004
- * Written by Robbie Williamson
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Written by Robbie Williamson
+ * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
+ * Copyright (c) Linux Test Project, 2014-2023
*/
-/*
- * Test Description: Test that a normal page cannot be mapped into a high
- * memory region.
+/*\
+ * [Description]
+ *
+ * Verify that, a normal page cannot be mapped into a high memory region,
+ * and mmap() call fails with either ENOMEM or EINVAL errno.
*/
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "test.h"
-#include "safe_macros.h"
-#include "lapi/abisize.h"
-
-char *TCID = "mmap15";
-int TST_TOTAL = 1;
+#include "tst_test.h"
#ifdef __ia64__
-# define HIGH_ADDR (void *)(0xa000000000000000UL)
+# define HIGH_ADDR ((void *)(0xa000000000000000UL))
#else
-# define HIGH_ADDR (void *)(-page_size)
+# define HIGH_ADDR ((void *)(-page_size))
#endif
-static long page_size;
+#define TEMPFILE "mmapfile"
-static void setup(void);
-static void cleanup(void);
+static long page_size;
+static int fd;
-int main(int ac, char **av)
+static void run(void)
{
- int lc, fd;
- void *addr;
-
-#ifdef TST_ABI32
- tst_brkm(TCONF, NULL, "This test is only for 64bit");
-#endif
+ fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
- tst_parse_opts(ac, av, NULL, NULL);
+ TESTPTR(mmap(HIGH_ADDR, page_size, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0));
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- fd = SAFE_OPEN(cleanup, "testfile", O_RDWR | O_CREAT, 0666);
-
- /* Attempt to mmap into highmem addr, should get ENOMEM */
- addr = mmap(HIGH_ADDR, page_size, PROT_READ,
- MAP_SHARED | MAP_FIXED, fd, 0);
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL, "mmap into high region "
- "succeeded unexpectedly");
- munmap(addr, page_size);
- close(fd);
- continue;
- }
-
- if (errno != ENOMEM && errno != EINVAL) {
- tst_resm(TFAIL | TERRNO, "mmap into high region "
- "failed unexpectedly");
- } else {
- tst_resm(TPASS | TERRNO, "mmap into high region "
- "failed as expected");
- }
-
- SAFE_CLOSE(cleanup, fd);
+ if (TST_RET_PTR != MAP_FAILED) {
+ tst_res(TFAIL, "mmap() into high mem region succeeded unexpectedly");
+ SAFE_MUNMAP(TST_RET_PTR, page_size);
+ return;
}
- cleanup();
- tst_exit();
+ if (TST_ERR == ENOMEM || TST_ERR == EINVAL)
+ tst_res(TPASS | TERRNO, "mmap() failed with expected errno");
+ else
+ tst_res(TFAIL | TERRNO, "mmap() failed with unexpected errno");
+
+ SAFE_CLOSE(fd);
}
static void setup(void)
{
- tst_require_root();
-
- tst_tmpdir();
-
page_size = getpagesize();
-
- TEST_PAUSE;
}
static void cleanup(void)
{
- tst_rmdir();
+ if (fd > 0)
+ SAFE_CLOSE(fd);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .skip_in_compat = 1,
+ .needs_tmpdir = 1
+};
diff --git a/testcases/kernel/syscalls/mount/mount04.c b/testcases/kernel/syscalls/mount/mount04.c
index 5969fbacb..5eb5ee11b 100644
--- a/testcases/kernel/syscalls/mount/mount04.c
+++ b/testcases/kernel/syscalls/mount/mount04.c
@@ -1,119 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
+ * Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * DESCRIPTION
- * Verify that mount(2) returns -1 and sets errno to EPERM if the user
- * is not the super-user.
+ * Verify that mount(2) returns -1 and sets errno to EPERM if the user
+ * is not root.
*/
-#include <errno.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include "tst_test.h"
#include <pwd.h>
-#include "test.h"
-#include "safe_macros.h"
-
-static void setup(void);
-static void cleanup(void);
-
-char *TCID = "mount04";
-
-#define DIR_MODE S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
-
-static char *mntpoint = "mntpoint";
-static const char *fs_type;
-static const char *device;
-
-int TST_TOTAL = 1;
-
-static void verify_mount(void)
-{
-
- TEST(mount(device, mntpoint, fs_type, 0, NULL));
-
- if (TEST_RETURN == -1) {
- if (TEST_ERRNO == EPERM)
- tst_resm(TPASS | TTERRNO, "mount() failed expectedly");
- else
- tst_resm(TFAIL | TTERRNO,
- "mount() was expected to fail with EPERM");
- return;
- }
+#include <sys/mount.h>
- if (TEST_RETURN == 0) {
- tst_resm(TFAIL, "mount() succeeded unexpectedly");
- if (tst_umount(mntpoint))
- tst_brkm(TBROK, cleanup, "umount() failed");
- return;
- }
+#define MNTPOINT "mntpoint"
- tst_resm(TFAIL | TTERRNO, "mount() returned %li", TEST_RETURN);
-}
-
-int main(int ac, char **av)
+static void cleanup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- verify_mount();
- }
-
- cleanup();
- tst_exit();
+ if (tst_is_mounted(MNTPOINT))
+ SAFE_UMOUNT(MNTPOINT);
}
-static void setup(void)
+static void run(void)
{
- char nobody_uid[] = "nobody";
struct passwd *ltpuser;
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- tst_require_root();
-
- tst_tmpdir();
+ ltpuser = SAFE_GETPWNAM("nobody");
+ SAFE_SETEUID(ltpuser->pw_uid);
- fs_type = tst_dev_fs_type();
- device = tst_acquire_device(cleanup);
+ TST_EXP_FAIL(
+ mount(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, NULL),
+ EPERM,
+ "mount() failed expectedly for normal user"
+ );
- if (!device)
- tst_brkm(TCONF, cleanup, "Failed to obtain block device");
-
- tst_mkfs(cleanup, device, fs_type, NULL, NULL);
-
- ltpuser = SAFE_GETPWNAM(cleanup, nobody_uid);
- SAFE_SETEUID(cleanup, ltpuser->pw_uid);
- SAFE_MKDIR(cleanup, mntpoint, DIR_MODE);
-
- TEST_PAUSE;
+ if (tst_is_mounted(MNTPOINT))
+ SAFE_UMOUNT(MNTPOINT);
}
-static void cleanup(void)
-{
- if (seteuid(0))
- tst_resm(TWARN | TERRNO, "seteuid(0) failed");
-
- if (device)
- tst_release_device(device);
-
- tst_rmdir();
-}
+static struct tst_test test = {
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_root = 1,
+ .format_device = 1,
+ .mntpoint = MNTPOINT,
+};
diff --git a/testcases/kernel/syscalls/mount/mount05.c b/testcases/kernel/syscalls/mount/mount05.c
index ca26f9738..616eeee79 100644
--- a/testcases/kernel/syscalls/mount/mount05.c
+++ b/testcases/kernel/syscalls/mount/mount05.c
@@ -1,131 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2013 Fujitsu Ltd.
- * Author: DAN LI <li.dan@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Copyright (c) 2013 Fujitsu Ltd. Dan Li <li.dan@cn.fujitsu.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * DESCRIPTION
- * Test for feature MS_BIND of mount.
- * "Perform a bind mount, making a file or a directory subtree visible
- * at another point within a file system."
+/*\
+ * [Description]
+ *
+ * Test for feature MS_BIND of mount, which performs a bind mount, making a file
+ * or a directory subtree visible at another point within a file system.
*/
-#include <errno.h>
+#include "tst_test.h"
#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-static void help(void);
-static void setup(void);
-static void cleanup(void);
-char *TCID = "mount05";
-int TST_TOTAL = 1;
+#define MNTPOINT1 "mntpoint1"
+#define TESTFILE1 MNTPOINT1 "/testfile"
+#define TESTDIR1 MNTPOINT1 "/testdir"
-#define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
+#define MNTPOINT2 "mntpoint2"
+#define TESTFILE2 MNTPOINT2 "/testfile"
+#define TESTDIR2 MNTPOINT2 "/testdir"
-static int dflag;
-static char *fstype = "ext2";
-static char *device;
-static const char file_src[] = "mnt_src/tstfile";
-static const char file_des[] = "mnt_des/tstfile";
-static const char mntpoint_src[] = "mnt_src";
-static const char mntpoint_des[] = "mnt_des";
-
-static option_t options[] = {
- {"T:", NULL, &fstype},
- {"D:", &dflag, &device},
- {NULL, NULL, NULL},
-};
-
-int main(int argc, char *argv[])
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(argc, argv, options, &help);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
+ SAFE_MOUNT(tst_device->dev, MNTPOINT1, tst_device->fs_type, 0, NULL);
- TEST(mount(mntpoint_src, mntpoint_des, fstype, MS_BIND, NULL));
+ tst_res(TINFO, "Creating file in '%s'", TESTFILE1);
- if (TEST_RETURN != 0) {
- tst_resm(TFAIL | TTERRNO, "mount(2) failed");
- } else {
-
- if (open(file_des, O_CREAT | O_EXCL, S_IRWXU) == -1 &&
- errno == EEXIST)
- tst_resm(TPASS, "bind mount is ok");
- else
- tst_resm(TFAIL, "file %s is not available",
- file_des);
-
- TEST(tst_umount(mntpoint_des));
- if (TEST_RETURN != 0)
- tst_brkm(TBROK | TTERRNO, cleanup,
- "umount(2) failed");
- }
- }
-
- cleanup();
- tst_exit();
+ SAFE_FILE_PRINTF(TESTFILE1, "LTP TEST FILE");
+ SAFE_MKDIR(TESTDIR1, 0750);
}
-void setup(void)
+static void cleanup(void)
{
- tst_require_root();
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- tst_tmpdir();
-
- SAFE_MKDIR(cleanup, mntpoint_src, DIR_MODE);
- SAFE_MKDIR(cleanup, mntpoint_des, DIR_MODE);
-
- if (dflag) {
- tst_mkfs(NULL, device, fstype, NULL, NULL);
+ if (tst_is_mounted(MNTPOINT1))
+ SAFE_UMOUNT(MNTPOINT1);
- SAFE_MOUNT(cleanup, device, mntpoint_src, fstype, 0, NULL);
- }
-
- SAFE_FILE_PRINTF(cleanup, file_src, "TEST FILE");
-
- TEST_PAUSE;
+ if (tst_is_mounted(MNTPOINT2))
+ SAFE_UMOUNT(MNTPOINT2);
}
-void cleanup(void)
+static void run(void)
{
- if (dflag)
- if (tst_umount(mntpoint_src) != 0)
- tst_brkm(TBROK | TTERRNO, NULL, "umount(2) failed");
+ SAFE_MKDIR(MNTPOINT2, 0750);
+ SAFE_MOUNT(MNTPOINT1, MNTPOINT2, tst_device->fs_type, MS_BIND, NULL);
- tst_rmdir();
-}
+ TST_EXP_PASS(access(TESTFILE2, F_OK), "Accessing to '%s'", TESTFILE2);
+ TST_EXP_PASS(access(TESTDIR2, F_OK), "Accessing to '%s'", TESTDIR2);
-void help(void)
-{
- printf("-T type : specifies the type of filesystem to be mounted. "
- "Default ext2.\n");
- printf("-D device : device used for mounting.\n");
+ if (tst_is_mounted(MNTPOINT2))
+ SAFE_UMOUNT(MNTPOINT2);
+
+ SAFE_RMDIR(MNTPOINT2);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_root = 1,
+ .format_device = 1,
+ .mntpoint = MNTPOINT1,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *const []){
+ "exfat",
+ "vfat",
+ "ntfs",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/mount/mount06.c b/testcases/kernel/syscalls/mount/mount06.c
index 857f5f905..2376deab3 100644
--- a/testcases/kernel/syscalls/mount/mount06.c
+++ b/testcases/kernel/syscalls/mount/mount06.c
@@ -1,34 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Copyright (c) 2013 Fujitsu Ltd.
- * Author: DAN LI <li.dan@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
+ * Copyright (c) 2013 Fujitsu Ltd. Dan Li <li.dan@cn.fujitsu.com>
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * DESCRIPTION
- * Test for feature MS_MOVE of mount(2).
- * "Move an existing mount point to the new location."
+/*\
+ * [Description]
+ *
+ * Test for feature MS_MOVE of mount, which moves an existing mount point to
+ * a new location.
*/
-#include <errno.h>
+#include "tst_test.h"
+#include <stdio.h>
#include <sys/mount.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "test.h"
-#include "safe_macros.h"
#ifndef MS_MOVE
#define MS_MOVE 8192
@@ -38,126 +23,86 @@
#define MS_PRIVATE (1 << 18)
#endif
-#define MNTPOINT_SRC "mnt_src"
-#define MNTPOINT_DES "mnt_des"
-#define LINELENGTH 256
-#define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
-
-static int ismount(char *mntpoint);
-static void setup(void);
-static void cleanup(void);
+#define MNTPOINT_SRC "mntpoint1"
+#define MNTPOINT_DST "mntpoint2"
-char *TCID = "mount06";
-int TST_TOTAL = 1;
-
-static const char *fs_type;
-static const char *device;
-static char path_name[PATH_MAX];
+static char *tmppath;
static char mntpoint_src[PATH_MAX];
-static char mntpoint_des[PATH_MAX];
-static int mount_flag;
+static char mntpoint_dst[PATH_MAX];
+static char tstfiles_src[PATH_MAX];
+static char tstfiles_dst[PATH_MAX];
-int main(int argc, char *argv[])
+static void setup(void)
{
- int lc;
+ tmppath = tst_get_tmpdir();
- tst_parse_opts(argc, argv, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- SAFE_MOUNT(cleanup, device, mntpoint_src, fs_type, 0, NULL);
-
- TEST(mount(mntpoint_src, mntpoint_des, fs_type, MS_MOVE, NULL));
-
- if (TEST_RETURN != 0) {
- tst_resm(TFAIL | TTERRNO, "mount(2) failed");
- } else {
-
- if (!ismount(mntpoint_src) && ismount(mntpoint_des))
- tst_resm(TPASS, "move mount is ok");
- else
- tst_resm(TFAIL, "move mount does not work");
+ /*
+ * Turn current dir into a private mount point being a parent
+ * mount which is required by move mount.
+ */
+ SAFE_MOUNT(tmppath, tmppath, "none", MS_BIND, NULL);
+ SAFE_MOUNT("none", tmppath, "none", MS_PRIVATE, NULL);
- TEST(tst_umount(mntpoint_des));
- if (TEST_RETURN != 0)
- tst_brkm(TBROK | TTERRNO, cleanup,
- "umount(2) failed");
- }
- }
+ snprintf(mntpoint_src, PATH_MAX, "%s/%s", tmppath, MNTPOINT_SRC);
+ snprintf(mntpoint_dst, PATH_MAX, "%s/%s", tmppath, MNTPOINT_DST);
- cleanup();
- tst_exit();
-}
+ snprintf(tstfiles_src, PATH_MAX, "%s/%s/testfile", tmppath, MNTPOINT_SRC);
+ snprintf(tstfiles_dst, PATH_MAX, "%s/%s/testfile", tmppath, MNTPOINT_DST);
-int ismount(char *mntpoint)
-{
- int ret = 0;
- FILE *file;
- char line[LINELENGTH];
-
- file = fopen("/proc/mounts", "r");
- if (file == NULL)
- tst_brkm(TFAIL | TERRNO, NULL, "Open /proc/mounts failed");
-
- while (fgets(line, LINELENGTH, file) != NULL) {
- if (strstr(line, mntpoint) != NULL) {
- ret = 1;
- break;
- }
- }
- fclose(file);
- return ret;
+ SAFE_MKDIR(mntpoint_dst, 0750);
}
-static void setup(void)
+static void cleanup(void)
{
- tst_require_root();
+ if (tst_is_mounted(mntpoint_src))
+ SAFE_UMOUNT(mntpoint_src);
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ if (tst_is_mounted(mntpoint_dst))
+ SAFE_UMOUNT(mntpoint_dst);
- tst_tmpdir();
+ if (tst_is_mounted(tmppath))
+ SAFE_UMOUNT(tmppath);
- fs_type = tst_dev_fs_type();
- device = tst_acquire_device(cleanup);
-
- if (!device)
- tst_brkm(TCONF, cleanup, "Failed to obtain block device");
-
- tst_mkfs(cleanup, device, fs_type, NULL, NULL);
-
- if (getcwd(path_name, sizeof(path_name)) == NULL)
- tst_brkm(TBROK, cleanup, "getcwd failed");
+ SAFE_RMDIR(mntpoint_dst);
+}
- /*
- * Turn current dir into a private mount point being a parent
- * mount which is required by move mount.
- */
- SAFE_MOUNT(cleanup, path_name, path_name, "none", MS_BIND, NULL);
+static void run(void)
+{
+ SAFE_MOUNT(tst_device->dev, mntpoint_src, tst_device->fs_type, 0, NULL);
+ SAFE_FILE_PRINTF(tstfiles_src, "LTP TEST FILE");
- mount_flag = 1;
+ SAFE_MOUNT(mntpoint_src, mntpoint_dst, tst_device->fs_type, MS_MOVE, NULL);
- SAFE_MOUNT(cleanup, "none", path_name, "none", MS_PRIVATE, NULL);
+ TST_EXP_FAIL(
+ access(tstfiles_src, F_OK),
+ ENOENT,
+ "File %s doesn't exist",
+ tstfiles_src);
- snprintf(mntpoint_src, PATH_MAX, "%s/%s", path_name, MNTPOINT_SRC);
- snprintf(mntpoint_des, PATH_MAX, "%s/%s", path_name, MNTPOINT_DES);
+ TST_EXP_PASS(
+ access(tstfiles_dst, F_OK),
+ "File %s exists :",
+ tstfiles_dst);
- SAFE_MKDIR(cleanup, mntpoint_src, DIR_MODE);
- SAFE_MKDIR(cleanup, mntpoint_des, DIR_MODE);
+ if (tst_is_mounted(mntpoint_src))
+ SAFE_UMOUNT(mntpoint_src);
- TEST_PAUSE;
+ if (tst_is_mounted(mntpoint_dst))
+ SAFE_UMOUNT(mntpoint_dst);
}
-static void cleanup(void)
-{
- if (mount_flag && tst_umount(path_name) != 0)
- tst_resm(TWARN | TERRNO, "umount(2) %s failed", path_name);
-
- if (device)
- tst_release_device(device);
-
- tst_rmdir();
-}
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_root = 1,
+ .format_device = 1,
+ .mntpoint = MNTPOINT_SRC,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *const []){
+ "exfat",
+ "vfat",
+ "ntfs",
+ NULL
+ },
+};
diff --git a/testcases/kernel/syscalls/mremap/mremap06.c b/testcases/kernel/syscalls/mremap/mremap06.c
index a19262750..3bbaf441a 100644
--- a/testcases/kernel/syscalls/mremap/mremap06.c
+++ b/testcases/kernel/syscalls/mremap/mremap06.c
@@ -18,15 +18,16 @@
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
+#include <lapi/mmap.h>
#include "tst_test.h"
#include "tst_safe_macros.h"
-#define NUM_PAGES 3
+#define NUM_GRANULARITYS 3
static int fd;
static char *buf, *buf2;
-static int page_size, mmap_size, mremap_size;
+static int mmap_size, mremap_size;
static struct tcase {
size_t incompatible;
@@ -37,11 +38,11 @@ static struct tcase {
},
{
.incompatible = 3,
- .desc = "third page's mapping incompatible",
+ .desc = "third MMAP_GRANULARITY's mapping incompatible",
},
{
.incompatible = 1,
- .desc = "first page's mapping incompatible",
+ .desc = "first MMAP_GRANULARITY's mapping incompatible",
},
};
@@ -51,7 +52,7 @@ static int check_pages(void)
char val;
for (i = 0; i < (int)ARRAY_SIZE(tcases); i++) {
- val = buf[i * page_size];
+ val = buf[i * MMAP_GRANULARITY];
if (val != 0x30 + i) {
tst_res(TFAIL, "page %d wrong value %d (0x%x)", i, val - 0x30, val);
fail = 1;
@@ -70,19 +71,20 @@ static void do_test(unsigned int n)
buf = SAFE_MMAP(0, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- buf2 = mremap(buf + page_size, page_size, page_size,
+ buf2 = mremap(buf + MMAP_GRANULARITY, MMAP_GRANULARITY, MMAP_GRANULARITY,
MREMAP_MAYMOVE|MREMAP_FIXED, buf + mremap_size);
if (buf2 == MAP_FAILED)
tst_brk(TBROK, "mremap() failed");
if (tc->incompatible) {
- ret = mprotect(buf + (tc->incompatible-1)*page_size, page_size, PROT_READ);
+ ret = mprotect(buf + (tc->incompatible-1)*MMAP_GRANULARITY,
+ MMAP_GRANULARITY, PROT_READ);
if (ret == -1)
tst_brk(TBROK, "mprotect() failed");
}
- buf2 = mremap(buf + mremap_size, page_size, page_size,
- MREMAP_MAYMOVE|MREMAP_FIXED, buf + page_size);
+ buf2 = mremap(buf + mremap_size, MMAP_GRANULARITY, MMAP_GRANULARITY,
+ MREMAP_MAYMOVE|MREMAP_FIXED, buf + MMAP_GRANULARITY);
if (buf2 == MAP_FAILED)
tst_brk(TBROK, "mremap() failed");
@@ -96,9 +98,8 @@ static void setup(void)
{
int ret, i;
- page_size = getpagesize();
- mmap_size = (NUM_PAGES+1) * page_size;
- mremap_size = NUM_PAGES * page_size;
+ mmap_size = (NUM_GRANULARITYS+1) * MMAP_GRANULARITY;
+ mremap_size = NUM_GRANULARITYS * MMAP_GRANULARITY;
fd = SAFE_OPEN("testfile", O_CREAT | O_RDWR | O_TRUNC, 0600);
@@ -109,7 +110,7 @@ static void setup(void)
buf = SAFE_MMAP(0, mmap_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
for (i = 0; i < (int)ARRAY_SIZE(tcases)+1; i++)
- buf[i*page_size] = 0x30 + i;
+ buf[i*MMAP_GRANULARITY] = 0x30 + i;
/* clear the page tables */
SAFE_MUNMAP(buf, mmap_size);
diff --git a/testcases/kernel/syscalls/open/open11.c b/testcases/kernel/syscalls/open/open11.c
index 3c3c11b84..3431efc2c 100644
--- a/testcases/kernel/syscalls/open/open11.c
+++ b/testcases/kernel/syscalls/open/open11.c
@@ -1,28 +1,34 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (c) Linux Test Project, 2013-2022
+ */
+
+/*\
+ * [Description]
*
* Basic tests for open(2) and make sure open(2) works and handles error
* conditions correctly.
*
* There are 28 test cases:
+ *
* 1. Open regular file O_RDONLY
* 2. Open regular file O_WRONLY
* 3. Open regular file O_RDWR
* 4. Open regular file O_RDWR | O_SYNC
* 5. Open regular file O_RDWR | O_TRUNC
- * 6. Open dir O_RDONLY
- * 7. Open dir O_RDWR, expect EISDIR
+ * 6. Open directory O_RDONLY
+ * 7. Open directory O_RDWR, expect EISDIR
* 8. Open regular file O_DIRECTORY, expect ENOTDIR
* 9. Open hard link file O_RDONLY
* 10. Open hard link file O_WRONLY
* 11. Open hard link file O_RDWR
- * 12. Open sym link file O_RDONLY
- * 13. Open sym link file O_WRONLY
- * 14. Open sym link file O_RDWR
- * 15. Open sym link dir O_RDONLY
- * 16. Open sym link dir O_WRONLY, expect EISDIR
- * 17. Open sym link dir O_RDWR, expect EISDIR
+ * 12. Open symlink file O_RDONLY
+ * 13. Open symlink file O_WRONLY
+ * 14. Open symlink file O_RDWR
+ * 15. Open symlink directory O_RDONLY
+ * 16. Open symlink directory O_WRONLY, expect EISDIR
+ * 17. Open symlink directory O_RDWR, expect EISDIR
* 18. Open device special file O_RDONLY
* 19. Open device special file O_WRONLY
* 20. Open device special file O_RDWR
@@ -30,8 +36,8 @@
* 22. Open link file O_RDONLY | O_CREAT
* 23. Open symlink file O_RDONLY | O_CREAT
* 24. Open regular file O_RDONLY | O_CREAT
- * 25. Open symlink dir O_RDONLY | O_CREAT, expect EISDIR
- * 26. Open dir O_RDONLY | O_CREAT, expect EISDIR
+ * 25. Open symlink directory O_RDONLY | O_CREAT, expect EISDIR
+ * 26. Open directory O_RDONLY | O_CREAT, expect EISDIR
* 27. Open regular file O_RDONLY | O_TRUNC, behaviour is undefined but should
* not oops or hang
* 28. Open regular file(non-empty) O_RDONLY | O_TRUNC, behaviour is undefined
@@ -54,7 +60,7 @@
#define T_LINK_REG "t_link_reg" /* hard link to T_REG */
#define T_NEW_REG "t_new_reg" /* new regular file to be created */
#define T_SYMLINK_REG "t_symlink_reg" /* symlink to T_REG */
-#define T_DIR "t_dir" /* test dir */
+#define T_DIR "t_dir" /* test directory */
#define T_SYMLINK_DIR "t_symlink_dir" /* symlink to T_DIR */
#define T_DEV MNTPOINT"/t_dev" /* test device special file */
@@ -68,205 +74,191 @@ static struct test_case {
int err;
} tc[] = {
/* Test open(2) regular file */
- { /* open regular file O_RDONLY */
- .desc = "Open regular file O_RDONLY",
+ {
+ .desc = "open regular file O_RDONLY",
.path = T_REG_EMPTY,
.flags = O_RDONLY,
.mode = 0644,
- .err = 0,
},
- { /* open regular file O_WRONLY */
- .desc = "Open regular file O_WRONLY",
+ {
+ .desc = "open regular file O_WRONLY",
.path = T_REG_EMPTY,
.flags = O_WRONLY,
.mode = 0644,
- .err = 0,
},
- { /* open regular file O_RDWR */
- .desc = "Open regular file O_RDWR",
+ {
+ .desc = "open regular file O_RDWR",
.path = T_REG_EMPTY,
.flags = O_RDWR,
.mode = 0644,
- .err = 0,
},
- { /* open regular file O_RDWR | O_SYNC*/
- .desc = "Open regular file O_RDWR | O_SYNC",
+ {
+ .desc = "open regular file O_RDWR | O_SYNC",
.path = T_REG_EMPTY,
.flags = O_RDWR | O_SYNC,
.mode = 0644,
- .err = 0,
},
- { /* open regular file O_RDWR | O_TRUNC */
- .desc = "Open regular file O_RDWR | O_TRUNC",
+ {
+ .desc = "open regular file O_RDWR | O_TRUNC",
.path = T_REG_EMPTY,
.flags = O_RDWR | O_TRUNC,
.mode = 0644,
- .err = 0,
},
+
/* Test open(2) directory */
- { /* open dir O_RDONLY */
- .desc = "Open dir O_RDONLY",
+ {
+ .desc = "open directory O_RDONLY",
.path = T_DIR,
.flags = O_RDONLY,
.mode = 0755,
- .err = 0,
},
- { /* open dir O_RDWR */
- .desc = "Open dir O_RDWR, expect EISDIR",
+ {
+ .desc = "open directory O_RDWR",
.path = T_DIR,
.flags = O_RDWR,
.mode = 0755,
.err = EISDIR,
},
- { /* open regular file O_DIRECTORY */
- .desc = "Open regular file O_DIRECTORY, expect ENOTDIR",
+ {
+ .desc = "open regular file O_DIRECTORY",
.path = T_REG_EMPTY,
.flags = O_RDONLY | O_DIRECTORY,
.mode = 0644,
.err = ENOTDIR,
},
/* Test open(2) hard link */
- { /* open hard link file O_RDONLY */
- .desc = "Open hard link file O_RDONLY",
+ {
+ .desc = "open hard link file O_RDONLY",
.path = T_LINK_REG,
.flags = O_RDONLY,
.mode = 0644,
- .err = 0,
},
- { /* open hard link file O_WRONLY */
- .desc = "Open hard link file O_WRONLY",
+ {
+ .desc = "open hard link file O_WRONLY",
.path = T_LINK_REG,
.flags = O_WRONLY,
.mode = 0644,
- .err = 0,
},
- { /* open hard link file O_RDWR */
- .desc = "Open hard link file O_RDWR",
+ {
+ .desc = "open hard link file O_RDWR",
.path = T_LINK_REG,
.flags = O_RDWR,
.mode = 0644,
- .err = 0,
},
- /* Test open(2) sym link */
- { /* open sym link file O_RDONLY */
- .desc = "Open sym link file O_RDONLY",
+
+ /* Test open(2) symlink */
+ {
+ .desc = "open symlink file O_RDONLY",
.path = T_SYMLINK_REG,
.flags = O_RDONLY,
.mode = 0644,
- .err = 0,
},
- { /* open sym link file O_WRONLY */
- .desc = "Open sym link file O_WRONLY",
+ {
+ .desc = "open symlink file O_WRONLY",
.path = T_SYMLINK_REG,
.flags = O_WRONLY,
.mode = 0644,
- .err = 0,
},
- { /* open sym link file O_RDWR */
- .desc = "Open sym link file O_RDWR",
+ {
+ .desc = "open symlink file O_RDWR",
.path = T_SYMLINK_REG,
.flags = O_RDWR,
.mode = 0644,
- .err = 0,
},
- { /* open sym link dir O_RDONLY */
- .desc = "Open sym link dir O_RDONLY",
+ {
+ .desc = "open symlink directory O_RDONLY",
.path = T_SYMLINK_DIR,
.flags = O_RDONLY,
.mode = 0644,
- .err = 0,
},
- { /* open sym link dir O_WRONLY */
- .desc = "Open sym link dir O_WRONLY, expect EISDIR",
+ {
+ .desc = "open symlink directory O_WRONLY",
.path = T_SYMLINK_DIR,
.flags = O_WRONLY,
.mode = 0644,
.err = EISDIR,
},
- { /* open sym link dir O_RDWR */
- .desc = "Open sym link dir O_RDWR, expect EISDIR",
+ {
+ .desc = "open symlink directory O_RDWR",
.path = T_SYMLINK_DIR,
.flags = O_RDWR,
.mode = 0644,
.err = EISDIR,
},
- /* * Test open(2) device special */
- { /* open device special file O_RDONLY */
- .desc = "Open device special file O_RDONLY",
+
+ /* Test open(2) device special */
+ {
+ .desc = "open device special file O_RDONLY",
.path = T_DEV,
.flags = O_RDONLY,
.mode = 0644,
- .err = 0,
},
- { /* open device special file O_WRONLY */
- .desc = "Open device special file O_WRONLY",
+ {
+ .desc = "open device special file O_WRONLY",
.path = T_DEV,
.flags = O_WRONLY,
.mode = 0644,
- .err = 0,
},
- { /* open device special file O_RDWR */
- .desc = "Open device special file O_RDWR",
+ {
+ .desc = "open device special file O_RDWR",
.path = T_DEV,
.flags = O_RDWR,
.mode = 0644,
- .err = 0,
},
- /* * Test open(2) non-existing file */
- { /* open non-existing regular file in existing dir */
- .desc = "Open non-existing regular file in existing dir",
+
+ /* Test open(2) non-existing file */
+ {
+ .desc = "open non-existing regular file in existing dir",
.path = T_DIR"/"T_NEW_REG,
.flags = O_RDWR | O_CREAT,
.mode = 0644,
- .err = 0,
},
+
/* test open(2) with O_CREAT */
- { /* open hard link file O_RDONLY | O_CREAT */
- .desc = "Open link file O_RDONLY | O_CREAT",
+ {
+ .desc = "open link file O_RDONLY | O_CREAT",
.path = T_LINK_REG,
.flags = O_RDONLY | O_CREAT,
.mode = 0644,
- .err = 0,
},
- { /* open sym link file O_RDONLY | O_CREAT */
- .desc = "Open symlink file O_RDONLY | O_CREAT",
+ {
+ .desc = "open symlink file O_RDONLY | O_CREAT",
.path = T_SYMLINK_REG,
.flags = O_RDONLY | O_CREAT,
.mode = 0644,
- .err = 0,
},
- { /* open regular file O_RDONLY | O_CREAT */
- .desc = "Open regular file O_RDONLY | O_CREAT",
+ {
+ .desc = "open regular file O_RDONLY | O_CREAT",
.path = T_REG_EMPTY,
.flags = O_RDONLY | O_CREAT,
.mode = 0644,
- .err = 0,
},
- { /* open symlink dir O_RDONLY | O_CREAT */
- .desc = "Open symlink dir O_RDONLY | O_CREAT, expect EISDIR",
+ {
+ .desc = "open symlink directory O_RDONLY | O_CREAT",
.path = T_SYMLINK_DIR,
.flags = O_RDONLY | O_CREAT,
.mode = 0644,
.err = EISDIR,
},
- { /* open dir O_RDONLY | O_CREAT */
- .desc = "Open dir O_RDONLY | O_CREAT, expect EISDIR",
+ {
+ .desc = "open directory O_RDONLY | O_CREAT",
.path = T_DIR,
.flags = O_RDONLY | O_CREAT,
.mode = 0644,
.err = EISDIR,
},
+
/* Other random open(2) tests */
- { /* open regular file O_RDONLY | O_TRUNC */
- .desc = "Open regular file O_RDONLY | O_TRUNC, "
+ {
+ .desc = "open regular file O_RDONLY | O_TRUNC, "
"behaviour is undefined but should not oops or hang",
.path = T_REG_EMPTY,
.flags = O_RDONLY | O_TRUNC,
.mode = 0644,
.err = -1,
},
- { /* open regular(non-empty) file O_RDONLY | O_TRUNC */
- .desc = "Open regular file(non-empty) O_RDONLY | O_TRUNC, "
+ {
+ .desc = "open regular file(non-empty) O_RDONLY | O_TRUNC, "
"behaviour is undefined but should not oops or hang",
.path = T_REG,
.flags = O_RDONLY | O_TRUNC,
diff --git a/testcases/kernel/syscalls/pathconf/.gitignore b/testcases/kernel/syscalls/pathconf/.gitignore
index 31abe8a28..82e38b253 100644
--- a/testcases/kernel/syscalls/pathconf/.gitignore
+++ b/testcases/kernel/syscalls/pathconf/.gitignore
@@ -1 +1,2 @@
/pathconf01
+/pathconf02
diff --git a/testcases/kernel/syscalls/pathconf/pathconf01.c b/testcases/kernel/syscalls/pathconf/pathconf01.c
index 362bae94f..66b8d1fc1 100644
--- a/testcases/kernel/syscalls/pathconf/pathconf01.c
+++ b/testcases/kernel/syscalls/pathconf/pathconf01.c
@@ -1,237 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * Copyright (c) Linux Test Project, 2000-2023
+ * Authors: William Roske, Dave Fenner
*/
-/* $Id: pathconf01.c,v 1.5 2009/11/02 13:57:17 subrata_modak Exp $ */
-/**********************************************************
- *
- * OS Test - Silicon Graphics, Inc.
- *
- * TEST IDENTIFIER : pathconf01
- *
- * EXECUTED BY : anyone
- *
- * TEST TITLE : Basic test for pathconf(2)
- *
- * PARENT DOCUMENT : usctpl01
- *
- * TEST CASE TOTAL : 6
- *
- * WALL CLOCK TIME : 1
- *
- * CPU TYPES : ALL
- *
- * AUTHOR : William Roske
- *
- * CO-PILOT : Dave Fenner
- *
- * DATE STARTED : 03/30/92
- *
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- *
- * 1.) pathconf(2) returns...(See Description)
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * OUTPUT SPECIFICATIONS
- *
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * RESOURCES
- * None
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * SPECIAL PROCEDURAL REQUIREMENTS
- * None
- *
- * INTERCASE DEPENDENCIES
- * None
- *
- * DETAILED DESCRIPTION
- * This is a Phase I test for the pathconf(2) system call. It is intended
- * to provide a limited exposure of the system call, for now. It
- * should/will be extended when full functional tests are written for
- * pathconf(2).
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
-
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-void setup();
-void cleanup();
-void help();
-
-struct pathconf_args {
- char *define_tag;
- int value;
-} args[] = {
- {
- "_PC_LINK_MAX", _PC_LINK_MAX}, {
- "_PC_NAME_MAX", _PC_NAME_MAX}, {
- "_PC_PATH_MAX", _PC_PATH_MAX}, {
- "_PC_PIPE_BUF", _PC_PIPE_BUF}, {
- "_PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, {
- "_PC_NO_TRUNC", _PC_NO_TRUNC}, {
- NULL, 0}
-};
-
-char *TCID = "pathconf01";
-int TST_TOTAL = ARRAY_SIZE(args);
+/*\
+ * [Description]
+ *
+ * Check the basic functionality of the pathconf(2) system call.
+ */
-int i;
+#include <stdlib.h>
+#include "tst_test.h"
+#define NAME_DESC(x) .value = x, .name = #x
-int lflag;
-char *path;
+static char *path;
-option_t options[] = {
- {"l:", &lflag, &path}, /* -l <path to test> */
- {NULL, NULL, NULL}
+static struct tcase {
+ int value;
+ char *name;
+} tcases[] = {
+ {NAME_DESC(_PC_LINK_MAX)},
+ {NAME_DESC(_PC_MAX_CANON)},
+ {NAME_DESC(_PC_MAX_INPUT)},
+ {NAME_DESC(_PC_NAME_MAX)},
+ {NAME_DESC(_PC_PATH_MAX)},
+ {NAME_DESC(_PC_PIPE_BUF)},
+ {NAME_DESC(_PC_CHOWN_RESTRICTED)},
+ {NAME_DESC(_PC_NO_TRUNC)},
+ {NAME_DESC(_PC_VDISABLE)},
+ {NAME_DESC(_PC_SYNC_IO)},
+ {NAME_DESC(_PC_ASYNC_IO)},
+ {NAME_DESC(_PC_PRIO_IO)},
+ {NAME_DESC(_PC_FILESIZEBITS)},
+ {NAME_DESC(_PC_REC_INCR_XFER_SIZE)},
+ {NAME_DESC(_PC_REC_MAX_XFER_SIZE)},
+ {NAME_DESC(_PC_REC_MIN_XFER_SIZE)},
+ {NAME_DESC(_PC_REC_XFER_ALIGN)},
};
-int main(int ac, char **av)
+static void verify_pathconf(unsigned int i)
{
- int lc;
+ struct tcase *tc = &tcases[i];
- tst_parse_opts(ac, av, options, &help);
+ path = tst_get_tmpdir();
- if (!lflag) {
- tst_tmpdir();
- path = tst_get_tmpdir();
- }
- /***************************************************************
- * perform global setup for test
- ***************************************************************/
- setup();
+ TEST(pathconf(path, tc->value));
- /***************************************************************
- * check looping state if -c option given
- ***************************************************************/
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- for (i = 0; i < TST_TOTAL; i++) {
-
- errno = -4;
-
- /*
- * Call pathconf(2)
- */
- TEST(pathconf(path, args[i].value));
-
- /*
- * A test case can only fail if -1 is returned and the errno
- * was set. If the errno remains unchanged, the
- * system call did not fail.
- */
- if (TEST_RETURN == -1 && errno != -4) {
- tst_resm(TFAIL,
- "pathconf(%s, %s) Failed, errno=%d : %s",
- path, args[i].define_tag, TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- tst_resm(TPASS,
- "pathconf(%s, %s) returned %ld",
- path, args[i].define_tag,
- TEST_RETURN);
- }
- }
- }
-
- /***************************************************************
- * cleanup and exit
- ***************************************************************/
- cleanup();
-
- tst_exit();
+ if (TST_RET == -1 && errno != 0)
+ tst_res(TFAIL, "pathconf Failed, errno = %d", TST_ERR);
+ else
+ tst_res(TPASS, "pathconf(%s, %s)", path, tc->name);
}
-/***************************************************************
- * setup() - performs all ONE TIME setup for this test.
- ***************************************************************/
-void setup(void)
+static void cleanup(void)
{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-}
-
-/***************************************************************
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- ***************************************************************/
-void cleanup(void)
-{
- if (!lflag) {
- tst_rmdir();
- free(path);
- }
+ free(path);
}
-/***************************************************************
- * help
- ***************************************************************/
-void help(void)
-{
- printf(" -l path a path to test with pathconf(2) (def: /tmp)\n");
-}
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .test = verify_pathconf,
+ .tcnt = ARRAY_SIZE(tcases),
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/pathconf/pathconf02.c b/testcases/kernel/syscalls/pathconf/pathconf02.c
new file mode 100644
index 000000000..3fb2cdbe8
--- /dev/null
+++ b/testcases/kernel/syscalls/pathconf/pathconf02.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 FUJITSU LIMITED. All rights reserved.
+ * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that,
+ *
+ * - pathconf() fails with ENOTDIR if a component used as a directory
+ * in path is not in fact a directory.
+ * - pathconf() fails with ENOENT if path is an empty string.
+ * - pathconf() fails with ENAMETOOLONG if path is too long.
+ * - pathconf() fails with EINVA if name is invalid.
+ * - pathconf() fails with EACCES if search permission is denied for
+ * one of the directories in the path prefix of path.
+ * - pathconf() fails with ELOOP if too many symbolic links were
+ * encountered while resolving path.
+ */
+
+#define FILEPATH "testfile/testfile_1"
+#define TESTELOOP "test_eloop1"
+#define PATH_LEN (PATH_MAX + 2)
+
+#include <stdlib.h>
+#include <pwd.h>
+#include "tst_test.h"
+
+static char *fpath;
+static char *emptypath;
+static char path[PATH_LEN];
+static char *long_path = path;
+static char *abs_path;
+static char *testeloop;
+static struct passwd *user;
+
+static struct tcase {
+ char **path;
+ int name;
+ int exp_errno;
+ char *desc;
+} tcases[] = {
+ {&fpath, 0, ENOTDIR, "path prefix is not a directory"},
+ {&emptypath, 0, ENOENT, "path is an empty string"},
+ {&long_path, 0, ENAMETOOLONG, "path is too long"},
+ {&abs_path, -1, EINVAL, "name is invalid"},
+ {&abs_path, 0, EACCES, "without full permissions of the path prefix"},
+ {&testeloop, 0, ELOOP, "too many symbolic links"},
+};
+
+static void verify_fpathconf(unsigned int i)
+{
+ struct tcase *tc = &tcases[i];
+
+ if (tc->exp_errno == EACCES)
+ SAFE_SETEUID(user->pw_uid);
+
+ TST_EXP_FAIL(pathconf(*tc->path, tc->name), tc->exp_errno,
+ "pathconf() fail with %s", tc->desc);
+
+ if (tc->exp_errno == EACCES)
+ SAFE_SETEUID(0);
+}
+
+static void setup(void)
+{
+ user = SAFE_GETPWNAM("nobody");
+
+ SAFE_TOUCH("testfile", 0777, NULL);
+
+ char *tmpdir = tst_get_tmpdir();
+
+ abs_path = tst_aprintf("%s/%s", tmpdir, FILEPATH);
+
+ SAFE_CHMOD(tmpdir, 0);
+ free(tmpdir);
+
+ memset(path, 'a', PATH_LEN);
+
+ SAFE_SYMLINK("test_eloop1", "test_eloop2");
+ SAFE_SYMLINK("test_eloop2", "test_eloop1");
+}
+
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcases),
+ .test = verify_fpathconf,
+ .setup = setup,
+ .needs_tmpdir = 1,
+ .bufs = (struct tst_buffers []) {
+ {&fpath, .str = FILEPATH},
+ {&emptypath, .str = ""},
+ {&testeloop, .str = TESTELOOP},
+ {},
+ },
+ .needs_root = 1,
+};
diff --git a/testcases/kernel/syscalls/pipe/.gitignore b/testcases/kernel/syscalls/pipe/.gitignore
index 774d73205..581a68b78 100644
--- a/testcases/kernel/syscalls/pipe/.gitignore
+++ b/testcases/kernel/syscalls/pipe/.gitignore
@@ -12,3 +12,4 @@
/pipe12
/pipe13
/pipe14
+/pipe15
diff --git a/testcases/kernel/syscalls/pipe/pipe15.c b/testcases/kernel/syscalls/pipe/pipe15.c
new file mode 100644
index 000000000..c85ad1820
--- /dev/null
+++ b/testcases/kernel/syscalls/pipe/pipe15.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 SUSE LLC Marius Kittler <mkittler@suse.de>
+ */
+
+/*\
+ * [Description]
+ *
+ * This is a regression test for hangup on pipe operations. See
+ * https://www.spinics.net/lists/linux-api/msg49762.html for
+ * additional context. It tests that pipe operations do not block
+ * indefinitely when going to the soft limit on the total size of
+ * all pipes created by a single user.
+ */
+
+#define _GNU_SOURCE
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+#include "tst_safe_macros.h"
+
+static int pipe_count;
+static int *pipes;
+static char *buffer;
+
+static void run(void)
+{
+ const int *const pipe = pipes + 2 * (pipe_count - 1);
+ const int buffer_size = SAFE_FCNTL(pipe[1], F_GETPIPE_SZ);
+
+ tst_res(TINFO, "Soft-limited buffer size: %d bytes", buffer_size);
+ SAFE_WRITE(1, pipe[1], buffer, buffer_size);
+ SAFE_READ(1, pipe[0], buffer, buffer_size - 1);
+ SAFE_WRITE(1, pipe[1], buffer, 1);
+ tst_res(TPASS, "Pipe operation did not block");
+
+ SAFE_READ(1, pipe[0], buffer, 2);
+}
+
+static void setup(void)
+{
+ int pipe[2];
+ int page_size = getpagesize(), soft_limit;
+ struct rlimit nfd;
+
+ SAFE_PIPE(pipe);
+ const int buffer_size = SAFE_FCNTL(pipe[1], F_GETPIPE_SZ);
+ SAFE_CLOSE(pipe[0]);
+ SAFE_CLOSE(pipe[1]);
+
+ SAFE_FILE_SCANF("/proc/sys/fs/pipe-user-pages-soft", "%i", &soft_limit);
+ pipe_count = soft_limit * page_size / buffer_size;
+
+ tst_res(TINFO, "Soft limit for pipes: %i pages", soft_limit);
+ tst_res(TINFO, "Buffer size: %d byte", buffer_size);
+ tst_res(TINFO, "Creating %i pipes", pipe_count);
+
+ SAFE_GETRLIMIT(RLIMIT_NOFILE, &nfd);
+ if (nfd.rlim_max < (unsigned long)pipe_count)
+ tst_brk(TCONF, "NOFILE limit max too low: %lu < %i", nfd.rlim_max, pipe_count);
+ if (nfd.rlim_cur < nfd.rlim_max) {
+ nfd.rlim_cur = nfd.rlim_max;
+ SAFE_SETRLIMIT(RLIMIT_NOFILE, &nfd);
+ }
+
+ buffer = SAFE_MALLOC(buffer_size);
+ pipes = SAFE_MALLOC(pipe_count * 2 * sizeof(int));
+ for (int i = 0; i < pipe_count; ++i)
+ SAFE_PIPE(pipes + i * 2);
+
+}
+
+static void cleanup(void)
+{
+ for (int i = 0; i < pipe_count * 2; i++)
+ if (pipes[i] > 0)
+ SAFE_CLOSE(pipes[i]);
+ if (pipes)
+ free(pipes);
+ if (buffer)
+ free(buffer);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+ .cleanup = cleanup,
+ .tags = (const struct tst_tag[]){
+ {"linux-git", "46c4c9d1beb7"},
+ },
+};
diff --git a/testcases/kernel/syscalls/preadv/preadv.h b/testcases/kernel/syscalls/preadv/preadv.h
index 73466a9aa..c715715b1 100644
--- a/testcases/kernel/syscalls/preadv/preadv.h
+++ b/testcases/kernel/syscalls/preadv/preadv.h
@@ -1,18 +1,9 @@
-/*
-* Copyright (c) 2015 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License as
-* published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it would be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-*
-* You should have received a copy of the GNU General Public License
-* alone with this program.
-*/
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2016-2023
+ */
#ifndef PREADV_H
#define PREADV_H
diff --git a/testcases/kernel/syscalls/preadv/preadv01.c b/testcases/kernel/syscalls/preadv/preadv01.c
index 62f9296f2..871b3ab42 100644
--- a/testcases/kernel/syscalls/preadv/preadv01.c
+++ b/testcases/kernel/syscalls/preadv/preadv01.c
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) 2015 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*/
-
-/*
-* Test Name: preadv01
-*
-* Test Description:
-* Testcase to check the basic functionality of the preadv(2).
-* Preadv(2) should succeed to read the expected content of data
-* and after reading the file, the file offset is not changed.
-*/
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2016-2023
+ */
+
+/*\
+ * [Description]
+ *
+ * Testcase to check the basic functionality of the preadv(2).
+ *
+ * Preadv(2) should succeed to read the expected content of data
+ * and after reading the file, the file offset is not changed.
+ */
#define _GNU_SOURCE
@@ -38,7 +39,7 @@ static struct tcase {
{1, CHUNK*3/2, CHUNK/2, 'b'}
};
-void verify_preadv(unsigned int n)
+static void verify_preadv(unsigned int n)
{
int i;
char *vec;
@@ -81,7 +82,7 @@ void verify_preadv(unsigned int n)
"with content '%c' expectedly", tc->size, tc->content);
}
-void setup(void)
+static void setup(void)
{
char buf[CHUNK];
@@ -94,7 +95,7 @@ void setup(void)
SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, sizeof(buf));
}
-void cleanup(void)
+static void cleanup(void)
{
if (fd > 0)
SAFE_CLOSE(fd);
diff --git a/testcases/kernel/syscalls/preadv/preadv02.c b/testcases/kernel/syscalls/preadv/preadv02.c
index 500059e42..9977a4f48 100644
--- a/testcases/kernel/syscalls/preadv/preadv02.c
+++ b/testcases/kernel/syscalls/preadv/preadv02.c
@@ -1,32 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) 2015-2016 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*/
-
-/*
-* Test Name: preadv02
-*
-* Description:
-* 1) preadv(2) fails if iov_len is invalid.
-* 2) preadv(2) fails if the vector count iovcnt is less than zero.
-* 3) preadv(2) fails if offset is negative.
-* 4) preadv(2) fails when attempts to read into a invalid address.
-* 5) preadv(2) fails if file descriptor is invalid.
-* 6) preadv(2) fails if file descriptor is not open for reading.
-* 7) preadv(2) fails when fd refers to a directory.
-* 8) preadv(2) fails if fd is associated with a pipe.
-*
-* Expected Result:
-* 1) preadv(2) should return -1 and set errno to EINVAL.
-* 2) preadv(2) should return -1 and set errno to EINVAL.
-* 3) preadv(2) should return -1 and set errno to EINVAL.
-* 4) preadv(2) should return -1 and set errno to EFAULT.
-* 5) preadv(2) should return -1 and set errno to EBADF.
-* 6) preadv(2) should return -1 and set errno to EBADF.
-* 7) preadv(2) should return -1 and set errno to EISDIR.
-* 8) preadv(2) should return -1 and set errno to ESPIPE.
-*/
+ * Copyright (c) 2015-2016 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2017-2023
+ */
+
+/*\
+ * [Description]
+ *
+ * - EINVAL when iov_len is invalid.
+ * - EINVAL when the vector count iovcnt is less than zero.
+ * - EINVAL when offset is negative.
+ * - EFAULT when attempts to read into a invalid address.
+ * - EBADF when file descriptor is invalid.
+ * - EBADF when file descriptor is not open for reading.
+ * - EISDIR when fd refers to a directory.
+ * - ESPIPE when fd is associated with a pipe.
+ */
#define _GNU_SOURCE
diff --git a/testcases/kernel/syscalls/preadv/preadv03.c b/testcases/kernel/syscalls/preadv/preadv03.c
index d4595dda6..558d85050 100644
--- a/testcases/kernel/syscalls/preadv/preadv03.c
+++ b/testcases/kernel/syscalls/preadv/preadv03.c
@@ -2,12 +2,15 @@
/*
* Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2019-2023
*/
-/*
- * Description:
+/*\
+ * [Description]
+ *
* Check the basic functionality of the preadv(2) for the file
* opened with O_DIRECT in all filesystem.
+ *
* preadv(2) should succeed to read the expected content of data
* and after reading the file, the file offset is not changed.
*/
diff --git a/testcases/kernel/syscalls/ptrace/.gitignore b/testcases/kernel/syscalls/ptrace/.gitignore
index 01cbc6072..1ee6117e9 100644
--- a/testcases/kernel/syscalls/ptrace/.gitignore
+++ b/testcases/kernel/syscalls/ptrace/.gitignore
@@ -3,6 +3,7 @@
/ptrace03
/ptrace04
/ptrace05
+/ptrace06
/ptrace07
/ptrace08
/ptrace09
diff --git a/testcases/kernel/syscalls/ptrace/Makefile b/testcases/kernel/syscalls/ptrace/Makefile
index 9ee7b8374..d7eca6837 100644
--- a/testcases/kernel/syscalls/ptrace/Makefile
+++ b/testcases/kernel/syscalls/ptrace/Makefile
@@ -1,34 +1,9 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) Linux Test Project, 2002-2023
# Copyright (c) International Business Machines Corp., 2001
top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-# - ptrace06 is a broken test ; it hangs the target consistently, chewing up
-# CPU. See: `Issue 3 - ptrace06 hung for 7 hours' --
-# http://sourceforge.net/mailarchive/forum.php?thread_name=364299f40910062300s65c43c93w9cccdfe8835c2334%40mail.gmail.com&forum_name=ltp-list
-# - simple_tracer is a utility that Mike Frysinger added that shouldn't be
-# compiled by default:
-#
-# gcc -g -O2 -g -O2 -fno-strict-aliasing -pipe -Wall
-# -I//scratch/ltp-install6/include -I../../../../include
-# -L//scratch/ltp-install6/lib simple_tracer.c -laio -lltp -o
-# simple_tracer
-# In file included from simple_tracer.c:25:
-# syscalls.h:6:23: error: _syscalls.h: No such file or directory
-# make[4]: *** [simple_tracer] Error 1
-# make[4]: Leaving directory
-# `/scratch/ltp-dev2/ltp/testcases/kernel/syscalls/ptrace'
-# make[3]: *** [all] Error 2
-# make[3]: Leaving directory `/scratch/ltp-dev2/ltp/testcases/kernel/syscalls'
-# make[2]: *** [all] Error 2
-# make[2]: Leaving directory `/scratch/ltp-dev2/ltp/testcases/kernel'
-# make[1]: *** [all] Error 2
-# make[1]: Leaving directory `/scratch/ltp-dev2/ltp/testcases'
-# make: *** [testcases-all] Error 2
-#
-
-FILTER_OUT_MAKE_TARGETS := ptrace06 simple_tracer
-
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/ptrace/make_syscall_list.sh b/testcases/kernel/syscalls/ptrace/make_syscall_list.sh
deleted file mode 100755
index e5d6d2765..000000000
--- a/testcases/kernel/syscalls/ptrace/make_syscall_list.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-set -- $( \
- printf '#include <sys/syscall.h>' | \
- ${CC:-gcc} -E -dD - | \
- awk '$2 ~ /^SYS_/ { sub(/SYS_/,"",$2); print $2; }'
-)
-printf 'P(%s)\n' "$@"
diff --git a/testcases/kernel/syscalls/ptrace/ptrace.h b/testcases/kernel/syscalls/ptrace/ptrace.h
deleted file mode 100644
index 4a43f01ef..000000000
--- a/testcases/kernel/syscalls/ptrace/ptrace.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * ptrace is a fickle beast and each arch sucks in a different way
- */
-
-#ifndef __LTP_PTRACE_H__
-#define __LTP_PTRACE_H__
-
-#ifdef HAVE_SYS_PTRACE_H
-# include <sys/ptrace.h>
-#endif
-#ifdef HAVE_SYS_REG_H
-# include <sys/reg.h>
-#endif
-#ifdef __ia64__ /* what a pos */
-# define ia64_fpreg FU_ia64_fpreg
-# define pt_all_user_regs FU_pt_all_user_regs
-#endif
-#ifdef HAVE_ASM_PTRACE_H
-# include <asm/ptrace.h>
-#endif
-#ifdef HAVE_LINUX_PTRACE_H
-# ifndef HAVE_STRUCT_PTRACE_PEEKSIGINFO_ARGS
-# include <linux/ptrace.h>
-# endif
-#endif
-#undef FU_ia64_fpreg
-#undef FU_pt_all_user_regs
-
-#if defined(HAVE_STRUCT_PT_REGS)
-typedef struct pt_regs ptrace_regs;
-#elif defined(HAVE_STRUCT_USER_REGS_STRUCT)
-typedef struct user_regs_struct ptrace_regs;
-#endif
-
-#endif
diff --git a/testcases/kernel/syscalls/ptrace/ptrace01.c b/testcases/kernel/syscalls/ptrace/ptrace01.c
index 9071bbaba..53ddfb393 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace01.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace01.c
@@ -26,8 +26,7 @@
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
-#include <config.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "tst_test.h"
static struct tcase {
diff --git a/testcases/kernel/syscalls/ptrace/ptrace02.c b/testcases/kernel/syscalls/ptrace/ptrace02.c
index e330f459e..a48ef58a5 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace02.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace02.c
@@ -11,9 +11,8 @@
#include <signal.h>
#include <sys/wait.h>
#include <pwd.h>
-#include <config.h>
#include <stdlib.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "tst_test.h"
uid_t uid;
diff --git a/testcases/kernel/syscalls/ptrace/ptrace03.c b/testcases/kernel/syscalls/ptrace/ptrace03.c
index b2b3fb49d..42ac3e7cf 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace03.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace03.c
@@ -14,9 +14,8 @@
#include <signal.h>
#include <sys/wait.h>
#include <pwd.h>
-#include <config.h>
#include <stdlib.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "tst_test.h"
static pid_t unused_pid;
diff --git a/testcases/kernel/syscalls/ptrace/ptrace04.c b/testcases/kernel/syscalls/ptrace/ptrace04.c
index af35fb3a2..8f1b5c6cc 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace04.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace04.c
@@ -13,9 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-
-#include <config.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "test.h"
#include "spawn_ptrace_child.h"
@@ -49,7 +47,7 @@ int TST_TOTAL = 2;
void compare_registers(unsigned char poison)
{
-#ifdef HAVE_STRUCT_PTRACE_REGS
+#if defined(HAVE_STRUCT_PTRACE_REGS) && defined(PTRACE_GETREGS)
ptrace_regs _pt_regs;
size_t i;
long ret;
diff --git a/testcases/kernel/syscalls/ptrace/ptrace05.c b/testcases/kernel/syscalls/ptrace/ptrace05.c
index 54cfa4d7b..541018393 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace05.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace05.c
@@ -33,9 +33,7 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-
-#include <config.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "test.h"
#include "lapi/signal.h"
diff --git a/testcases/kernel/syscalls/ptrace/ptrace06.c b/testcases/kernel/syscalls/ptrace/ptrace06.c
index c0cb3b9bd..a1db3bab8 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace06.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace06.c
@@ -16,13 +16,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-
-#include <config.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "test.h"
#include "spawn_ptrace_child.h"
-#include "config.h"
/* this should be sizeof(struct user), but that info is only found
* in the kernel asm/user.h which is not exported to userspace.
diff --git a/testcases/kernel/syscalls/ptrace/ptrace07.c b/testcases/kernel/syscalls/ptrace/ptrace07.c
index 362cee543..a78243671 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace07.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace07.c
@@ -35,9 +35,8 @@
#include <stdlib.h>
#include <sys/uio.h>
#include <sys/wait.h>
+#include <sys/ptrace.h>
-#include "config.h"
-#include "ptrace.h"
#include "tst_safe_macros.h"
#include "lapi/cpuid.h"
diff --git a/testcases/kernel/syscalls/ptrace/ptrace11.c b/testcases/kernel/syscalls/ptrace/ptrace11.c
index c54441671..90154852f 100644
--- a/testcases/kernel/syscalls/ptrace/ptrace11.c
+++ b/testcases/kernel/syscalls/ptrace/ptrace11.c
@@ -16,9 +16,8 @@
#include <signal.h>
#include <sys/wait.h>
#include <pwd.h>
-#include <config.h>
#include <stdlib.h>
-#include "ptrace.h"
+#include <sys/ptrace.h>
#include "tst_test.h"
static void verify_ptrace(void)
diff --git a/testcases/kernel/syscalls/ptrace/simple_tracer.c b/testcases/kernel/syscalls/ptrace/simple_tracer.c
deleted file mode 100644
index ae1af7c2f..000000000
--- a/testcases/kernel/syscalls/ptrace/simple_tracer.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * simple example ptrace() code to help build basis for other tests
- *
- * Copyright (c) 2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#define _GNU_SOURCE
-
-#include <config.h>
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ptrace.h>
-#include <sys/syscall.h>
-#include "ptrace.h"
-
-#include "test.h"
-#include "spawn_ptrace_child.h"
-
-#include "syscalls.h"
-
-char *TCID = "simple_tracer";
-int TST_TOTAL = 0;
-
-#define _decode(name, val) \
-({ \
- if (sizeof(long) == 4) \
- printf(name ":%08lx ", val); \
- else if (sizeof(long) == 8) \
- printf(name ":%016lx ", val); \
- else \
- printf(name ":%lx ", val); \
- val; \
-})
-#define decode(reg) _decode(#reg, pt->reg)
-#define decode_user(name, offset) \
- _decode(name, vptrace(PTRACE_PEEKUSER, pid, offset, NULL));
-#define decode_sysnum(nr) printf("%s ", get_sysnum(nr))
-static void decode_regs(struct pt_regs *pt)
-{
-#if defined(__bfin__)
- long nr = decode_user("orig_p0", PT_ORIG_P0);
- decode(p0);
- decode(r0);
- decode(r1);
- decode(r2);
- decode(r3);
- decode(r4);
- decode(r5);
- decode_sysnum(nr);
- puts("");
-#elif defined(__i386__)
- long nr = decode_user("orig_eax", 4 * ORIG_EAX);
- decode(eax);
- decode(ebx);
- decode(ecx);
- decode(edx);
- decode(esi);
- decode(edi);
- decode(ebp);
- decode_sysnum(nr);
- puts("");
-#elif defined(__x86_64__)
- long nr = decode_user("orig_rax", 8 * ORIG_RAX);
- decode(rax);
- decode(rbx);
- decode(rcx);
- decode(rdx);
- decode(rsi);
- decode(rdi);
- decode(rbp);
- decode_sysnum(nr);
- puts("");
-#elif defined(__sparc__)
-#define G1 u_regs[0]
-#define G2 u_regs[1]
-#define G3 u_regs[2]
-#define G4 u_regs[3]
-#define G5 u_regs[4]
-#define G6 u_regs[5]
-#define G7 u_regs[6]
-#define O0 u_regs[7]
-#define O1 u_regs[8]
-#define O2 u_regs[9]
-#define O3 u_regs[10]
-#define O4 u_regs[11]
-#define O5 u_regs[12]
-#define O6 u_regs[13]
-#define O7 u_regs[14]
- decode(G1);
- decode(G2);
- decode(G3);
- decode(G4);
- decode(G5);
- decode(G6);
- decode(G7);
- decode(O0);
- decode(O1);
- decode(O2);
- decode(O3);
- decode(O4);
- decode(O5);
- decode(O6);
- decode(O7);
- decode_sysnum(pt->G1);
- puts("");
-#else
-#warning "no idea how to decode your arch"
- puts("no idea how to decode your arch");
-#endif
-}
-
-int main(int argc, char *argv[])
-{
- struct pt_regs pt_regs;
- long ret;
- int status;
-
- make_a_baby(argc, argv);
-
- while (1) {
- ret = vptrace(PTRACE_GETREGS, pid, NULL, &pt_regs);
- if (ret)
- break;
- decode_regs(&pt_regs);
-
- ret = vptrace(PTRACE_SYSCALL, pid, NULL, NULL);
- if (ret)
- break;
-
- if (waitpid(pid, &status, 0) == -1)
- break;
- }
-
- /* hopefully this worked */
- vptrace(PTRACE_KILL, pid, NULL, NULL);
-
- tst_exit();
-}
diff --git a/testcases/kernel/syscalls/ptrace/syscalls.h b/testcases/kernel/syscalls/ptrace/syscalls.h
deleted file mode 100644
index 2d9c5ceb6..000000000
--- a/testcases/kernel/syscalls/ptrace/syscalls.h
+++ /dev/null
@@ -1,17 +0,0 @@
-const struct sysnums {
- long nr;
- const char *snr;
-} sysnums[] = {
-#define P(NR) { .nr = SYS_##NR, .snr = #NR, },
-#include "_syscalls.h"
-#undef P
-};
-
-const char *get_sysnum(long nr)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(sysnums); ++i)
- if (sysnums[i].nr == nr)
- break;
- return i == ARRAY_SIZE(sysnums) ? "???" : sysnums[i].snr;
-}
diff --git a/testcases/kernel/syscalls/pwritev/pwritev.h b/testcases/kernel/syscalls/pwritev/pwritev.h
index 833160ddb..e657dc7e6 100644
--- a/testcases/kernel/syscalls/pwritev/pwritev.h
+++ b/testcases/kernel/syscalls/pwritev/pwritev.h
@@ -1,18 +1,9 @@
-/*
-* Copyright (c) 2015 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License as
-* published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it would be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-*
-* You should have received a copy of the GNU General Public License
-* alone with this program.
-*/
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2016-2023
+ */
#ifndef PWRITEV_H
#define PWRITEV_H
diff --git a/testcases/kernel/syscalls/pwritev/pwritev01.c b/testcases/kernel/syscalls/pwritev/pwritev01.c
index 66358f7c4..f5fce81f2 100644
--- a/testcases/kernel/syscalls/pwritev/pwritev01.c
+++ b/testcases/kernel/syscalls/pwritev/pwritev01.c
@@ -1,17 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) 2015 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*/
-
-/*
-* Test Name: pwritev01
-*
-* Test Description:
-* Testcase to check the basic functionality of the pwritev(2).
-* pwritev(2) should succeed to write the expected content of data
-* and after writing the file, the file offset is not changed.
-*/
+ * Copyright (c) 2015 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2016-2023
+ */
+
+/*\
+ * [Description]
+ *
+ * Testcase to check the basic functionality of the pwritev(2).
+ *
+ * pwritev(2) should succeed to write the expected content of data
+ * and after writing the file, the file offset is not changed.
+ */
#define _GNU_SOURCE
#include <string.h>
diff --git a/testcases/kernel/syscalls/pwritev/pwritev02.c b/testcases/kernel/syscalls/pwritev/pwritev02.c
index 0881b7566..59a286847 100644
--- a/testcases/kernel/syscalls/pwritev/pwritev02.c
+++ b/testcases/kernel/syscalls/pwritev/pwritev02.c
@@ -1,30 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
-* Copyright (c) 2015-2016 Fujitsu Ltd.
-* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
-*/
-
-/*
-* Test Name: pwritev02
-*
-* Description:
-* 1) pwritev(2) fails if iov_len is invalid.
-* 2) pwritev(2) fails if the vector count iovcnt is less than zero.
-* 3) pwritev(2) fails if offset is negative.
-* 4) pwritev(2) fails when attempts to write from a invalid address
-* 5) pwritev(2) fails if file descriptor is invalid.
-* 6) pwritev(2) fails if file descriptor is not open for writing.
-* 7) pwritev(2) fails if fd is associated with a pipe.
-*
-* Expected Result:
-* 1) pwritev(2) should return -1 and set errno to EINVAL.
-* 2) pwritev(2) should return -1 and set errno to EINVAL.
-* 3) pwritev(2) should return -1 and set errno to EINVAL.
-* 4) pwritev(2) should return -1 and set errno to EFAULT.
-* 5) pwritev(2) should return -1 and set errno to EBADF.
-* 6) pwritev(2) should return -1 and set errno to EBADF.
-* 7) pwritev(2) should return -1 and set errno to ESPIPE.
-*/
+ * Copyright (c) 2015-2016 Fujitsu Ltd.
+ * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2017-2023
+ */
+
+/*\
+ * [Description]
+ *
+ * - EINVAL when iov_len is invalid.
+ * - EINVAL when the vector count iovcnt is less than zero.
+ * - EINVAL when offset is negative.
+ * - EFAULT when attempts to write from a invalid address
+ * - EBADF when file descriptor is invalid.
+ * - EBADF when file descriptor is not open for writing.
+ * - ESPIPE when fd is associated with a pipe.
+ */
#define _GNU_SOURCE
diff --git a/testcases/kernel/syscalls/pwritev/pwritev03.c b/testcases/kernel/syscalls/pwritev/pwritev03.c
index 8b91de336..1bf9d5731 100644
--- a/testcases/kernel/syscalls/pwritev/pwritev03.c
+++ b/testcases/kernel/syscalls/pwritev/pwritev03.c
@@ -2,12 +2,15 @@
/*
* Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
* Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
+ * Copyright (c) Linux Test Project, 2019-2023
*/
-/*
- * Description:
+/*\
+ * [Description]
+ *
* Check the basic functionality of the pwritev(2) for the file
* opened with O_DIRECT in all filesystem.
+ *
* pwritev(2) should succeed to write the expected content of data
* and after writing the file, the file offset is not changed.
*/
@@ -90,7 +93,7 @@ static void verify_direct_pwritev(unsigned int n)
static void setup(void)
{
int dev_fd, ret;
-
+
dev_fd = SAFE_OPEN(tst_device->dev, O_RDWR);
SAFE_IOCTL(dev_fd, BLKSSZGET, &ret);
SAFE_CLOSE(dev_fd);
diff --git a/testcases/kernel/syscalls/readahead/readahead01.c b/testcases/kernel/syscalls/readahead/readahead01.c
index bdef7945d..a1f313605 100644
--- a/testcases/kernel/syscalls/readahead/readahead01.c
+++ b/testcases/kernel/syscalls/readahead/readahead01.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2012 Linux Test Project, Inc.
+ * Copyright (C) 2023-2024 Cyril Hrubis <chrubis@suse.cz>
*/
/*\
@@ -30,43 +31,45 @@
static void test_bad_fd(void)
{
- char tempname[PATH_MAX] = "readahead01_XXXXXX";
- int fd;
+ int fd[2];
+
+ TST_EXP_FAIL(readahead(-1, 0, getpagesize()), EBADF,
+ "readahead() with fd = -1");
- tst_res(TINFO, "%s -1", __func__);
- TST_EXP_FAIL(readahead(-1, 0, getpagesize()), EBADF);
+ SAFE_PIPE(fd);
+ SAFE_CLOSE(fd[0]);
+ SAFE_CLOSE(fd[1]);
- tst_res(TINFO, "%s O_WRONLY", __func__);
- fd = mkstemp(tempname);
- if (fd == -1)
- tst_res(TFAIL | TERRNO, "mkstemp failed");
- SAFE_CLOSE(fd);
- fd = SAFE_OPEN(tempname, O_WRONLY);
- TST_EXP_FAIL(readahead(fd, 0, getpagesize()), EBADF);
- SAFE_CLOSE(fd);
- unlink(tempname);
+ TST_EXP_FAIL(readahead(fd[0], 0, getpagesize()), EBADF,
+ "readahead() with invalid fd");
}
-static void test_invalid_fd(void)
+static void test_invalid_fd(struct tst_fd *fd)
{
- int fd[2];
- tst_res(TINFO, "%s pipe", __func__);
- SAFE_PIPE(fd);
- TST_EXP_FAIL(readahead(fd[0], 0, getpagesize()), EINVAL);
- SAFE_CLOSE(fd[0]);
- SAFE_CLOSE(fd[1]);
+ switch (fd->type) {
+ /* These succeed */
+ case TST_FD_FILE:
+ case TST_FD_MEMFD:
+ case TST_FD_MEMFD_SECRET:
+ case TST_FD_PROC_MAPS:
+ return;
+ default:
+ break;
+ }
- tst_res(TINFO, "%s socket", __func__);
- fd[0] = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
- TST_EXP_FAIL(readahead(fd[0], 0, getpagesize()), EINVAL);
- SAFE_CLOSE(fd[0]);
+ int exp_errnos[] = {EBADF, EINVAL, ESPIPE};
+
+ TST_EXP_FAIL_ARR(readahead(fd->fd, 0, getpagesize()), exp_errnos,
+ "readahead() on %s", tst_fd_desc(fd));
}
static void test_readahead(void)
{
test_bad_fd();
- test_invalid_fd();
+
+ TST_FD_FOREACH(fd)
+ test_invalid_fd(&fd);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/remap_file_pages/remap_file_pages01.c b/testcases/kernel/syscalls/remap_file_pages/remap_file_pages01.c
index 09143a2d0..8a401fe0a 100644
--- a/testcases/kernel/syscalls/remap_file_pages/remap_file_pages01.c
+++ b/testcases/kernel/syscalls/remap_file_pages/remap_file_pages01.c
@@ -85,6 +85,7 @@
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <linux/unistd.h>
+#include <lapi/mmap.h>
#include "test.h" /*LTP Specific Include File */
@@ -92,6 +93,7 @@
#define WINDOW_START 0x48000000
static int page_sz;
+static int granula;
size_t page_words;
size_t cache_pages;
size_t cache_sz;
@@ -140,10 +142,10 @@ static void test_nonlinear(int fd)
char *data = NULL;
int i, j, repeat = 2;
- for (i = 0; i < (int)cache_pages; i++) {
+ for (i = 0; i < (int)cache_pages; i += granula) {
char *page = cache_contents + i * page_sz;
- for (j = 0; j < (int)page_words; j++)
+ for (j = 0; j < (int)page_words * granula; j++)
page[j] = i;
}
@@ -164,24 +166,24 @@ static void test_nonlinear(int fd)
}
again:
- for (i = 0; i < (int)window_pages; i += 2) {
+ for (i = 0; i < (int)window_pages; i += 2 * granula) {
char *page = data + i * page_sz;
- if (remap_file_pages(page, page_sz * 2, 0,
- (window_pages - i - 2), 0) == -1) {
+ if (remap_file_pages(page, 2 * MMAP_GRANULARITY, 0,
+ (window_pages - i - 2 * granula), 0) == -1) {
tst_resm(TFAIL | TERRNO,
"remap_file_pages error for page=%p, "
- "page_sz=%d, window_pages=%zu",
- page, (page_sz * 2), (window_pages - i - 2));
+ "remap_sz=%d, window_pages=%zu",
+ page, 2 * MMAP_GRANULARITY, (window_pages - i - 2 * granula));
cleanup(data);
}
}
- for (i = 0; i < (int)window_pages; i++) {
+ for (i = 0, j = 0; i < (int)window_pages; i += granula, j++) {
/*
* Double-check the correctness of the mapping:
*/
- if (i & 1) {
+ if (j & 1) {
if (data[i * page_sz] != ((int)window_pages) - i) {
tst_resm(TFAIL,
"hm, mapped incorrect data, "
@@ -191,12 +193,12 @@ again:
cleanup(data);
}
} else {
- if (data[i * page_sz] != ((int)window_pages) - i - 2) {
+ if (data[i * page_sz] != ((int)window_pages) - i - 2 * granula) {
tst_resm(TFAIL,
"hm, mapped incorrect data, "
- "data[%d]=%d, (window_pages-%d-2)=%zu",
+ "data[%d]=%d, (window_pages-%d-2 * min_pages)=%zu",
(i * page_sz), data[i * page_sz], i,
- (window_pages - i - 2));
+ (window_pages - i - 2 * granula));
cleanup(data);
}
}
@@ -223,13 +225,15 @@ void setup(void)
page_words = page_sz;
+ granula = MMAP_GRANULARITY / page_sz;
+
/* Set the cache size */
- cache_pages = 1024;
+ cache_pages = 1024 * granula;
cache_sz = cache_pages * page_sz;
cache_contents = malloc(cache_sz * sizeof(char));
/* Set the window size */
- window_pages = 16;
+ window_pages = 16 * granula;
window_sz = window_pages * page_sz;
sprintf(fname, "/dev/shm/cache_%d", getpid());
diff --git a/testcases/kernel/syscalls/rename/rename10.c b/testcases/kernel/syscalls/rename/rename10.c
index 444f65366..5b5f79073 100644
--- a/testcases/kernel/syscalls/rename/rename10.c
+++ b/testcases/kernel/syscalls/rename/rename10.c
@@ -18,7 +18,13 @@
#define MNT_POINT "mntpoint"
#define TEMP_FILE "tmpfile"
-static char long_path[NAME_MAX + 1] = {[0 ... NAME_MAX] = 'a'};
+/* Path longer than PATH_MAX: fails the syscall right away (getname() fails) */
+static char long_path[PATH_MAX + 1] = {[0 ... PATH_MAX] = 'a'};
+/*
+ * Path fitting in PATH_MAX, but with an excessively long file name: rejected
+ * by the underlying filesystem
+ */
+static char long_name[PATH_MAX] = {[0 ... PATH_MAX - 2] = 'a', [PATH_MAX - 1] = '\0'};
static void setup(void)
{
@@ -30,6 +36,8 @@ static void run(void)
{
TST_EXP_FAIL(rename(TEMP_FILE, long_path),
ENAMETOOLONG);
+ TST_EXP_FAIL(rename(TEMP_FILE, long_name),
+ ENAMETOOLONG);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/renameat/renameat01.c b/testcases/kernel/syscalls/renameat/renameat01.c
index 3de103563..c318a7971 100644
--- a/testcases/kernel/syscalls/renameat/renameat01.c
+++ b/testcases/kernel/syscalls/renameat/renameat01.c
@@ -50,7 +50,6 @@
#include "test.h"
#include "safe_macros.h"
#include "lapi/fcntl.h"
-#include "lapi/renameat.h"
#define MNTPOINT "mntpoint"
#define TESTDIR "testdir"
diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
index 597de4665..40ff6e988 100644
--- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
+++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval01.c
@@ -2,13 +2,17 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
+ */
+/*\
+ * [Description]
*
* Gets round-robin time quantum by calling sched_rr_get_interval() and
* checks that the value is sane.
*
- * It is also a regression test for kernel
- * commit 975e155ed873 ("sched/rt: Show the 'sched_rr_timeslice' SCHED_RR
- * timeslice tuning knob in milliseconds").
+ * It is also a regression test for:
+ *
+ * - 975e155ed873 (sched/rt: Show the 'sched_rr_timeslice' SCHED_RR timeslice tuning knob in milliseconds)
+ * - c7fcb99877f9 ( sched/rt: Fix sysctl_sched_rr_timeslice intial value)
*/
#include "time64_variants.h"
diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c
index 15e4a3053..a61e2969b 100644
--- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c
+++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval02.c
@@ -2,6 +2,9 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
+ */
+/*\
+ * [Description]
*
* Verify that for a process with scheduling policy SCHED_FIFO,
* sched_rr_get_interval() writes zero into timespec structure
diff --git a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c
index f5a88f084..731c50082 100644
--- a/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c
+++ b/testcases/kernel/syscalls/sched_rr_get_interval/sched_rr_get_interval03.c
@@ -2,14 +2,20 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* AUTHOR : Saji Kumar.V.R <saji.kumar@wipro.com>
+ */
+/*\
+ * [Description]
+ *
+ * Verify that:
+ *
+ * - sched_rr_get_interval() fails with errno set to EINVAL for an
+ * invalid pid
+ *
+ * - sched_rr_get_interval() fails with errno set to ESRCH if the
+ * process with specified pid does not exists
*
- * Verify that
- * 1) sched_rr_get_interval() fails with errno set to EINVAL for an
- * invalid pid
- * 2) sched_rr_get_interval() fails with errno set to ESRCH if the
- * process with specified pid does not exists
- * 3) sched_rr_get_interval() fails with errno set to EFAULT if the
- * address specified as &tp is invalid
+ * - sched_rr_get_interval() fails with errno set to EFAULT if the
+ * address specified as &tp is invalid
*/
#include "time64_variants.h"
diff --git a/testcases/kernel/syscalls/sched_setparam/sched_setparam03.c b/testcases/kernel/syscalls/sched_setparam/sched_setparam03.c
index 759b790b6..ffa92a3bf 100644
--- a/testcases/kernel/syscalls/sched_setparam/sched_setparam03.c
+++ b/testcases/kernel/syscalls/sched_setparam/sched_setparam03.c
@@ -49,7 +49,7 @@ void setup(void)
tst_res(TINFO, "Testing %s variant", tv->desc);
if (tv->sched_setscheduler(0, SCHED_FIFO, &p))
- tst_brk(TBROK | TERRNO, "sched_setcheduler(0, SCHED_FIFO, 1)");
+ tst_brk(TBROK | TERRNO, "sched_setscheduler(0, SCHED_FIFO, 1)");
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/sched_setparam/sched_setparam04.c b/testcases/kernel/syscalls/sched_setparam/sched_setparam04.c
index dbcb3c55c..26477e455 100644
--- a/testcases/kernel/syscalls/sched_setparam/sched_setparam04.c
+++ b/testcases/kernel/syscalls/sched_setparam/sched_setparam04.c
@@ -2,22 +2,23 @@
/*
* Copyright (c) 2021, BELLSOFT. All rights reserved.
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
- * AUTHOR: Saji Kumar.V.R <saji.kumar@wipro.com>
+ * Author: Saji Kumar.V.R <saji.kumar@wipro.com>
*/
/*\
* [Description]
*
* Verify that:
+ *
* 1. sched_setparam(2) returns -1 and sets errno to ESRCH if the
- * process with specified pid could not be found
+ * process with specified pid could not be found.
* 2. sched_setparam(2) returns -1 and sets errno to EINVAL if
- * the parameter pid is an invalid value (-1)
+ * the parameter pid is an invalid value (-1).
* 3. sched_setparam(2) returns -1 and sets errno to EINVAL if the
- * parameter p is an invalid address
+ * parameter p is an invalid address.
* 4. sched_setparam(2) returns -1 sets errno to EINVAL if the
* value for p.sched_priority is other than 0 for scheduling
- * policy, SCHED_OTHER
+ * policy, SCHED_OTHER.
*/
#include "tst_test.h"
diff --git a/testcases/kernel/syscalls/sched_setscheduler/.gitignore b/testcases/kernel/syscalls/sched_setscheduler/.gitignore
index aa8ad9695..1b8860d2c 100644
--- a/testcases/kernel/syscalls/sched_setscheduler/.gitignore
+++ b/testcases/kernel/syscalls/sched_setscheduler/.gitignore
@@ -1,3 +1,4 @@
/sched_setscheduler01
/sched_setscheduler02
/sched_setscheduler03
+/sched_setscheduler04
diff --git a/testcases/kernel/syscalls/sched_setscheduler/sched_setscheduler04.c b/testcases/kernel/syscalls/sched_setscheduler/sched_setscheduler04.c
new file mode 100644
index 000000000..828d1ec09
--- /dev/null
+++ b/testcases/kernel/syscalls/sched_setscheduler/sched_setscheduler04.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 Federico Bonfiglio <federico.bonfiglio@protonmail.ch>
+ */
+
+/*
+ * [Description]
+ *
+ * Testcases that test if sched_setscheduler with flag
+ * SCHED_RESET_ON_FORK restores children policy to
+ * SCHED_NORMAL.
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <linux/sched.h>
+
+#include "tst_test.h"
+#include "tst_sched.h"
+
+struct test_case_t {
+ int policy;
+ char *desc;
+};
+
+static struct test_case_t cases[] = {
+ {
+ .policy = SCHED_FIFO,
+ .desc = "SCHED_FIFO"
+ },
+ {
+ .policy = SCHED_RR,
+ .desc = "SCHED_RR"
+ }
+};
+
+static void test_reset_on_fork(unsigned int i)
+{
+ struct sched_variant *tv = &sched_variants[tst_variant];
+ struct test_case_t *tc = &cases[i];
+
+ tst_res(TINFO, "Testing %s variant %s policy", tv->desc, tc->desc);
+
+ struct sched_param param = { .sched_priority = 10 };
+
+ tv->sched_setscheduler(getpid(), tc->policy | SCHED_RESET_ON_FORK, &param);
+
+ pid_t pid = SAFE_FORK();
+
+ if (pid) {
+ if (sched_getscheduler(pid) == SCHED_NORMAL)
+ tst_res(TPASS, "Policy reset to SCHED_NORMAL");
+ else
+ tst_res(TFAIL, "Policy NOT reset to SCHED_NORMAL");
+
+ sched_getparam(pid, &param);
+
+ /* kernel will return sched_priority 0 if task is not RT Policy */
+ if (param.sched_priority == 0)
+ tst_res(TPASS, "Priority set to 0");
+ else
+ tst_res(TFAIL, "Priority not set to 0");
+ }
+}
+
+static struct tst_test test = {
+ .forks_child = 1,
+ .caps = (struct tst_cap[]) {
+ TST_CAP(TST_CAP_REQ, CAP_SYS_NICE),
+ {}
+ },
+ .test_variants = ARRAY_SIZE(sched_variants),
+ .tcnt = ARRAY_SIZE(cases),
+ .test = test_reset_on_fork,
+};
diff --git a/testcases/kernel/syscalls/sendfile/sendfile09.c b/testcases/kernel/syscalls/sendfile/sendfile09.c
index 4a2d2083f..6cb3cd593 100644
--- a/testcases/kernel/syscalls/sendfile/sendfile09.c
+++ b/testcases/kernel/syscalls/sendfile/sendfile09.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2014
+ * Copyright (c) Linux Test Project, 2013-2023
*/
/*\
@@ -20,11 +21,7 @@
#include <inttypes.h>
#include <sys/sendfile.h>
-
#include "tst_test.h"
-#include "lapi/abisize.h"
-
-#ifndef TST_ABI32
#define ONE_GB (INT64_C(1) << 30)
#define IN_FILE "in_file"
@@ -97,12 +94,9 @@ static struct tst_test test = {
.test = run,
.tcnt = ARRAY_SIZE(tc),
.max_runtime = 120,
+ .skip_in_compat = 1,
.tags = (const struct tst_tag[]) {
{"linux-git", "5d73320a96fcc"},
{}
}
};
-
-#else
-TST_TEST_TCONF("This test is only for 64bit");
-#endif
diff --git a/testcases/kernel/syscalls/sendmmsg/sendmmsg.h b/testcases/kernel/syscalls/sendmmsg/sendmmsg.h
index 65d5b680f..69ed80d44 100644
--- a/testcases/kernel/syscalls/sendmmsg/sendmmsg.h
+++ b/testcases/kernel/syscalls/sendmmsg/sendmmsg.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef SENDMMSG_H__
+#define SENDMMSG_H__
+
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
@@ -25,3 +28,5 @@ static struct time64_variants variants[] = {
{ .recvmmsg = sys_recvmmsg64, .sendmmsg = sys_sendmmsg, .ts_type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
#endif
};
+
+#endif /* SENDMMSG_H__ */
diff --git a/testcases/kernel/syscalls/setgroups/.gitignore b/testcases/kernel/syscalls/setgroups/.gitignore
index 9de928241..0649a3425 100644
--- a/testcases/kernel/syscalls/setgroups/.gitignore
+++ b/testcases/kernel/syscalls/setgroups/.gitignore
@@ -4,3 +4,5 @@
/setgroups02_16
/setgroups03
/setgroups03_16
+/setgroups04
+/setgroups04_16
diff --git a/testcases/kernel/syscalls/setgroups/Makefile b/testcases/kernel/syscalls/setgroups/Makefile
index b2bb1e005..41160978e 100644
--- a/testcases/kernel/syscalls/setgroups/Makefile
+++ b/testcases/kernel/syscalls/setgroups/Makefile
@@ -3,6 +3,9 @@
top_srcdir ?= ../../../..
+# Remove after rewriting setgroups04.c to the new API.
+USE_LEGACY_COMPAT_16_H := 1
+
include $(top_srcdir)/include/mk/testcases.mk
include $(abs_srcdir)/../utils/compat_16.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/setgroups/setgroups04.c b/testcases/kernel/syscalls/setgroups/setgroups04.c
new file mode 100644
index 000000000..93a064cda
--- /dev/null
+++ b/testcases/kernel/syscalls/setgroups/setgroups04.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) Bull S.A. 2001
+ * Copyright (c) International Business Machines Corp., 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Test Name: setgroups04
+ *
+ * Test Description:
+ * Verify that, setgroups() fails with -1 and sets errno to EFAULT if the list has an invalid address.
+ *
+ * Expected Result:
+ * setgroups() should fail with return value -1 and set expected errno.
+ *
+ * Algorithm:
+ * Setup:
+ * Setup signal handling.
+ * Pause for SIGUSR1 if option specified.
+ *
+ * Test:
+ * Loop if the proper options are given.
+ * Execute system call
+ * Check return code, if system call failed (return=-1)
+ * if errno set == expected errno
+ * Issue sys call fails with expected return value and errno.
+ * Otherwise,
+ * Issue sys call fails with unexpected errno.
+ * Otherwise,
+ * Issue sys call returns unexpected value.
+ *
+ * Cleanup:
+ * Print errno log and/or timing stats if options given
+ *
+ * Usage: <for command-line>
+ * setgroups04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
+ * where, -c n : Run n copies concurrently.
+ * -f : Turn off functionality Testing.
+ * -i n : Execute test n times.
+ * -I x : Execute test for x seconds.
+ * -P x : Pause for x seconds between iterations.
+ * -t : Turn on syscall timing.
+ *
+ * HISTORY
+ * 05/2002 Ported by André Merlier
+ *
+ * RESTRICTIONS:
+ * none.
+ *
+ */
+#include <sys/types.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "test.h"
+
+/*
+ * Don't forget to remove USE_LEGACY_COMPAT_16_H from Makefile after
+ * rewriting this test to the new API.
+ */
+#include "compat_16.h"
+
+TCID_DEFINE(setgroups04);
+int TST_TOTAL = 1;
+
+GID_T groups_list[NGROUPS];
+
+void setup(); /* setup function for the test */
+void cleanup(); /* cleanup function for the test */
+
+#if !defined(UCLINUX)
+
+int main(int ac, char **av)
+{
+ int lc;
+ int gidsetsize; /* total no. of groups */
+ char *test_desc; /* test specific error message */
+
+ tst_parse_opts(ac, av, NULL, NULL);
+
+ /* Perform setup for test */
+ setup();
+
+ for (lc = 0; TEST_LOOPING(lc); lc++) {
+
+ tst_count = 0;
+
+ gidsetsize = NGROUPS;
+ test_desc = "EFAULT";
+
+ /*
+ * Call setgroups() to test condition
+ * verify that it fails with -1 return value and
+ * sets appropriate errno.
+ */
+ TEST(SETGROUPS(cleanup, gidsetsize, sbrk(0)));
+
+ if (TEST_RETURN != -1) {
+ tst_resm(TFAIL, "setgroups() returned %ld, "
+ "expected -1, errno=%d", TEST_RETURN,
+ EFAULT);
+ } else {
+
+ if (TEST_ERRNO == EFAULT) {
+ tst_resm(TPASS,
+ "setgroups() fails with expected "
+ "error EFAULT errno:%d", TEST_ERRNO);
+ } else {
+ tst_resm(TFAIL, "setgroups() fails, %s, "
+ "errno=%d, expected errno=%d",
+ test_desc, TEST_ERRNO, EFAULT);
+ }
+ }
+
+ }
+
+ cleanup();
+ tst_exit();
+
+}
+
+#else
+
+int main(void)
+{
+ tst_resm(TINFO, "test is not available on uClinux");
+ tst_exit();
+}
+
+#endif /* if !defined(UCLINUX) */
+
+/*
+ * setup()
+ */
+void setup(void)
+{
+ tst_require_root();
+
+ tst_sig(NOFORK, DEF_HANDLER, cleanup);
+
+ TEST_PAUSE;
+
+}
+
+/*
+ * cleanup()
+ */
+void cleanup(void)
+{
+
+}
diff --git a/testcases/kernel/syscalls/setsockopt/.gitignore b/testcases/kernel/syscalls/setsockopt/.gitignore
index fd3235bb3..5c05290a5 100644
--- a/testcases/kernel/syscalls/setsockopt/.gitignore
+++ b/testcases/kernel/syscalls/setsockopt/.gitignore
@@ -7,3 +7,4 @@
/setsockopt07
/setsockopt08
/setsockopt09
+/setsockopt10
diff --git a/testcases/kernel/syscalls/setsockopt/setsockopt10.c b/testcases/kernel/syscalls/setsockopt/setsockopt10.c
new file mode 100644
index 000000000..4e7e44938
--- /dev/null
+++ b/testcases/kernel/syscalls/setsockopt/setsockopt10.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2023 SUSE LLC Richard Palethorpe <rpalethorpe@suse.com>
+ */
+/*\
+ * [Description]
+ *
+ * Reproducer for CVE-2023-0461 which is an exploitable use-after-free
+ * in a TLS socket. In fact it is exploitable in any User Level
+ * Protocol (ULP) which does not clone its context when accepting a
+ * connection.
+ *
+ * Because it does not clone the context, the child socket which is
+ * created on accept has a pointer to the listening socket's
+ * context. When the child is closed the parent's context is freed
+ * while it still has a reference to it.
+ *
+ * TLS can only be added to a socket which is connected. Not listening
+ * or disconnected, and a connected socket can not be set to
+ * listening. So we have to connect the socket, add TLS, then
+ * disconnect, then set it to listening.
+ *
+ * To my knowledge, setting a socket from open to disconnected
+ * requires a trick; we have to "connect" to an unspecified
+ * address. This could explain why the bug was not found earlier.
+ *
+ * The accepted fix was to disallow listening on sockets with a ULP
+ * set which does not have a clone function.
+ *
+ * The test uses two processes, first the child acts as a server so
+ * that the parent can create the TLS socket. Then the child connects
+ * to the parent's TLS socket.
+ *
+ * When we try to listen on the parent, the current kernel should
+ * return EINVAL. However if clone is implemented then this could
+ * become a valid operation. It is also quite easy to crash the kernel
+ * if we set some TLS options before doing a double free.
+ *
+ * commit 2c02d41d71f90a5168391b6a5f2954112ba2307c
+ * Author: Paolo Abeni <pabeni@redhat.com>
+ * Date: Tue Jan 3 12:19:17 2023 +0100
+ *
+ * net/ulp: prevent ULP without clone op from entering the LISTEN status
+ */
+
+#include "sched.h"
+#include "tst_test.h"
+
+#ifdef HAVE_LINUX_TLS_H
+
+#include <linux/tls.h>
+#include <netinet/in.h>
+
+#include "lapi/sched.h"
+#include "lapi/socket.h"
+#include "lapi/tcp.h"
+#include "tst_checkpoint.h"
+#include "tst_net.h"
+#include "tst_safe_net.h"
+#include "tst_taint.h"
+
+static struct tls12_crypto_info_aes_gcm_128 opts = {
+ .info = {
+ .version = TLS_1_2_VERSION,
+ .cipher_type = TLS_CIPHER_AES_GCM_128,
+ },
+ .iv = { 'i', 'v' },
+ .key = { 'k', 'e', 'y' },
+ .salt = { 's', 'a', 'l', 't' },
+ .rec_seq = { 'r', 'e', 'c', 's' },
+};
+
+static struct sockaddr_in tcp0_addr, tcp1_addr;
+static const struct sockaddr unspec_addr = {
+ .sa_family = AF_UNSPEC
+};
+
+static int tcp0_sk, tcp1_sk, tcp2_sk, tcp3_sk;
+
+static void setup(void)
+{
+ tst_init_sockaddr_inet(&tcp0_addr, "127.0.0.1", 0x7c90);
+ tst_init_sockaddr_inet(&tcp1_addr, "127.0.0.1", 0x7c91);
+}
+
+static void cleanup(void)
+{
+ if (tcp0_sk > 0)
+ SAFE_CLOSE(tcp0_sk);
+ if (tcp1_sk > 0)
+ SAFE_CLOSE(tcp1_sk);
+ if (tcp2_sk > 0)
+ SAFE_CLOSE(tcp2_sk);
+ if (tcp3_sk > 0)
+ SAFE_CLOSE(tcp3_sk);
+}
+
+static void child(void)
+{
+ tst_res(TINFO, "child: Listen for tcp1 connection");
+ tcp0_sk = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+ SAFE_BIND(tcp0_sk, (struct sockaddr *)&tcp0_addr, sizeof(tcp0_addr));
+ SAFE_LISTEN(tcp0_sk, 1);
+ TST_CHECKPOINT_WAKE(0);
+
+ tcp3_sk = SAFE_ACCEPT(tcp0_sk, NULL, 0);
+ TST_CHECKPOINT_WAIT(1);
+ SAFE_CLOSE(tcp3_sk);
+ SAFE_CLOSE(tcp0_sk);
+
+ tcp3_sk = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+ TST_CHECKPOINT_WAIT(2);
+
+ tst_res(TINFO, "child: connect for tcp2 connection");
+ TEST(connect(tcp3_sk, (struct sockaddr *)&tcp1_addr, sizeof(tcp1_addr)));
+
+ if (TST_RET == -1) {
+ tst_res(TINFO | TTERRNO, "child: could not connect to tcp1");
+ return;
+ }
+
+ TST_CHECKPOINT_WAIT(3);
+}
+
+static void run(void)
+{
+ const pid_t child_pid = SAFE_FORK();
+
+ if (child_pid == 0) {
+ child();
+ return;
+ }
+
+ tcp1_sk = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+ TST_CHECKPOINT_WAIT(0);
+
+ tst_res(TINFO, "parent: Connect for tcp0 connection");
+ SAFE_CONNECT(tcp1_sk, (struct sockaddr *)&tcp0_addr, sizeof(tcp0_addr));
+ TEST(setsockopt(tcp1_sk, SOL_TCP, TCP_ULP, "tls", 3));
+
+ if (TST_RET == -1 && TST_ERR == ENOENT)
+ tst_brk(TCONF | TTERRNO, "parent: setsockopt failed: The TLS module is probably not loaded");
+ else if (TST_RET == -1)
+ tst_brk(TBROK | TTERRNO, "parent: setsockopt failed");
+
+ SAFE_SETSOCKOPT(tcp1_sk, SOL_TLS, TLS_TX, &opts, sizeof(opts));
+ TST_CHECKPOINT_WAKE(1);
+
+ tst_res(TINFO, "parent: Disconnect by setting unspec address");
+ SAFE_CONNECT(tcp1_sk, &unspec_addr, sizeof(unspec_addr));
+ SAFE_BIND(tcp1_sk, (struct sockaddr *)&tcp1_addr, sizeof(tcp1_addr));
+
+ TEST(listen(tcp1_sk, 1));
+
+ if (TST_RET == -1) {
+ if (TST_ERR == EINVAL)
+ tst_res(TPASS | TTERRNO, "parent: Can't listen on disconnected TLS socket");
+ else
+ tst_res(TCONF | TTERRNO, "parent: Can't listen on disconnected TLS socket, but the errno is not EINVAL as expected");
+
+ TST_CHECKPOINT_WAKE(2);
+ tst_reap_children();
+ return;
+ }
+
+ tst_res(TINFO, "parent: Can listen on disconnected TLS socket");
+ TST_CHECKPOINT_WAKE(2);
+
+ tcp2_sk = SAFE_ACCEPT(tcp1_sk, NULL, 0);
+ SAFE_CLOSE(tcp2_sk);
+
+ tst_res(TINFO, "parent: Attempting double free, because we set cipher options this should result in an crash");
+ tst_flush();
+ SAFE_CLOSE(tcp1_sk);
+
+ TST_CHECKPOINT_WAKE(3);
+ tst_reap_children();
+ sched_yield();
+
+ tst_res(TCONF, "parent: We're still here, maybe the kernel can clone the TLS-ULP context now?");
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+ .taint_check = TST_TAINT_W | TST_TAINT_D,
+ .needs_kconfigs = (const char *[]) {
+ "CONFIG_TLS",
+ NULL
+ },
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "2c02d41d71f90"},
+ {"CVE", "2023-0461"},
+ {}
+ }
+};
+
+#else
+
+TST_TEST_TCONF("linux/tls.h missing, we assume your system is too old");
+
+#endif
diff --git a/testcases/kernel/syscalls/setuid/Makefile b/testcases/kernel/syscalls/setuid/Makefile
index 1fdd7bd76..88d6385d9 100644
--- a/testcases/kernel/syscalls/setuid/Makefile
+++ b/testcases/kernel/syscalls/setuid/Makefile
@@ -4,8 +4,5 @@ top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
-#for compat_16.mk uses the compat_16_tst.h
-COMPAT_TST_16_H := 1
-
include $(abs_srcdir)/../utils/compat_16.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/setxattr/setxattr01.c b/testcases/kernel/syscalls/setxattr/setxattr01.c
index 8cd2821d0..31f41369a 100644
--- a/testcases/kernel/syscalls/setxattr/setxattr01.c
+++ b/testcases/kernel/syscalls/setxattr/setxattr01.c
@@ -137,7 +137,7 @@ static void verify_setxattr(unsigned int i)
{
/* some tests might require existing keys for each iteration */
if (tc[i].keyneeded) {
- SAFE_SETXATTR(FNAME, tc[i].key, tc[i].value, tc[i].size,
+ SAFE_SETXATTR(FNAME, tc[i].key, *tc[i].value, tc[i].size,
XATTR_CREATE);
}
diff --git a/testcases/kernel/syscalls/sighold/sighold02.c b/testcases/kernel/syscalls/sighold/sighold02.c
index 1cfb7688b..2807bf67e 100644
--- a/testcases/kernel/syscalls/sighold/sighold02.c
+++ b/testcases/kernel/syscalls/sighold/sighold02.c
@@ -1,9 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- * AUTHOR : Bob Clark
- * CO-PILOT : Barrie Kletscher
- * DATE STARTED : 9/26/86
+ * Authors: Bob Clark, Barrie Kletscher
* Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz>
* Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
@@ -12,8 +10,9 @@
* [Description]
*
* This test checks following conditions:
- * 1. sighold action to turn off the receipt of all signals was done without error.
- * 2. After signals were held, and sent, no signals were trapped.
+ *
+ * 1. sighold action to turn off the receipt of all signals was done without error.
+ * 2. After signals were held, and sent, no signals were trapped.
*/
#define _XOPEN_SOURCE 600
diff --git a/testcases/kernel/syscalls/splice/.gitignore b/testcases/kernel/syscalls/splice/.gitignore
index a3e502f00..88a8dff78 100644
--- a/testcases/kernel/syscalls/splice/.gitignore
+++ b/testcases/kernel/syscalls/splice/.gitignore
@@ -3,3 +3,5 @@
/splice03
/splice04
/splice05
+/splice06
+/splice07
diff --git a/testcases/kernel/syscalls/splice/splice06.c b/testcases/kernel/syscalls/splice/splice06.c
new file mode 100644
index 000000000..0cb5dec29
--- /dev/null
+++ b/testcases/kernel/syscalls/splice/splice06.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023 SUSE LLC <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This test is cover splice() on proc files.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "tst_test.h"
+#include "lapi/splice.h"
+
+#define BUF_SIZE 100
+#define PIPE_MAX_INIT_SIZE 65536
+#define DOMAIN_INIT_NAME "LTP_INIT"
+#define DOMAIN_TEST_NAME "LTP_TEST"
+#define INTEGER_PROCFILE "/proc/sys/fs/pipe-max-size"
+#define STRING_PROCFILE "/proc/sys/kernel/domainname"
+static int pipe_max_test_size;
+
+static void format_str(char *str)
+{
+ int i;
+
+ for (i = 0; i < BUF_SIZE ; i++) {
+ if (!isdigit(str[i])) {
+ str[i] = '\0';
+ break;
+ }
+ }
+ if (i == BUF_SIZE)
+ tst_brk(TBROK, "can not find nonnumeric character from input string");
+}
+
+static int splice_read_num(const char *file)
+{
+ int pipes[2];
+ int fd_in;
+ int ret;
+ int num;
+ char buf[BUF_SIZE];
+
+ memset(buf, '\0', sizeof(buf));
+ fd_in = SAFE_OPEN(file, O_RDONLY);
+ SAFE_PIPE(pipes);
+
+ ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE - 1, 0);
+ if (ret < 0)
+ tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed");
+
+ SAFE_READ(0, pipes[0], buf, BUF_SIZE);
+
+ /* Search for the first nonnumeric character and replace it with \0 */
+ format_str(buf);
+
+ if (tst_parse_int(buf, &num, 0, INT_MAX))
+ tst_brk(TBROK, "Invalid buffer num %s", buf);
+
+ SAFE_CLOSE(fd_in);
+ SAFE_CLOSE(pipes[0]);
+ SAFE_CLOSE(pipes[1]);
+
+ return num;
+}
+
+static char *splice_read_str(const char *file, char *dest)
+{
+ int pipes[2];
+ int fd_in;
+ int ret;
+
+ fd_in = SAFE_OPEN(file, O_RDONLY);
+ SAFE_PIPE(pipes);
+
+ ret = splice(fd_in, NULL, pipes[1], NULL, BUF_SIZE, 0);
+ if (ret < 0)
+ tst_brk(TBROK | TERRNO, "splice(fd_in, pipe) failed");
+
+ SAFE_READ(0, pipes[0], dest, BUF_SIZE);
+
+ SAFE_CLOSE(fd_in);
+ SAFE_CLOSE(pipes[0]);
+ SAFE_CLOSE(pipes[1]);
+
+ return dest;
+}
+
+
+static void splice_write_num(const char *file, int num)
+{
+ int pipes[2];
+ int fd_out;
+ int ret;
+ char buf[BUF_SIZE];
+
+ memset(buf, '\0', sizeof(buf));
+
+ fd_out = SAFE_OPEN(file, O_WRONLY, 0777);
+ SAFE_PIPE(pipes);
+ sprintf(buf, "%d", num);
+
+ SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], buf, strlen(buf));
+
+ ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0);
+ if (ret < 0)
+ tst_brk(TBROK | TERRNO, "splice write failed");
+
+ SAFE_CLOSE(fd_out);
+ SAFE_CLOSE(pipes[0]);
+ SAFE_CLOSE(pipes[1]);
+}
+
+static void splice_write_str(const char *file, char *dest)
+{
+ int pipes[2];
+ int fd_out;
+ int ret;
+
+ fd_out = SAFE_OPEN(file, O_WRONLY, 0777);
+ SAFE_PIPE(pipes);
+
+ SAFE_WRITE(SAFE_WRITE_ALL, pipes[1], dest, strlen(dest));
+
+ ret = splice(pipes[0], NULL, fd_out, NULL, BUF_SIZE, 0);
+ if (ret < 0)
+ tst_brk(TBROK | TERRNO, "splice write failed");
+
+ SAFE_CLOSE(fd_out);
+ SAFE_CLOSE(pipes[0]);
+ SAFE_CLOSE(pipes[1]);
+}
+
+static void file_write_num(const char *file, int num)
+{
+ SAFE_FILE_PRINTF(file, "%d", num);
+}
+
+static void file_write_str(const char *file, char *dest)
+{
+ SAFE_FILE_PRINTF(file, "%s", dest);
+}
+
+static int file_read_num(const char *file)
+{
+ int num;
+
+ SAFE_FILE_SCANF(file, "%d", &num);
+
+ return num;
+}
+
+static char *file_read_str(const char *file, char *dest)
+{
+ SAFE_FILE_SCANF(file, "%s", dest);
+ return dest;
+}
+
+static void splice_test(void)
+{
+
+ char buf_file[BUF_SIZE];
+ char buf_splice[BUF_SIZE];
+
+ if (file_read_num(INTEGER_PROCFILE) == splice_read_num(INTEGER_PROCFILE))
+ tst_res(TPASS, "Read num through splice correctly");
+ else
+ tst_brk(TBROK | TERRNO, "Read num through splice failed");
+
+ splice_write_num(INTEGER_PROCFILE, pipe_max_test_size);
+
+ if (file_read_num(INTEGER_PROCFILE) == pipe_max_test_size)
+ tst_res(TPASS, "Write num through splice correctly");
+ else
+ tst_brk(TBROK | TERRNO, "Write num through splice failed");
+
+ memset(buf_file, '\0', sizeof(buf_file));
+ memset(buf_splice, '\0', sizeof(buf_splice));
+
+ file_read_str(STRING_PROCFILE, buf_file);
+ splice_read_str(STRING_PROCFILE, buf_splice);
+
+ if (!strncmp(buf_file, buf_splice, strlen(buf_file)))
+ tst_res(TPASS, "Read string through splice correctly");
+ else
+ tst_brk(TBROK | TERRNO, "Read string through splice failed");
+
+ memset(buf_file, '\0', sizeof(buf_file));
+
+ splice_write_str(STRING_PROCFILE, DOMAIN_TEST_NAME);
+ file_read_str(STRING_PROCFILE, buf_file);
+
+ if (!strncmp(buf_file, DOMAIN_TEST_NAME, strlen(buf_file)))
+ tst_res(TPASS, "Write string through splice correctly");
+ else
+ tst_brk(TBROK | TERRNO, "Write string through splice failed");
+}
+
+static void setup(void)
+{
+ pipe_max_test_size = getpagesize();
+ file_write_str(STRING_PROCFILE, DOMAIN_INIT_NAME);
+ file_write_num(STRING_PROCFILE, PIPE_MAX_INIT_SIZE);
+}
+
+static struct tst_test test = {
+ .min_kver = "5.11",
+ .setup = setup,
+ .test_all = splice_test,
+ .needs_tmpdir = 1,
+ .save_restore = (const struct tst_path_val[]) {
+ {INTEGER_PROCFILE, NULL, TST_SR_TCONF},
+ {STRING_PROCFILE, NULL, TST_SR_TCONF},
+ {}
+ },
+};
diff --git a/testcases/kernel/syscalls/splice/splice07.c b/testcases/kernel/syscalls/splice/splice07.c
new file mode 100644
index 000000000..9c23e0aac
--- /dev/null
+++ b/testcases/kernel/syscalls/splice/splice07.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2023-2024 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * [Description]
+ *
+ * Iterate over all kinds of file descriptors and feed splice() with all possible
+ * combinations where at least one file descriptor is invalid. We do expect the
+ * syscall to fail either with EINVAL or EBADF.
+ */
+
+#define _GNU_SOURCE
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "tst_test.h"
+
+static void check_splice(struct tst_fd *fd_in, struct tst_fd *fd_out)
+{
+ /* These combinations just hang since the pipe is empty */
+ if (fd_in->type == TST_FD_PIPE_READ) {
+ switch (fd_out->type) {
+ case TST_FD_FILE:
+ case TST_FD_PIPE_WRITE:
+ case TST_FD_UNIX_SOCK:
+ case TST_FD_INET_SOCK:
+ case TST_FD_MEMFD:
+ return;
+ default:
+ break;
+ }
+ }
+
+ if (fd_out->type == TST_FD_PIPE_WRITE) {
+ switch (fd_in->type) {
+ /* While these combinations succeeed */
+ case TST_FD_DEV_ZERO:
+ case TST_FD_FILE:
+ case TST_FD_PROC_MAPS:
+ case TST_FD_MEMFD:
+ return;
+ /* And this complains about socket not being connected */
+ case TST_FD_INET_SOCK:
+ return;
+ default:
+ break;
+ }
+ }
+
+ const int exp_errnos[] = {EBADF, EINVAL};
+
+ TST_EXP_FAIL2_ARR(splice(fd_in->fd, NULL, fd_out->fd, NULL, 1, 0),
+ exp_errnos, "splice() on %s -> %s",
+ tst_fd_desc(fd_in), tst_fd_desc(fd_out));
+}
+
+static void verify_splice(void)
+{
+ TST_FD_FOREACH(fd_in) {
+ tst_res(TINFO, "%s -> ...", tst_fd_desc(&fd_in));
+ TST_FD_FOREACH(fd_out)
+ check_splice(&fd_in, &fd_out);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = verify_splice,
+};
diff --git a/testcases/kernel/syscalls/swapon/swapon01.c b/testcases/kernel/syscalls/swapon/swapon01.c
index c334ae246..e59fb20a1 100644
--- a/testcases/kernel/syscalls/swapon/swapon01.c
+++ b/testcases/kernel/syscalls/swapon/swapon01.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2003-2024
*/
/*\
@@ -16,30 +17,26 @@
#include "lapi/syscalls.h"
#include "libswap.h"
+#define SWAP_FILE "swapfile01"
+
static void verify_swapon(void)
{
- TEST(tst_syscall(__NR_swapon, "./swapfile01", 0));
+ TST_EXP_PASS(tst_syscall(__NR_swapon, SWAP_FILE, 0));
- if (TST_RET == -1) {
- tst_res(TFAIL | TTERRNO, "Failed to turn on swapfile");
- } else {
- tst_res(TPASS, "Succeeded to turn on swapfile");
- /*we need to turn this swap file off for -i option */
- if (tst_syscall(__NR_swapoff, "./swapfile01") != 0) {
- tst_brk(TBROK | TERRNO, "Failed to turn off swapfile,"
- " system reboot after execution of LTP "
- "test suite is recommended.");
- }
+ if (TST_PASS && tst_syscall(__NR_swapoff, SWAP_FILE) != 0) {
+ tst_brk(TBROK | TERRNO,
+ "Failed to turn off swapfile, system reboot recommended");
}
}
static void setup(void)
{
- is_swap_supported("./tstswap");
- make_swapfile("swapfile01", 0);
+ is_swap_supported(SWAP_FILE);
+ make_swapfile(SWAP_FILE, 0);
}
static struct tst_test test = {
+ .needs_root = 1,
.needs_tmpdir = 1,
.test_all = verify_swapon,
.setup = setup
diff --git a/testcases/kernel/syscalls/swapon/swapon02.c b/testcases/kernel/syscalls/swapon/swapon02.c
index d34c17a80..fceea77be 100644
--- a/testcases/kernel/syscalls/swapon/swapon02.c
+++ b/testcases/kernel/syscalls/swapon/swapon02.c
@@ -1,56 +1,39 @@
// SPDX-License-Identifier: GPL-2.0-or-later
-
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2002-2023
*/
/*\
* [Description]
*
* This test case checks whether swapon(2) system call returns
- * 1. ENOENT when the path does not exist
- * 2. EINVAL when the path exists but is invalid
- * 3. EPERM when user is not a superuser
- * 4. EBUSY when the specified path is already being used as a swap area
+ * - ENOENT when the path does not exist
+ * - EINVAL when the path exists but is invalid
+ * - EPERM when user is not a superuser
+ * - EBUSY when the specified path is already being used as a swap area
*/
-#include <errno.h>
#include <pwd.h>
#include "tst_test.h"
#include "lapi/syscalls.h"
#include "libswap.h"
-static void setup01(void);
-static void cleanup01(void);
-
static uid_t nobody_uid;
static int do_swapoff;
static struct tcase {
char *err_desc;
int exp_errno;
- char *exp_errval;
char *path;
- void (*setup)(void);
- void (*cleanup)(void);
} tcases[] = {
- {"Path does not exist", ENOENT, "ENOENT", "./doesnotexist", NULL, NULL},
- {"Invalid path", EINVAL, "EINVAL", "./notswap", NULL, NULL},
- {"Permission denied", EPERM, "EPERM", "./swapfile01", setup01, cleanup01},
- {"File already used", EBUSY, "EBUSY", "./alreadyused", NULL, NULL},
+ {"Path does not exist", ENOENT, "./doesnotexist"},
+ {"Invalid path", EINVAL, "./notswap"},
+ {"Permission denied", EPERM, "./swapfile01"},
+ {"File already used", EBUSY, "./alreadyused"},
};
-static void setup01(void)
-{
- SAFE_SETEUID(nobody_uid);
-}
-
-static void cleanup01(void)
-{
- SAFE_SETEUID(0);
-}
-
static void setup(void)
{
struct passwd *nobody;
@@ -70,7 +53,7 @@ static void setup(void)
do_swapoff = 1;
}
-void cleanup(void)
+static void cleanup(void)
{
if (do_swapoff && tst_syscall(__NR_swapoff, "alreadyused"))
tst_res(TWARN | TERRNO, "swapoff(alreadyused) failed");
@@ -79,24 +62,19 @@ void cleanup(void)
static void verify_swapon(unsigned int i)
{
struct tcase *tc = tcases + i;
- if (tc->setup)
- tc->setup();
+ if (tc->exp_errno == EPERM)
+ SAFE_SETEUID(nobody_uid);
- TEST(tst_syscall(__NR_swapon, tc->path, 0));
+ TST_EXP_FAIL(tst_syscall(__NR_swapon, tc->path, 0), tc->exp_errno,
+ "swapon(2) fail with %s", tc->err_desc);
- if (tc->cleanup)
- tc->cleanup();
+ if (tc->exp_errno == EPERM)
+ SAFE_SETEUID(0);
- if (TST_RET == -1 && TST_ERR == tc->exp_errno) {
- tst_res(TPASS, "swapon(2) expected failure;"
- " Got errno - %s : %s",
- tc->exp_errval, tc->err_desc);
- return;
+ if (TST_RET != -1) {
+ tst_res(TFAIL, "swapon(2) failed unexpectedly, expected: %s",
+ tst_strerrno(tc->exp_errno));
}
-
- tst_res(TFAIL, "swapon(2) failed to produce expected error:"
- " %d, errno: %s and got %d.", tc->exp_errno,
- tc->exp_errval, TST_ERR);
}
static struct tst_test test = {
diff --git a/testcases/kernel/syscalls/swapon/swaponoff.h b/testcases/kernel/syscalls/swapon/swaponoff.h
index e3eae3fe3..900761bda 100644
--- a/testcases/kernel/syscalls/swapon/swaponoff.h
+++ b/testcases/kernel/syscalls/swapon/swaponoff.h
@@ -2,17 +2,7 @@
#ifndef __SWAP_ON_OFF_H_
#define __SWAP_ON_OFF_H_
-/*
- * Read swapon(2) / swapoff(2) for a full history lesson behind the value of
- * MAX_SWAPFILES.
- */
#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
#define MAX_SWAPFILES 30
-#elif LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 10)
-#define MAX_SWAPFILES 32
-#else
-#define MAX_SWAPFILES 8
-#endif
#endif
diff --git a/testcases/kernel/syscalls/symlink/.gitignore b/testcases/kernel/syscalls/symlink/.gitignore
index d1497e680..6ea587ff3 100644
--- a/testcases/kernel/syscalls/symlink/.gitignore
+++ b/testcases/kernel/syscalls/symlink/.gitignore
@@ -2,4 +2,3 @@
/symlink02
/symlink03
/symlink04
-/symlink05
diff --git a/testcases/kernel/syscalls/symlink/symlink02.c b/testcases/kernel/syscalls/symlink/symlink02.c
index c18db2b37..d2226501e 100644
--- a/testcases/kernel/syscalls/symlink/symlink02.c
+++ b/testcases/kernel/syscalls/symlink/symlink02.c
@@ -1,208 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
- *
+ * Copyright (c) Linux Test Project, 2001-2023
+ * Author: William Roske
*/
-/* $Id: symlink02.c,v 1.6 2009/08/28 14:17:14 vapier Exp $ */
-/**********************************************************
- *
- * OS Test - Silicon Graphics, Inc.
- *
- * TEST IDENTIFIER : symlink02
- *
- * EXECUTED BY : anyone
- *
- * TEST TITLE : Basic test for symlink(2)
- *
- * PARENT DOCUMENT : usctpl01
- *
- * TEST CASE TOTAL : 1
- *
- * WALL CLOCK TIME : 1
- *
- * CPU TYPES : ALL
- *
- * AUTHOR : William Roske
- *
- * CO-PILOT : Dave Fenner
- *
- * DATE STARTED : 03/30/92
- *
- * INITIAL RELEASE : UNICOS 7.0
- *
- * TEST CASES
- *
- * 1.) symlink(2) returns...(See Description)
- *
- * INPUT SPECIFICATIONS
- * The standard options for system call tests are accepted.
- * (See the parse_opts(3) man page).
- *
- * OUTPUT SPECIFICATIONS
- *$
- * DURATION
- * Terminates - with frequency and infinite modes.
- *
- * SIGNALS
- * Uses SIGUSR1 to pause before test if option set.
- * (See the parse_opts(3) man page).
- *
- * RESOURCES
- * None
- *
- * ENVIRONMENTAL NEEDS
- * No run-time environmental needs.
- *
- * SPECIAL PROCEDURAL REQUIREMENTS
- * None
- *
- * INTERCASE DEPENDENCIES
- * None
- *
- * DETAILED DESCRIPTION
- * This is a Phase I test for the symlink(2) system call. It is intended
- * to provide a limited exposure of the system call, for now. It
- * should/will be extended when full functional tests are written for
- * symlink(2).
- *
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise, Issue a PASS message.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- *
- *
- *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include "test.h"
-#include "safe_macros.h"
-
-void setup();
-void cleanup();
+/*\
+ * [Description]
+ *
+ * Check the basic functionality of the symlink() system call.
+ */
-char *TCID = "symlink02";
-int TST_TOTAL = 1;
+#include "tst_test.h"
-char fname[255], symlnk[255];
-int fd;
+static char *fname, *symlnk;
-int main(int ac, char **av)
+static void verify_symlink(void)
{
- int lc;
-
- /***************************************************************
- * parse standard options
- ***************************************************************/
- tst_parse_opts(ac, av, NULL, NULL);
-
- /***************************************************************
- * perform global setup for test
- ***************************************************************/
- setup();
-
- /***************************************************************
- * check looping state if -c option given
- ***************************************************************/
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call symlink(2)
- */
- TEST(symlink(fname, symlnk));
-
- /* check return code */
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "symlink(%s, %s) Failed, errno=%d : %s",
- fname, symlnk, TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- SAFE_UNLINK(cleanup, symlnk);
- }
- }
-
- /***************************************************************
- * cleanup and exit
- ***************************************************************/
- cleanup();
- tst_exit();
+ TST_EXP_POSITIVE(symlink(fname, symlnk), "symlink(%s, %s)",
+ fname, symlnk);
+ if (TST_RET == -1)
+ tst_res(TFAIL, "symlink(%s, %s) Failed", fname, symlnk);
+ else
+ SAFE_UNLINK(symlnk);
}
-/***************************************************************
- * setup() - performs all ONE TIME setup for this test.
- ***************************************************************/
-void setup(void)
+static void setup(void)
{
+ fname = tst_aprintf("tfile_%d", getpid());
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- sprintf(fname, "tfile_%d", getpid());
- if ((fd = open(fname, O_RDWR | O_CREAT, 0700)) == -1) {
- tst_brkm(TBROK, cleanup,
- "open(%s, O_RDWR|O_CREAT,0700) Failed, errno=%d : %s",
- fname, errno, strerror(errno));
- }
-
- if (close(fd) == -1) {
- tst_resm(TWARN, "close(%s) Failed, errno=%d : %s",
- fname, errno, strerror(errno));
- }
- sprintf(symlnk, "st_%d", getpid());
+ symlnk = tst_aprintf("st_%d", getpid());
}
-/***************************************************************
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- ***************************************************************/
-void cleanup(void)
-{
-
- tst_rmdir();
-
-}
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .test_all = verify_symlink,
+};
diff --git a/testcases/kernel/syscalls/symlink/symlink04.c b/testcases/kernel/syscalls/symlink/symlink04.c
index 2190b3b1b..c43a03a26 100644
--- a/testcases/kernel/syscalls/symlink/symlink04.c
+++ b/testcases/kernel/syscalls/symlink/symlink04.c
@@ -1,193 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) Linux Test Project, 2001-2023
+ * Author: John George
*/
-/*
- * Test Name : symlink04
- *
- * Test Description :
- * Verify that, symlink will succeed to creat a symbolic link of an existing
- * object name path.
- *
- * Expected Result:
- * symlink() should return value 0 on success and symbolic link of an
- * existing object should be created.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Create temporary directory.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise,
- * Verify the Functionality of system call
- * if successful,
- * Issue Functionality-Pass message.
- * Otherwise,
- * Issue Functionality-Fail message.
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory created.
- *
- * Usage: <for command-line>
- * symlink04 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * History
- * 07/2001 John George
- * -Ported
- *
- * Restrictions:
- * None.
+/*\
+ * [Description]
*
+ * Check that a symbolic link may point to an existing file or
+ * to a nonexistent one.
*/
+#include <stdlib.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include "test.h"
-#include "safe_macros.h"
+#include "tst_test.h"
-#define TESTFILE "testfile"
-#define SYMFILE "slink_file"
-#define FILE_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
+#define TESTFILE "testfile"
+#define NONFILE "noexistfile"
+#define SYMFILE "slink_file"
-char *TCID = "symlink04";
-int TST_TOTAL = 1;
+static char *testfile;
+static char *nonfile;
-void setup();
-void cleanup();
+static struct tcase {
+ char **srcfile;
+} tcases[] = {
+ {&testfile},
+ {&nonfile},
+};
-int main(int ac, char **av)
+static void setup(void)
{
- struct stat stat_buf; /* stat structure buffer */
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call symlink(2) to create a symlink of
- * testfile.
- */
- TEST(symlink(TESTFILE, SYMFILE));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL, "symlink(%s, %s) Failed, errno=%d : %s",
- TESTFILE, SYMFILE, TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- /*
- * Get the symlink file status information
- * using lstat(2).
- */
- if (lstat(SYMFILE, &stat_buf) < 0) {
- tst_brkm(TFAIL, cleanup, "lstat(2) of "
- "%s failed, error:%d", SYMFILE,
- errno);
- }
-
- /* Check if the st_mode contains a link */
- if (!S_ISLNK(stat_buf.st_mode)) {
- tst_resm(TFAIL,
- "symlink of %s doesn't exist",
- TESTFILE);
- } else {
- tst_resm(TPASS, "symlink(%s, %s) "
- "functionality successful",
- TESTFILE, SYMFILE);
- }
- }
-
- /* Unlink the symlink file for next loop */
- SAFE_UNLINK(cleanup, SYMFILE);
- tst_count++; /* incr TEST_LOOP counter */
- }
-
- cleanup();
- tst_exit();
-
+ SAFE_TOUCH(TESTFILE, 0644, NULL);
}
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- * Create a temporary directory and change directory to it.
- * Create a test file under temporary directory and close it
- */
-void setup(void)
+static void verify_symlink(unsigned int i)
{
- int fd; /* file handle for testfile */
+ struct tcase *tc = &tcases[i];
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
+ struct stat stat_buf;
- /* Pause if that option was specified
- * TEST_PAUSE contains the code to fork the test with the -i option.
- * You want to make sure you do this before you create your temporary
- * directory.
- */
- TEST_PAUSE;
+ TST_EXP_PASS(symlink(*tc->srcfile, SYMFILE));
- tst_tmpdir();
+ SAFE_LSTAT(SYMFILE, &stat_buf);
- /* creat/open a testfile */
- if ((fd = open(TESTFILE, O_RDWR | O_CREAT, FILE_MODE)) == -1) {
- tst_brkm(TBROK, cleanup,
- "open(%s, O_RDWR|O_CREAT, %#o) Failed, errno=%d : %s",
- TESTFILE, FILE_MODE, errno, strerror(errno));
- }
+ if (!S_ISLNK(stat_buf.st_mode))
+ tst_res(TFAIL, "symlink of %s doesn't exist", *tc->srcfile);
- /* Close the temporary file created above */
- if (close(fd) == -1) {
- tst_resm(TBROK, "close(%s) Failed, errno=%d : %s",
- TESTFILE, errno, strerror(errno));
- }
+ SAFE_UNLINK(SYMFILE);
}
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * Remove the test directory and testfile created in the setup.
- */
-void cleanup(void)
-{
-
- tst_rmdir();
-
-}
+static struct tst_test test = {
+ .tcnt = ARRAY_SIZE(tcases),
+ .setup = setup,
+ .test = verify_symlink,
+ .bufs = (struct tst_buffers []) {
+ {&testfile, .str = TESTFILE},
+ {&nonfile, .str = NONFILE},
+ {},
+ },
+ .needs_tmpdir = 1,
+};
diff --git a/testcases/kernel/syscalls/symlink/symlink05.c b/testcases/kernel/syscalls/symlink/symlink05.c
deleted file mode 100644
index 83b151f5d..000000000
--- a/testcases/kernel/syscalls/symlink/symlink05.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Test Name : symlink05
- *
- * Test Description :
- * Verify that, symlink will succeed to creat a symbolic link of an
- * non-existing object name path.
- *
- * Expected Result:
- * symlink() should return value 0 on success and symlink of an
- * non-existing object should be created.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Create temporary directory.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise,
- * Verify the Functionality of system call
- * if successful,
- * Issue Functionality-Pass message.
- * Otherwise,
- * Issue Functionality-Fail message.
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory created.
- *
- * Usage: <for command-line>
- * symlink05 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * History
- * 07/2001 John George
- * -Ported
- *
- * Restrictions:
- * This test should be run by 'non-super-user' only.
- *
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-#define TESTFILE "testfile"
-#define SYMFILE "slink_file"
-
-char *TCID = "symlink05";
-int TST_TOTAL = 1;
-
-void setup();
-void cleanup();
-
-int main(int ac, char **av)
-{
- struct stat stat_buf; /* stat structure buffer */
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call symlink(2) to create a symlink of
- * an non-existing testfile.
- */
- TEST(symlink(TESTFILE, SYMFILE));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL,
- "symlink(%s, %s) Failed, errno=%d : %s",
- TESTFILE, SYMFILE, TEST_ERRNO,
- strerror(TEST_ERRNO));
- } else {
- /*
- * Get the symlink file status information
- * using lstat(2).
- */
- if (lstat(SYMFILE, &stat_buf) < 0) {
- tst_brkm(TFAIL, cleanup, "lstat(2) of "
- "%s failed, error:%d",
- SYMFILE, errno);
- }
-
- /* Check if the st_mode contains a link */
- if (!S_ISLNK(stat_buf.st_mode)) {
- tst_resm(TFAIL,
- "symlink of %s doesn't exist",
- TESTFILE);
- } else {
- tst_resm(TPASS, "symlink(%s, %s) "
- "functionality successful",
- TESTFILE, SYMFILE);
- }
- }
-
- /* Unlink the symlink file for next loop */
- SAFE_UNLINK(cleanup, SYMFILE);
- tst_count++; /* incr TEST_LOOP counter */
- }
-
- cleanup();
- tst_exit();
-
-}
-
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- * Create a temporary directory and change directory to it.
- */
-void setup(void)
-{
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- /* Pause if that option was specified
- * TEST_PAUSE contains the code to fork the test with the -i option.
- * You want to make sure you do this before you create your temporary
- * directory.
- */
- TEST_PAUSE;
-
- tst_tmpdir();
-
-}
-
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * Remove the temporary directory created in the setup.
- */
-void cleanup(void)
-{
-
- tst_rmdir();
-
-}
diff --git a/testcases/kernel/syscalls/timerfd/.gitignore b/testcases/kernel/syscalls/timerfd/.gitignore
index ef388685d..ca6cbb1f4 100644
--- a/testcases/kernel/syscalls/timerfd/.gitignore
+++ b/testcases/kernel/syscalls/timerfd/.gitignore
@@ -1,6 +1,5 @@
/timerfd01
/timerfd02
-/timerfd03
/timerfd04
/timerfd_create01
/timerfd_gettime01
diff --git a/testcases/kernel/syscalls/timerfd/timerfd02.c b/testcases/kernel/syscalls/timerfd/timerfd02.c
index 936cdbc53..3dabfb5c0 100644
--- a/testcases/kernel/syscalls/timerfd/timerfd02.c
+++ b/testcases/kernel/syscalls/timerfd/timerfd02.c
@@ -1,174 +1,51 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Ulrich Drepper <drepper@redhat.com> */
-/* Copyright (c) International Business Machines Corp., 2009 */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-/* the GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/******************************************************************************/
-/* */
-/* File: timerfd02.c */
-/* */
-/* Description: This Program tests the new system call introduced in 2.6.27. */
-/* Ulrich´s comment as in: */
-/* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=11fcb6c14676023d0bd437841f5dcd670e7990a0 */
-/* says: */
-/* The timerfd_create syscall already has a flags parameter. It just is */
-/* unused so far. This patch changes this by introducing the TFD_CLOEXEC */
-/* flag to set the close-on-exec flag for the returned file descriptor. A new */
-/* name TFD_CLOEXEC is introduced which in this implementation must have the */
-/* same value as O_CLOEXEC. */
-/* The following test must be adjusted for architectures other than x86 and */
-/* x86-64 and in case the syscall numbers changed. */
-/* */
-/* Usage: <for command-line> */
-/* timerfd02 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
-/* where, -c n : Run n copies concurrently. */
-/* -e : Turn on errno logging. */
-/* -i n : Execute test n times. */
-/* -I x : Execute test for x seconds. */
-/* -P x : Pause for x seconds between iterations. */
-/* -t : Turn on syscall timing. */
-/* */
-/* Total Tests: 1 */
-/* */
-/* Test Name: timerfd02 */
-/* */
-/* Author: Ulrich Drepper <drepper@redhat.com> */
-/* */
-/* History: Created - Jan 08 2009 - Ulrich Drepper <drepper@redhat.com> */
-/* Ported to LTP */
-/* - Jan 08 2009 - Subrata <subrata@linux.vnet.ibm.com> */
-/******************************************************************************/
-
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <errno.h>
-
-#include "test.h"
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Ulrich Drepper <drepper@redhat.com>
+ * Copyright (c) International Business Machines Corp., 2009
+ * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+/*\
+ * [Description]
+ *
+ * This test verifies that:
+ * - TFD_CLOEXEC sets the close-on-exec file status flag on the new open file
+ * - TFD_NONBLOCK sets the O_NONBLOCK file status flag on the new open file
+ */
+
+#include "tst_test.h"
+#include "tst_safe_timerfd.h"
#include "lapi/fcntl.h"
#include "lapi/syscalls.h"
-#define TFD_CLOEXEC O_CLOEXEC
+static int fdesc;
-char *TCID = "timerfd02";
-int testno;
-int TST_TOTAL = 1;
+static struct test_case_t {
+ int flags;
+ int check;
+ int expected;
+} tcases[] = {
+ { 0, F_GETFD, 0 },
+ { TFD_CLOEXEC, F_GETFD, FD_CLOEXEC },
+ { TFD_NONBLOCK, F_GETFL, O_NONBLOCK }
+};
-/* Extern Global Functions */
-/******************************************************************************/
-/* */
-/* Function: cleanup */
-/* */
-/* Description: Performs all one time clean up for this test on successful */
-/* completion, premature exit or failure. Closes all temporary */
-/* files, removes all temporary directories exits the test with */
-/* appropriate return code by calling tst_exit() function. */
-/* */
-/* Input: None. */
-/* */
-/* Output: None. */
-/* */
-/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
-/* On success - Exits calling tst_exit(). With '0' return code. */
-/* */
-/******************************************************************************/
-void cleanup(void)
+static void run(unsigned int i)
{
+ struct test_case_t *tcase = &tcases[i];
- tst_rmdir();
-
+ TST_EXP_FD(fdesc = SAFE_TIMERFD_CREATE(CLOCK_REALTIME, tcase->flags));
+ TST_EXP_EQ_LI(SAFE_FCNTL(fdesc, tcase->check) & tcase->expected, tcase->expected);
+ SAFE_CLOSE(fdesc);
}
-/* Local Functions */
-/******************************************************************************/
-/* */
-/* Function: setup */
-/* */
-/* Description: Performs all one time setup for this test. This function is */
-/* typically used to capture signals, create temporary dirs */
-/* and temporary files that may be used in the course of this */
-/* test. */
-/* */
-/* Input: None. */
-/* */
-/* Output: None. */
-/* */
-/* Return: On failure - Exits by calling cleanup(). */
-/* On success - returns 0. */
-/* */
-/******************************************************************************/
-void setup(void)
+static void cleanup(void)
{
- /* Capture signals if any */
- /* Create temporary directories */
- TEST_PAUSE;
- tst_tmpdir();
+ if (fcntl(fdesc, F_GETFD) != -1)
+ SAFE_CLOSE(fdesc);
}
-int main(int argc, char *argv[])
-{
- int fd, coe;
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); ++lc) {
- tst_count = 0;
- for (testno = 0; testno < TST_TOTAL; ++testno) {
- fd = tst_syscall(__NR_timerfd_create,
- CLOCK_REALTIME, 0);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup,
- "timerfd_create(0) failed");
- }
- coe = fcntl(fd, F_GETFD);
- if (coe == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if (coe & FD_CLOEXEC) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(0) set close-on-exec flag");
- }
- close(fd);
-
- fd = tst_syscall(__NR_timerfd_create, CLOCK_REALTIME,
- TFD_CLOEXEC);
- if (fd == -1) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(TFD_CLOEXEC) failed");
- }
- coe = fcntl(fd, F_GETFD);
- if (coe == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if ((coe & FD_CLOEXEC) == 0) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(TFD_CLOEXEC) set close-on-exec flag");
- }
- close(fd);
- tst_resm(TPASS, "timerfd_create(TFD_CLOEXEC) Passed");
- cleanup();
- }
- }
- tst_exit();
-}
+static struct tst_test test = {
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+ .cleanup = cleanup,
+};
diff --git a/testcases/kernel/syscalls/timerfd/timerfd03.c b/testcases/kernel/syscalls/timerfd/timerfd03.c
deleted file mode 100644
index 89dec325f..000000000
--- a/testcases/kernel/syscalls/timerfd/timerfd03.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/******************************************************************************/
-/* */
-/* Copyright (c) Ulrich Drepper <drepper@redhat.com> */
-/* Copyright (c) International Business Machines Corp., 2009 */
-/* */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or */
-/* (at your option) any later version. */
-/* */
-/* This program is distributed in the hope that it will be useful, */
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
-/* the GNU General Public License for more details. */
-/* */
-/* You should have received a copy of the GNU General Public License */
-/* along with this program; if not, write to the Free Software */
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-/* */
-/******************************************************************************/
-/******************************************************************************/
-/* */
-/* File: timerfd03.c */
-/* */
-/* Description: This Program tests the new system call introduced in 2.6.27. */
-/* Ulrich´s comment as in: */
-/* http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b1ef0e60d42f2fdaec26baee8327eb156347b4f */
-/* which says: */
-/* This patch adds support for the TFD_NONBLOCK flag to timerfd_create. The */
-/* additional changes needed are minimal. The following test must be adjusted */
-/* for architectures other than x86 and x86-64 and in case the syscall numbers*/
-/* changed. */
-/* */
-/* Usage: <for command-line> */
-/* timerfd03 [-c n] [-e][-i n] [-I x] [-p x] [-t] */
-/* where, -c n : Run n copies concurrently. */
-/* -e : Turn on errno logging. */
-/* -i n : Execute test n times. */
-/* -I x : Execute test for x seconds. */
-/* -P x : Pause for x seconds between iterations. */
-/* -t : Turn on syscall timing. */
-/* */
-/* Total Tests: 1 */
-/* */
-/* Test Name: timerfd03 */
-/* */
-/* Author: Ulrich Drepper <drepper@redhat.com> */
-/* */
-/* History: Created - Jan 13 2009 - Ulrich Drepper <drepper@redhat.com> */
-/* Ported to LTP */
-/* - Jan 13 2009 - Subrata <subrata@linux.vnet.ibm.com> */
-/******************************************************************************/
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <errno.h>
-
-#include "test.h"
-#include "lapi/fcntl.h"
-#include "lapi/syscalls.h"
-
-#define TFD_NONBLOCK O_NONBLOCK
-
-char *TCID = "timerfd03";
-int testno;
-int TST_TOTAL = 1;
-
-/* Extern Global Functions */
-/******************************************************************************/
-/* */
-/* Function: cleanup */
-/* */
-/* Description: Performs all one time clean up for this test on successful */
-/* completion, premature exit or failure. Closes all temporary */
-/* files, removes all temporary directories exits the test with */
-/* appropriate return code by calling tst_exit() function. */
-/* */
-/* Input: None. */
-/* */
-/* Output: None. */
-/* */
-/* Return: On failure - Exits calling tst_exit(). Non '0' return code. */
-/* On success - Exits calling tst_exit(). With '0' return code. */
-/* */
-/******************************************************************************/
-void cleanup(void)
-{
-
- tst_rmdir();
-
-}
-
-/* Local Functions */
-/******************************************************************************/
-/* */
-/* Function: setup */
-/* */
-/* Description: Performs all one time setup for this test. This function is */
-/* typically used to capture signals, create temporary dirs */
-/* and temporary files that may be used in the course of this */
-/* test. */
-/* */
-/* Input: None. */
-/* */
-/* Output: None. */
-/* */
-/* Return: On failure - Exits by calling cleanup(). */
-/* On success - returns 0. */
-/* */
-/******************************************************************************/
-void setup(void)
-{
- /* Capture signals if any */
- /* Create temporary directories */
- TEST_PAUSE;
- tst_tmpdir();
-}
-
-int main(int argc, char *argv[])
-{
- int fd, fl;
- int lc;
-
- tst_parse_opts(argc, argv, NULL, NULL);
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); ++lc) {
- tst_count = 0;
- for (testno = 0; testno < TST_TOTAL; ++testno) {
- fd = tst_syscall(__NR_timerfd_create,
- CLOCK_REALTIME, 0);
- if (fd == -1) {
- tst_brkm(TFAIL, cleanup,
- "timerfd_create(0) failed");
- }
- fl = fcntl(fd, F_GETFL);
- if (fl == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if (fl & O_NONBLOCK) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(0) set non-blocking mode");
- }
- close(fd);
-
- fd = tst_syscall(__NR_timerfd_create, CLOCK_REALTIME,
- TFD_NONBLOCK);
- if (fd == -1) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(TFD_NONBLOCK) failed");
- }
- fl = fcntl(fd, F_GETFL);
- if (fl == -1) {
- tst_brkm(TBROK, cleanup, "fcntl failed");
- }
- if ((fl & O_NONBLOCK) == 0) {
- tst_brkm(TFAIL,
- cleanup,
- "timerfd_create(TFD_NONBLOCK) set non-blocking mode");
- }
- close(fd);
- tst_resm(TPASS, "timerfd_create(TFD_NONBLOCK) PASSED");
- cleanup();
- }
- }
- tst_exit();
-}
diff --git a/testcases/kernel/syscalls/umount/umount01.c b/testcases/kernel/syscalls/umount/umount01.c
index d05296dce..264c8f7d7 100644
--- a/testcases/kernel/syscalls/umount/umount01.c
+++ b/testcases/kernel/syscalls/umount/umount01.c
@@ -2,12 +2,15 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* Author: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
+ * Copyright (c) Linux Test Project, 2002-2023
+ */
+
+/*\
+ * [Description]
*
- * Phase I test for the umount(2) system call.
- * It is intended to provide a limited exposure of the system call.
+ * Check the basic functionality of the umount(2) system call.
*/
-#include <errno.h>
#include <sys/mount.h>
#include "tst_test.h"
@@ -23,7 +26,7 @@ static void verify_umount(void)
mount_flag = 1;
}
- TEST(umount(MNTPOINT));
+ TST_EXP_PASS(umount(MNTPOINT));
if (TST_RET != 0 && TST_ERR == EBUSY) {
tst_res(TINFO, "umount() Failed with EBUSY "
@@ -31,12 +34,6 @@ static void verify_umount(void)
"is probing newly mounted dirs");
}
- if (TST_RET != 0) {
- tst_res(TFAIL | TTERRNO, "umount() Failed");
- return;
- }
-
- tst_res(TPASS, "umount() Passed");
mount_flag = 0;
}
diff --git a/testcases/kernel/syscalls/umount/umount02.c b/testcases/kernel/syscalls/umount/umount02.c
index 34a38c998..acc35e8a4 100644
--- a/testcases/kernel/syscalls/umount/umount02.c
+++ b/testcases/kernel/syscalls/umount/umount02.c
@@ -2,20 +2,24 @@
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
* Copyright (c) 2014 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2002-2023
* Author: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
+ */
+
+/*\
+ * [Description]
*
* Check for basic errors returned by umount(2) system call.
*
* Verify that umount(2) returns -1 and sets errno to
- * 1) EBUSY if it cannot be umounted, because dir is still busy.
- * 2) EFAULT if specialfile or device file points to invalid address space.
- * 3) ENOENT if pathname was empty or has a nonexistent component.
- * 4) EINVAL if specialfile or device is invalid or not a mount point.
- * 5) ENAMETOOLONG if pathname was longer than MAXPATHLEN.
+ *
+ * 1. EBUSY if it cannot be umounted, because dir is still busy.
+ * 2. EFAULT if specialfile or device file points to invalid address space.
+ * 3. ENOENT if pathname was empty or has a nonexistent component.
+ * 4. EINVAL if specialfile or device is invalid or not a mount point.
+ * 5. ENAMETOOLONG if pathname was longer than MAXPATHLEN.
*/
-#include <errno.h>
-#include <string.h>
#include <sys/mount.h>
#include "tst_test.h"
@@ -41,21 +45,7 @@ static void verify_umount(unsigned int n)
{
struct tcase *tc = &tcases[n];
- TEST(umount(tc->mntpoint));
-
- if (TST_RET != -1) {
- tst_res(TFAIL, "umount() succeeds unexpectedly");
- return;
- }
-
- if (tc->exp_errno != TST_ERR) {
- tst_res(TFAIL | TTERRNO, "umount() should fail with %s",
- tst_strerrno(tc->exp_errno));
- return;
- }
-
- tst_res(TPASS | TTERRNO, "umount() fails as expected: %s",
- tc->err_desc);
+ TST_EXP_FAIL(umount(tc->mntpoint), tc->exp_errno);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/umount/umount03.c b/testcases/kernel/syscalls/umount/umount03.c
index 1cef06fa1..3260312f7 100644
--- a/testcases/kernel/syscalls/umount/umount03.c
+++ b/testcases/kernel/syscalls/umount/umount03.c
@@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved.
+ * Copyright (c) Linux Test Project, 2002-2023
* Author: Nirmala Devi Dhanasekar <nirmala.devi@wipro.com>
+ */
+
+/*\
+ * [Description]
*
- * Verify that umount(2) returns -1 and sets errno to EPERM if the user
+ * Verify that umount(2) returns -1 and sets errno to EPERM if the user
* is not the super-user.
*/
-#include <errno.h>
#include <pwd.h>
#include <sys/mount.h>
-#include <sys/types.h>
-#include <unistd.h>
#include "tst_test.h"
#define MNTPOINT "mntpoint"
@@ -20,19 +22,7 @@ static int mount_flag;
static void verify_umount(void)
{
- TEST(umount(MNTPOINT));
-
- if (TST_RET != -1) {
- tst_res(TFAIL, "umount() succeeds unexpectedly");
- return;
- }
-
- if (TST_ERR != EPERM) {
- tst_res(TFAIL | TTERRNO, "umount() should fail with EPERM");
- return;
- }
-
- tst_res(TPASS | TTERRNO, "umount() fails as expected");
+ TST_EXP_FAIL(umount(MNTPOINT), EPERM);
}
static void setup(void)
diff --git a/testcases/kernel/syscalls/utils/compat_16.mk b/testcases/kernel/syscalls/utils/compat_16.mk
index e81a00c40..71a8cc56f 100644
--- a/testcases/kernel/syscalls/utils/compat_16.mk
+++ b/testcases/kernel/syscalls/utils/compat_16.mk
@@ -60,7 +60,7 @@ MAKE_TARGETS += $(addsuffix _16,$(MAKE_TARGETS))
# (no .h file, no TST_USE_NEWER64_SYSCALL def).
DEF_16 := TST_USE_COMPAT16_SYSCALL
-ifneq ($(COMPAT_TST_16_H),1)
+ifeq ($(USE_LEGACY_COMPAT_16_H),1)
COMPAT_16_H := $(abs_srcdir)/../utils/compat_16.h
else
COMPAT_16_H := $(abs_srcdir)/../utils/compat_tst_16.h
diff --git a/testcases/kernel/syscalls/wait4/wait402.c b/testcases/kernel/syscalls/wait4/wait402.c
index 39b170253..36fba7378 100644
--- a/testcases/kernel/syscalls/wait4/wait402.c
+++ b/testcases/kernel/syscalls/wait4/wait402.c
@@ -1,101 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- * Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
+ * Copyright (c) Linux Test Project, 2001-2015
+ * Copyright (c) 2023 Ioannis Bonatakis <ybonatakis@suse.com>
*/
- /*
- * wait402 - check for ECHILD errno when using an illegal pid value
- */
-
-#include "test.h"
+/*\
+ * [Description]
+ *
+ * Check for ECHILD errno when call wait4(2) with an invalid pid value.
+ */
-#include <errno.h>
-#define _USE_BSD
-#include <sys/types.h>
-#include <sys/resource.h>
+#include "tst_test.h"
#include <sys/wait.h>
-#include <stdlib.h>
-#include <string.h>
-
-char *TCID = "wait402";
-int TST_TOTAL = 1;
-
-static void cleanup(void);
-static void setup(void);
-
-static long get_pid_max(void)
-{
- long pid_max;
-
- SAFE_FILE_SCANF(NULL, "/proc/sys/kernel/pid_max", "%ld", &pid_max);
- return pid_max;
-}
+static pid_t pid_max;
-int main(int ac, char **av)
+static void run(void)
{
- int lc;
- pid_t epid = get_pid_max() + 1;
-
- int status = 1;
+ int status;
struct rusage rusage;
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- TEST(wait4(epid, &status, 0, &rusage));
-
- if (TEST_RETURN == 0) {
- tst_brkm(TFAIL, cleanup,
- "call failed to produce expected error - errno = %d - %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- }
-
- switch (TEST_ERRNO) {
- case ECHILD:
- tst_resm(TPASS,
- "received expected failure - errno = %d - %s",
- TEST_ERRNO, strerror(TEST_ERRNO));
- break;
- default:
- tst_brkm(TFAIL, cleanup,
- "call failed to produce expected "
- "error - errno = %d - %s", TEST_ERRNO,
- strerror(TEST_ERRNO));
- }
- }
-
- cleanup();
- tst_exit();
+ TST_EXP_FAIL2(wait4(pid_max + 1, &status, 0, &rusage), ECHILD);
}
static void setup(void)
{
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ SAFE_FILE_SCANF("/proc/sys/kernel/pid_max", "%d\n", &pid_max);
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+};
diff --git a/testcases/kernel/syscalls/writev/writev07.c b/testcases/kernel/syscalls/writev/writev07.c
index b725f08db..3dda1caa4 100644
--- a/testcases/kernel/syscalls/writev/writev07.c
+++ b/testcases/kernel/syscalls/writev/writev07.c
@@ -4,20 +4,26 @@
* Copyright (c) Linux Test Project, 2016
*/
-/*
- * Test Description:
- * Verify writev() behaviour with partially valid iovec list.
- * Kernel <4.8 used to shorten write up to first bad invalid
- * iovec. Starting with 4.8, a writev with short data (under
- * page size) is likely to get shorten to 0 bytes and return
- * EFAULT.
+/*\
+ * [Description]
+ *
+ * Verify writev() behaviour with partially valid iovec list.
+ * Kernel <4.8 used to shorten write up to first bad invalid
+ * iovec. Starting with 4.8, a writev with short data (under
+ * page size) is likely to get shorten to 0 bytes and return
+ * EFAULT.
+ *
+ * This test doesn't make assumptions how much will write get
+ * shortened. It only tests that file content/offset after
+ * syscall corresponds to return value of writev().
*
- * This test doesn't make assumptions how much will write get
- * shortened. It only tests that file content/offset after
- * syscall corresponds to return value of writev().
+ * See: [RFC] writev() semantics with invalid iovec in the middle
+ * https://marc.info/?l=linux-kernel&m=147388891614289&w=2.
*
- * See: [RFC] writev() semantics with invalid iovec in the middle
- * https://marc.info/?l=linux-kernel&m=147388891614289&w=2
+ * This is also regression test for kernel commits:
+ *
+ * * 20c64ec83a9f ("iomap: fix a regression for partial write errors")
+ * * 3ac974796e5d ("iomap: fix short copy in iomap_write_iter()")
*/
#include <errno.h>
@@ -138,4 +144,9 @@ static struct tst_test test = {
.needs_tmpdir = 1,
.setup = setup,
.test_all = test_writev,
+ .tags = (const struct tst_tag[]) {
+ {"linux-git", "20c64ec83a9f"},
+ {"linux-git", "3ac974796e5d"},
+ {},
+ }
};