1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2021 Facebook */
3 
4 #define _GNU_SOURCE         /* See feature_test_macros(7) */
5 #include <unistd.h>
6 #include <sys/syscall.h>   /* For SYS_xxx definitions */
7 #include <sys/types.h>
8 #include <test_progs.h>
9 #include "task_local_storage.skel.h"
10 #include "task_local_storage_exit_creds.skel.h"
11 #include "task_ls_recursion.skel.h"
12 
13 static void test_sys_enter_exit(void)
14 {
15 	struct task_local_storage *skel;
16 	int err;
17 
18 	skel = task_local_storage__open_and_load();
19 	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
20 		return;
21 
22 	skel->bss->target_pid = syscall(SYS_gettid);
23 
24 	err = task_local_storage__attach(skel);
25 	if (!ASSERT_OK(err, "skel_attach"))
26 		goto out;
27 
28 	syscall(SYS_gettid);
29 	syscall(SYS_gettid);
30 
31 	/* 3x syscalls: 1x attach and 2x gettid */
32 	ASSERT_EQ(skel->bss->enter_cnt, 3, "enter_cnt");
33 	ASSERT_EQ(skel->bss->exit_cnt, 3, "exit_cnt");
34 	ASSERT_EQ(skel->bss->mismatch_cnt, 0, "mismatch_cnt");
35 out:
36 	task_local_storage__destroy(skel);
37 }
38 
39 static void test_exit_creds(void)
40 {
41 	struct task_local_storage_exit_creds *skel;
42 	int err;
43 
44 	skel = task_local_storage_exit_creds__open_and_load();
45 	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
46 		return;
47 
48 	err = task_local_storage_exit_creds__attach(skel);
49 	if (!ASSERT_OK(err, "skel_attach"))
50 		goto out;
51 
52 	/* trigger at least one exit_creds() */
53 	if (CHECK_FAIL(system("ls > /dev/null")))
54 		goto out;
55 
56 	/* sync rcu to make sure exit_creds() is called for "ls" */
57 	kern_sync_rcu();
58 	ASSERT_EQ(skel->bss->valid_ptr_count, 0, "valid_ptr_count");
59 	ASSERT_NEQ(skel->bss->null_ptr_count, 0, "null_ptr_count");
60 out:
61 	task_local_storage_exit_creds__destroy(skel);
62 }
63 
64 static void test_recursion(void)
65 {
66 	struct task_ls_recursion *skel;
67 	int err;
68 
69 	skel = task_ls_recursion__open_and_load();
70 	if (!ASSERT_OK_PTR(skel, "skel_open_and_load"))
71 		return;
72 
73 	err = task_ls_recursion__attach(skel);
74 	if (!ASSERT_OK(err, "skel_attach"))
75 		goto out;
76 
77 	/* trigger sys_enter, make sure it does not cause deadlock */
78 	syscall(SYS_gettid);
79 
80 out:
81 	task_ls_recursion__destroy(skel);
82 }
83 
84 void test_task_local_storage(void)
85 {
86 	if (test__start_subtest("sys_enter_exit"))
87 		test_sys_enter_exit();
88 	if (test__start_subtest("exit_creds"))
89 		test_exit_creds();
90 	if (test__start_subtest("recursion"))
91 		test_recursion();
92 }
93