]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/test_local_storage.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / test_local_storage.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 /*
4  * Copyright (C) 2020 Google LLC.
5  */
6
7 #include <asm-generic/errno-base.h>
8 #include <sys/stat.h>
9 #include <test_progs.h>
10 #include <linux/limits.h>
11
12 #include "local_storage.skel.h"
13 #include "network_helpers.h"
14 #include "task_local_storage_helpers.h"
15
16 #define TEST_STORAGE_VALUE 0xbeefdead
17
18 struct storage {
19         void *inode;
20         unsigned int value;
21 };
22
23 /* Fork and exec the provided rm binary and return the exit code of the
24  * forked process and its pid.
25  */
26 static int run_self_unlink(struct local_storage *skel, const char *rm_path)
27 {
28         int child_pid, child_status, ret;
29         int null_fd;
30
31         child_pid = fork();
32         if (child_pid == 0) {
33                 null_fd = open("/dev/null", O_WRONLY);
34                 dup2(null_fd, STDOUT_FILENO);
35                 dup2(null_fd, STDERR_FILENO);
36                 close(null_fd);
37
38                 skel->bss->monitored_pid = getpid();
39                 /* Use the copied /usr/bin/rm to delete itself
40                  * /tmp/copy_of_rm /tmp/copy_of_rm.
41                  */
42                 ret = execlp(rm_path, rm_path, rm_path, NULL);
43                 if (ret)
44                         exit(errno);
45         } else if (child_pid > 0) {
46                 waitpid(child_pid, &child_status, 0);
47                 ASSERT_EQ(skel->data->task_storage_result, 0, "task_storage_result");
48                 return WEXITSTATUS(child_status);
49         }
50
51         return -EINVAL;
52 }
53
54 static bool check_syscall_operations(int map_fd, int obj_fd)
55 {
56         struct storage val = { .value = TEST_STORAGE_VALUE },
57                        lookup_val = { .value = 0 };
58         int err;
59
60         /* Looking up an existing element should fail initially */
61         err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
62         if (!ASSERT_EQ(err, -ENOENT, "bpf_map_lookup_elem"))
63                 return false;
64
65         /* Create a new element */
66         err = bpf_map_update_elem(map_fd, &obj_fd, &val, BPF_NOEXIST);
67         if (!ASSERT_OK(err, "bpf_map_update_elem"))
68                 return false;
69
70         /* Lookup the newly created element */
71         err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
72         if (!ASSERT_OK(err, "bpf_map_lookup_elem"))
73                 return false;
74
75         /* Check the value of the newly created element */
76         if (!ASSERT_EQ(lookup_val.value, val.value, "bpf_map_lookup_elem"))
77                 return false;
78
79         err = bpf_map_delete_elem(map_fd, &obj_fd);
80         if (!ASSERT_OK(err, "bpf_map_delete_elem()"))
81                 return false;
82
83         /* The lookup should fail, now that the element has been deleted */
84         err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0);
85         if (!ASSERT_EQ(err, -ENOENT, "bpf_map_lookup_elem"))
86                 return false;
87
88         return true;
89 }
90
91 void test_test_local_storage(void)
92 {
93         char tmp_dir_path[] = "/tmp/local_storageXXXXXX";
94         int err, serv_sk = -1, task_fd = -1, rm_fd = -1;
95         struct local_storage *skel = NULL;
96         char tmp_exec_path[64];
97         char cmd[256];
98
99         skel = local_storage__open_and_load();
100         if (!ASSERT_OK_PTR(skel, "skel_load"))
101                 goto close_prog;
102
103         err = local_storage__attach(skel);
104         if (!ASSERT_OK(err, "attach"))
105                 goto close_prog;
106
107         task_fd = sys_pidfd_open(getpid(), 0);
108         if (!ASSERT_GE(task_fd, 0, "pidfd_open"))
109                 goto close_prog;
110
111         if (!check_syscall_operations(bpf_map__fd(skel->maps.task_storage_map),
112                                       task_fd))
113                 goto close_prog;
114
115         if (!ASSERT_OK_PTR(mkdtemp(tmp_dir_path), "mkdtemp"))
116                 goto close_prog;
117
118         snprintf(tmp_exec_path, sizeof(tmp_exec_path), "%s/copy_of_rm",
119                  tmp_dir_path);
120         snprintf(cmd, sizeof(cmd), "cp /bin/rm %s", tmp_exec_path);
121         if (!ASSERT_OK(system(cmd), "system(cp)"))
122                 goto close_prog_rmdir;
123
124         rm_fd = open(tmp_exec_path, O_RDONLY);
125         if (!ASSERT_GE(rm_fd, 0, "open(tmp_exec_path)"))
126                 goto close_prog_rmdir;
127
128         if (!check_syscall_operations(bpf_map__fd(skel->maps.inode_storage_map),
129                                       rm_fd))
130                 goto close_prog_rmdir;
131
132         /* Sets skel->bss->monitored_pid to the pid of the forked child
133          * forks a child process that executes tmp_exec_path and tries to
134          * unlink its executable. This operation should be denied by the loaded
135          * LSM program.
136          */
137         err = run_self_unlink(skel, tmp_exec_path);
138         if (!ASSERT_EQ(err, EPERM, "run_self_unlink"))
139                 goto close_prog_rmdir;
140
141         /* Set the process being monitored to be the current process */
142         skel->bss->monitored_pid = getpid();
143
144         /* Move copy_of_rm to a new location so that it triggers the
145          * inode_rename LSM hook with a new_dentry that has a NULL inode ptr.
146          */
147         snprintf(cmd, sizeof(cmd), "mv %s/copy_of_rm %s/check_null_ptr",
148                  tmp_dir_path, tmp_dir_path);
149         if (!ASSERT_OK(system(cmd), "system(mv)"))
150                 goto close_prog_rmdir;
151
152         ASSERT_EQ(skel->data->inode_storage_result, 0, "inode_storage_result");
153
154         serv_sk = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
155         if (!ASSERT_GE(serv_sk, 0, "start_server"))
156                 goto close_prog_rmdir;
157
158         ASSERT_EQ(skel->data->sk_storage_result, 0, "sk_storage_result");
159
160         if (!check_syscall_operations(bpf_map__fd(skel->maps.sk_storage_map),
161                                       serv_sk))
162                 goto close_prog_rmdir;
163
164 close_prog_rmdir:
165         snprintf(cmd, sizeof(cmd), "rm -rf %s", tmp_dir_path);
166         system(cmd);
167 close_prog:
168         close(serv_sk);
169         close(rm_fd);
170         close(task_fd);
171         local_storage__destroy(skel);
172 }
This page took 0.037876 seconds and 4 git commands to generate.