• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
26 #include <unordered_map>
27 
28 #include "functionalext.h"
29 
30 #define DEV_NULL_PATH "/dev/null"
31 
signal_handler_abort(int signum)32 void signal_handler_abort(int signum)
33 {
34     kill(getpid(), SIGSTOP);
35 }
36 
fdsan_test_get_tag_value()37 void fdsan_test_get_tag_value()
38 {
39     int fd = open(DEV_NULL_PATH, O_RDONLY);
40     uint64_t tag = fdsan_get_owner_tag(fd);
41     EXPECT_EQ("fdsan_test_get_tag_value", strcmp(fdsan_get_tag_type(tag), "native object of unknown type"), 0);
42     EXPECT_EQ("fdsan_test_get_tag_value", fdsan_get_tag_value(tag), 0);
43     EXPECT_EQ("fdsan_test_get_tag_value", close(fd), 0);
44 }
45 
fdsan_test_overflow()46 void fdsan_test_overflow()
47 {
48     std::unordered_map<int, uint64_t> fds;
49     for (int i = 0; i < 4096; ++i) {
50         int fd = open(DEV_NULL_PATH, O_RDONLY);
51         auto tag = 0xdead00000000ULL | i;
52         fdsan_exchange_owner_tag(fd, 0, tag);
53         fds[fd] = tag;
54     }
55 
56     for (auto [fd, tag] : fds) {
57         EXPECT_EQ("fdsan_test_overflow", fdsan_close_with_tag(fd, tag), 0);
58     }
59 }
60 
fdsan_test_vfork()61 void fdsan_test_vfork()
62 {
63     int fd = open(DEV_NULL_PATH, O_RDONLY);
64 
65     pid_t rc = vfork();
66     EXPECT_NE("fdsan_test_vfork", -1, rc);
67 
68     if (rc == 0) {
69         close(fd);
70         _exit(0);
71     }
72 
73     int status;
74     pid_t wait_result = waitpid(rc, &status, 0);
75     EXPECT_EQ("fdsan_test_vfork", wait_result, rc);
76     EXPECT_TRUE("fdsan_test_vfork", WIFEXITED(status));
77     EXPECT_EQ("fdsan_test_vfork", 0, WEXITSTATUS(status));
78 }
79 
fdsan_test_fatal_level()80 void fdsan_test_fatal_level()
81 {
82     struct sigaction sigabrt = {
83         .sa_handler = signal_handler_abort,
84     };
85     sigaction(SIGABRT, &sigabrt, nullptr);
86 
87     int status;
88     int pid = fork();
89     switch (pid) {
90         case -1: {
91             t_error("fork failed: %d\n", __LINE__);
92             break;
93         }
94         case 0: {
95             fdsan_set_error_level(FDSAN_ERROR_LEVEL_FATAL);
96             int fd = open(DEV_NULL_PATH, O_RDONLY);
97             uint64_t tag = 0xdead00000000ULL;
98             fdsan_exchange_owner_tag(fd, 0, tag);
99             fdsan_close_with_tag(fd, 0);
100             exit(0);
101         }
102         default: {
103             waitpid(pid, &status, WUNTRACED);
104             EXPECT_EQ("fdsan_test_fatal_level", WIFEXITED(status), 0);
105             EXPECT_EQ("fdsan_test_fatal_level", WIFSTOPPED(status), 1);
106             EXPECT_EQ("fdsan_test_fatal_level", WSTOPSIG(status), SIGSTOP);
107             kill(pid, SIGCONT);
108             break;
109         }
110     }
111     return;
112 }
113 
main()114 int main()
115 {
116     fdsan_test_get_tag_value();
117     fdsan_test_overflow();
118     fdsan_test_vfork();
119     fdsan_test_fatal_level();
120     return t_status;
121 }
122