1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <signal.h>
19 #include <pthread.h>
20 #include <fcntl.h>
21 #include <stdint.h>
22 #include <string.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 #include <musl_log.h>
26
27 #include <unordered_map>
28
29 #include "functionalext.h"
30
31 #define DEV_NULL_PATH "/dev/null"
32 const char *file_path = "/data/local/tmp/test.txt";
33
34 extern "C" FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
35 extern "C" int __fclose_ca(FILE *);
36
signal_handler_abort(int signum)37 void signal_handler_abort(int signum)
38 {
39 kill(getpid(), SIGSTOP);
40 }
41
signal_handler_abort1(int signum)42 void signal_handler_abort1(int signum)
43 {
44 exit(signum);
45 }
46
fdsan_test_get_tag_value()47 void fdsan_test_get_tag_value()
48 {
49 int fd = open(DEV_NULL_PATH, O_RDONLY);
50 uint64_t tag = fdsan_get_owner_tag(fd);
51 EXPECT_EQ("fdsan_test_get_tag_value", strcmp(fdsan_get_tag_type(tag), "native object of unknown type"), 0);
52 EXPECT_EQ("fdsan_test_get_tag_value", fdsan_get_tag_value(tag), 0);
53 EXPECT_EQ("fdsan_test_get_tag_value", close(fd), 0);
54 }
55
fdsan_test_overflow()56 void fdsan_test_overflow()
57 {
58 std::unordered_map<int, uint64_t> fds;
59 for (int i = 0; i < 4096; ++i) {
60 int fd = open(DEV_NULL_PATH, O_RDONLY);
61 auto tag = 0xdead00000000ULL | i;
62 fdsan_exchange_owner_tag(fd, 0, tag);
63 fds[fd] = tag;
64 }
65
66 for (auto [fd, tag] : fds) {
67 EXPECT_EQ("fdsan_test_overflow", fdsan_close_with_tag(fd, tag), 0);
68 }
69 }
70
fdsan_test_vfork()71 void fdsan_test_vfork()
72 {
73 int fd = open(DEV_NULL_PATH, O_RDONLY);
74
75 pid_t rc = vfork();
76 EXPECT_NE("fdsan_test_vfork", -1, rc);
77
78 if (rc == 0) {
79 close(fd);
80 _exit(0);
81 }
82
83 int status;
84 pid_t wait_result = waitpid(rc, &status, 0);
85 EXPECT_EQ("fdsan_test_vfork", wait_result, rc);
86 EXPECT_TRUE("fdsan_test_vfork", WIFEXITED(status));
87 EXPECT_EQ("fdsan_test_vfork", 0, WEXITSTATUS(status));
88 }
89
fdsan_test_fatal_level()90 void fdsan_test_fatal_level()
91 {
92 struct sigaction sigabrt = {
93 .sa_handler = signal_handler_abort,
94 };
95 sigaction(SIGABRT, &sigabrt, nullptr);
96
97 int status;
98 int pid = fork();
99 switch (pid) {
100 case -1: {
101 t_error("fork failed: %d\n", __LINE__);
102 break;
103 }
104 case 0: {
105 fdsan_set_error_level(FDSAN_ERROR_LEVEL_FATAL);
106 int fd = open(DEV_NULL_PATH, O_RDONLY);
107 uint64_t tag = 0xdead00000000ULL;
108 fdsan_exchange_owner_tag(fd, 0, tag);
109 fdsan_close_with_tag(fd, 0);
110 exit(0);
111 }
112 default: {
113 waitpid(pid, &status, WUNTRACED);
114 EXPECT_EQ("fdsan_test_fatal_level", WIFEXITED(status), 0);
115 EXPECT_EQ("fdsan_test_fatal_level", WIFSTOPPED(status), 1);
116 EXPECT_EQ("fdsan_test_fatal_level", WSTOPSIG(status), SIGSTOP);
117 kill(pid, SIGCONT);
118 break;
119 }
120 }
121 return;
122 }
123
CreateFile()124 bool CreateFile()
125 {
126 // 创建文件并打开文件描述符
127 int fd = open(file_path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
128 if (fd == -1) {
129 return false;
130 }
131
132 // 关闭文件描述符
133 close(fd);
134 return true;
135 }
136
137
fdsan_test_fork_subprocess_disabled()138 void fdsan_test_fork_subprocess_disabled()
139 {
140 struct sigaction sigabrt = {
141 .sa_handler = signal_handler_abort,
142 };
143 sigaction(SIGABRT, &sigabrt, nullptr);
144 int status;
145 int pid = fork();
146 switch (pid) {
147 case -1: {
148 t_error("fork failed: %d\n", __LINE__);
149 break;
150 }
151 case 0: {
152 enum fdsan_error_level errorLevel = fdsan_get_error_level();
153 if (errorLevel != FDSAN_ERROR_LEVEL_DISABLED) {
154 abort();
155 }
156 exit(0);
157 }
158 default: {
159 waitpid(pid, &status, WUNTRACED);
160 EXPECT_EQ("fdsan_test_fork_subprocess_disabled WIFEXITED", WIFEXITED(status), 1);
161 EXPECT_EQ("fdsan_test_fork_subprocess_disabled WIFSTOPPED", WIFSTOPPED(status), 0);
162 // 子进程的错误等级默认应该是disabled,这里检测子进程不会收到abort信号
163 EXPECT_EQ("fdsan_test_fork_subprocess_disabled WSTOPSIG", WSTOPSIG(status), 0);
164 kill(pid, SIGCONT);
165 break;
166 }
167 }
168 return;
169 }
170
fdsan_test_internal_fopen_succeed()171 void fdsan_test_internal_fopen_succeed()
172 {
173 struct sigaction sigabrt = {
174 .sa_handler = signal_handler_abort,
175 };
176 sigaction(SIGABRT, &sigabrt, nullptr);
177 bool res = CreateFile();
178 if (!res) {
179 t_error("fdsan_test_internal_fopen create file failed");
180 return;
181 }
182 int status;
183 int pid = fork();
184 switch (pid) {
185 case -1: {
186 t_error("fork failed: %d\n", __LINE__);
187 break;
188 }
189 case 0: {
190 fdsan_set_error_level(FDSAN_ERROR_LEVEL_FATAL);
191 unsigned char str[1024];
192 FILE f;
193 FILE *ptr = __fopen_rb_ca(file_path, &f, str, sizeof(str));
194 if (ptr == nullptr) {
195 t_error("fdsan_test_internal_fopen_succeed open file failed: ptr == NULL");
196 }
197 if (ptr) {
198 __fclose_ca(ptr);
199 }
200 exit(0);
201 }
202 default: {
203 waitpid(pid, &status, WUNTRACED);
204 EXPECT_EQ("fdsan_test_internal_fopen_succeed WIFEXITED", WIFEXITED(status), 1);
205 EXPECT_EQ("fdsan_test_internal_fopen_succeed WIFSTOPPED", WIFSTOPPED(status), 0);
206 // 子进程应该能够匹配到对应的tag,不应该通过信号方式退出,这里检测子进程不会收到abort信号
207 EXPECT_EQ("fdsan_test_internal_fopen_succeed WSTOPSIG", WSTOPSIG(status), 0);
208 kill(pid, SIGCONT);
209 break;
210 }
211 }
212 return;
213 }
214
main()215 int main()
216 {
217 fdsan_test_get_tag_value();
218 fdsan_test_overflow();
219 fdsan_test_vfork();
220 fdsan_test_fatal_level();
221 fdsan_test_fork_subprocess_disabled();
222 fdsan_test_internal_fopen_succeed();
223 return t_status;
224 }