[LTP] [PATCH] Add tls parameter and flag:CLONE_SETTLS cover for clone and clone3 syscall
chunfuwen
chwen@redhat.com
Tue Apr 22 11:32:57 CEST 2025
tls parameter and related flag:CLONE_SETTLS are missed in the testing,
so add them into existed test case
Signed-off-by: chunfuwen <chwen@redhat.com>
---
testcases/kernel/syscalls/clone/clone08.c | 40 ++++++++++++++++++---
testcases/kernel/syscalls/clone3/clone301.c | 36 ++++++++++++++++---
2 files changed, 67 insertions(+), 9 deletions(-)
diff --git a/testcases/kernel/syscalls/clone/clone08.c b/testcases/kernel/syscalls/clone/clone08.c
index dd97f3ff1..f5a8119a8 100644
--- a/testcases/kernel/syscalls/clone/clone08.c
+++ b/testcases/kernel/syscalls/clone/clone08.c
@@ -17,7 +17,11 @@
#include "lapi/syscalls.h"
#include "lapi/futex.h"
+#define TLS_SIZE 4096
+#define TLS_ALIGN 16
+
static pid_t ptid, ctid, tgid;
+static void *tls_ptr;
static void *child_stack;
static void test_clone_parent(int t);
@@ -32,6 +36,9 @@ static int child_clone_parent_settid(void *);
static void test_clone_thread(int t);
static int child_clone_thread(void *);
+/* TLS variable to validate in child */
+static __thread int tls_test_var = 12345;
+
/*
* Children cloned with CLONE_VM should avoid using any functions that
* might require dl_runtime_resolve, because they share thread-local
@@ -46,14 +53,14 @@ static struct test_case {
void (*testfunc)(int);
int (*do_child)(void *);
} test_cases[] = {
- {"CLONE_PARENT", CLONE_PARENT | SIGCHLD,
+ {"CLONE_PARENT", CLONE_PARENT | CLONE_SETTLS | SIGCHLD,
test_clone_parent, child_clone_parent},
- {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | SIGCHLD,
+ {"CLONE_CHILD_SETTID", CLONE_CHILD_SETTID | CLONE_SETTLS | SIGCHLD,
test_clone_tid, child_clone_child_settid},
- {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | SIGCHLD,
+ {"CLONE_PARENT_SETTID", CLONE_PARENT_SETTID | CLONE_VM | CLONE_SETTLS | SIGCHLD,
test_clone_tid, child_clone_parent_settid},
{"CLONE_THREAD", CLONE_THREAD | CLONE_SIGHAND | CLONE_VM |
- CLONE_CHILD_CLEARTID | SIGCHLD,
+ CLONE_CHILD_CLEARTID | CLONE_SETTLS | SIGCHLD,
test_clone_thread, child_clone_thread},
};
@@ -66,17 +73,24 @@ static void do_test(unsigned int i)
static void setup(void)
{
child_stack = SAFE_MALLOC(CHILD_STACK_SIZE);
+ tls_ptr = aligned_alloc(TLS_ALIGN, TLS_SIZE);
+ if (!tls_ptr) {
+ perror("aligned_alloc");
+ exit(EXIT_FAILURE);
+ }
+ memset(tls_ptr, 0, TLS_SIZE);
}
static void cleanup(void)
{
free(child_stack);
+ free(tls_ptr);
}
static long clone_child(const struct test_case *t)
{
TEST(ltp_clone7(t->flags, t->do_child, NULL, CHILD_STACK_SIZE,
- child_stack, &ptid, NULL, &ctid));
+ child_stack, &ptid, tls_ptr, &ctid));
if (TST_RET == -1 && TTERRNO == ENOSYS)
tst_brk(TCONF, "clone does not support 7 args");
@@ -87,6 +101,14 @@ static long clone_child(const struct test_case *t)
return TST_RET;
}
+static void validate_tls(void)
+{
+ if (tls_test_var == 12345)
+ tst_res(TPASS, "Child TLS variable has expected value");
+ else
+ tst_res(TFAIL, "Child TLS variable corrupted or not set");
+}
+
static void test_clone_parent(int t)
{
pid_t child;
@@ -102,6 +124,8 @@ static void test_clone_parent(int t)
static int child_clone_parent(void *arg LTP_ATTRIBUTE_UNUSED)
{
+ validate_tls();
+
if (parent_ppid == getppid()) {
tst_res(TPASS, "clone and forked child has the same parent");
} else {
@@ -120,6 +144,8 @@ static void test_clone_tid(int t)
static int child_clone_child_settid(void *arg LTP_ATTRIBUTE_UNUSED)
{
+ validate_tls();
+
if (ctid == tst_syscall(__NR_getpid))
tst_res(TPASS, "clone() correctly set ctid");
else
@@ -130,6 +156,8 @@ static int child_clone_child_settid(void *arg LTP_ATTRIBUTE_UNUSED)
static int child_clone_parent_settid(void *arg LTP_ATTRIBUTE_UNUSED)
{
+ validate_tls();
+
if (ptid == tst_syscall(__NR_getpid))
tst_res(TPASS, "clone() correctly set ptid");
else
@@ -175,6 +203,8 @@ static void test_clone_thread(int t)
static int child_clone_thread(void *arg LTP_ATTRIBUTE_UNUSED)
{
+ validate_tls();
+
if (tgid == tst_syscall(__NR_getpid))
tst_res(TPASS, "clone has the same thread id");
else
diff --git a/testcases/kernel/syscalls/clone3/clone301.c b/testcases/kernel/syscalls/clone3/clone301.c
index deed30b9f..9571c9f5c 100644
--- a/testcases/kernel/syscalls/clone3/clone301.c
+++ b/testcases/kernel/syscalls/clone3/clone301.c
@@ -18,22 +18,38 @@
#define CHILD_SIGNAL SIGUSR1
#define DATA 777
+#define TLS_SIZE 4096
+#define TLS_ALIGN 16
static int pidfd, child_tid, parent_tid, parent_received_signal;
static volatile int child_received_signal, child_data;
static struct clone_args *args;
+/* TLS variable to validate in child */
+static __thread int tls_test_var = 12345;
+
static struct tcase {
uint64_t flags;
int exit_signal;
} tcases[] = {
{0, SIGCHLD},
{0, SIGUSR2},
- {CLONE_FS, SIGCHLD},
- {CLONE_NEWPID, SIGCHLD},
- {CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_PIDFD, SIGCHLD},
+ {CLONE_FS | CLONE_SETTLS, SIGCHLD},
+ {CLONE_NEWPID | CLONE_SETTLS, SIGCHLD},
+ {CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_PIDFD | CLONE_SETTLS, SIGCHLD},
};
+static void *allocate_tls_region(void)
+{
+ void *tls_area = aligned_alloc(TLS_ALIGN, TLS_SIZE);
+ if (!tls_area) {
+ perror("aligned_alloc");
+ exit(EXIT_FAILURE);
+ }
+ memset(tls_area, 0, TLS_SIZE);
+ return tls_area;
+}
+
static void parent_rx_signal(int sig)
{
parent_received_signal = sig;
@@ -67,6 +83,13 @@ static void do_child(int clone_pidfd)
{
int count = 1000;
+ /* Validate TLS usage */
+ if (tls_test_var == 12345) {
+ tst_res(TPASS, "Child TLS variable has expected value");
+ } else {
+ tst_res(TFAIL, "Child TLS variable corrupted or not set");
+ }
+
if (clone_pidfd) {
child_received_signal = 0;
child_data = 0;
@@ -111,6 +134,8 @@ static void run(unsigned int n)
int status, clone_pidfd = tc->flags & CLONE_PIDFD;
pid_t pid;
+ void *tls_ptr = allocate_tls_region();
+
args->flags = tc->flags;
args->pidfd = (uint64_t)(&pidfd);
args->child_tid = (uint64_t)(&child_tid);
@@ -118,7 +143,7 @@ static void run(unsigned int n)
args->exit_signal = tc->exit_signal;
args->stack = 0;
args->stack_size = 0;
- args->tls = 0;
+ args->tls = (uint64_t)tls_ptr;
parent_received_signal = 0;
SAFE_SIGACTION(tc->exit_signal, &psig_action, NULL);
@@ -126,6 +151,7 @@ static void run(unsigned int n)
TEST(pid = clone3(args, sizeof(*args)));
if (pid < 0) {
tst_res(TFAIL | TTERRNO, "clone3() failed (%d)", n);
+ free(tls_ptr);
return;
}
@@ -139,11 +165,13 @@ static void run(unsigned int n)
TEST(pidfd_send_signal(pidfd, CHILD_SIGNAL, &uinfo, 0));
if (TST_RET != 0) {
tst_res(TFAIL | TTERRNO, "pidfd_send_signal() failed");
+ free(tls_ptr);
return;
}
}
SAFE_WAITPID(pid, &status, __WALL);
+ free(tls_ptr);
if (!parent_received_signal) {
tst_res(TFAIL, "Parent haven't got signal");
--
2.43.5
More information about the ltp
mailing list