[LTP] [PATCH] Add tls parameter and flag:CLONE_SETTLS cover for clone and clone3 syscall
Chunfu Wen
chwen@redhat.com
Thu Apr 24 07:25:19 CEST 2025
Hello Maintainers,
Could someone please drop a review of this patch?
Best Regards,
Chunfu Wen
On Tue, Apr 22, 2025 at 5:33 PM chunfuwen via ltp <ltp@lists.linux.it>
wrote:
> 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
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
>
More information about the ltp
mailing list