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 <errno.h>
17 #include <signal.h>
18 #include <string.h>
19 #include <sys/wait.h>
20 #include <sys/select.h>
21 #include <sigchain.h>
22 #include "fortify_test.h"
23 #include "functionalext.h"
24 #include "test.h"
25 
26 /**
27  * @tc.name     : fd_set_0010
28  * @tc.desc     : test FD_SET with normal fd
29  * @tc.level    : Level 1
30  */
fd_set_0010(void)31 static void fd_set_0010(void)
32 {
33     fd_set readfds;
34     FD_ZERO(&readfds);
35     int sockfd = 0;
36     FD_SET(sockfd, &readfds);
37     EXPECT_EQ(fd_set_0010, (&readfds)->fds_bits[0], 1);
38 
39     return;
40 }
41 
42 /**
43  * @tc.name     : fd_set_0020
44  * @tc.desc     : test FD_SET with fd < 0
45  * @tc.level    : Level 2
46  */
fd_set_0020(void)47 static void fd_set_0020(void)
48 {
49     struct sigaction sigabrt = {
50         .sa_handler = SignalHandler,
51     };
52     sigaction(SIGABRT, &sigabrt, NULL);
53 
54     int status;
55     int pid = fork();
56     fd_set readfds;
57     int sockfd = -1;
58     switch (pid) {
59         case -1:
60             t_error("fork failed: %s\n", strerror(errno));
61             break;
62         case 0:
63             FD_ZERO(&readfds);
64             FD_SET(sockfd, &readfds);
65             exit(0);
66         default:
67             waitpid(pid, &status, WUNTRACED);
68             TEST(WIFEXITED(status) == 0);
69             TEST(WIFSTOPPED(status) == 1);
70             TEST(WSTOPSIG(status) == SIGSTOP);
71             kill(pid, SIGCONT);
72             break;
73     }
74 
75     return;
76 }
77 
78 /**
79  * @tc.name     : fd_set_0030
80  * @tc.desc     : test FD_SET with fd >= 1024
81  * @tc.level    : Level 2
82  */
fd_set_0030(void)83 static void fd_set_0030(void)
84 {
85     struct sigaction sigabrt = {
86         .sa_handler = SignalHandler,
87     };
88     sigaction(SIGABRT, &sigabrt, NULL);
89 
90     int status;
91     int pid = fork();
92     fd_set readfds;
93     int sockfd = 1024;
94     switch (pid) {
95         case -1:
96             t_error("fork failed: %s\n", strerror(errno));
97             break;
98         case 0:
99             FD_ZERO(&readfds);
100             FD_SET(sockfd, &readfds);
101             exit(0);
102         default:
103             waitpid(pid, &status, WUNTRACED);
104             TEST(WIFEXITED(status) == 0);
105             TEST(WIFSTOPPED(status) == 1);
106             TEST(WSTOPSIG(status) == SIGSTOP);
107             kill(pid, SIGCONT);
108             break;
109     }
110 
111     return;
112 }
113 
114 /**
115  * @tc.name     : fd_clr_0010
116  * @tc.desc     : test FD_CLR with normal fd
117  * @tc.level    : Level 1
118  */
fd_clr_0010(void)119 static void fd_clr_0010(void)
120 {
121     fd_set readfds;
122     FD_ZERO(&readfds);
123     int sockfd = 0;
124     FD_SET(sockfd, &readfds);
125     FD_CLR(sockfd, &readfds);
126     EXPECT_EQ(fd_set_0010, (&readfds)->fds_bits[0], 0);
127 
128     return;
129 }
130 
131 /**
132  * @tc.name     : fd_clr_0020
133  * @tc.desc     : test FD_CLR with fd < 0
134  * @tc.level    : Level 2
135  */
fd_clr_0020(void)136 static void fd_clr_0020(void)
137 {
138     struct sigaction sigabrt = {
139         .sa_handler = SignalHandler,
140     };
141     sigaction(SIGABRT, &sigabrt, NULL);
142 
143     int status;
144     int pid = fork();
145     fd_set readfds;
146     int sockfd = -1;
147     switch (pid) {
148         case -1:
149             t_error("fork failed: %s\n", strerror(errno));
150             break;
151         case 0:
152             FD_ZERO(&readfds);
153             FD_CLR(sockfd, &readfds);
154             exit(0);
155         default:
156             waitpid(pid, &status, WUNTRACED);
157             TEST(WIFEXITED(status) == 0);
158             TEST(WIFSTOPPED(status) == 1);
159             TEST(WSTOPSIG(status) == SIGSTOP);
160             kill(pid, SIGCONT);
161             break;
162     }
163 
164     return;
165 }
166 
167 /**
168  * @tc.name     : fd_clr_0030
169  * @tc.desc     : test FD_CLR with fd >= 1024
170  * @tc.level    : Level 2
171  */
fd_clr_0030(void)172 static void fd_clr_0030(void)
173 {
174     struct sigaction sigabrt = {
175         .sa_handler = SignalHandler,
176     };
177     sigaction(SIGABRT, &sigabrt, NULL);
178 
179     int status;
180     int pid = fork();
181     fd_set readfds;
182     int sockfd = 1024;
183     switch (pid) {
184         case -1:
185             t_error("fork failed: %s\n", strerror(errno));
186             break;
187         case 0:
188             FD_ZERO(&readfds);
189             FD_CLR(sockfd, &readfds);
190             exit(0);
191         default:
192             waitpid(pid, &status, WUNTRACED);
193             TEST(WIFEXITED(status) == 0);
194             TEST(WIFSTOPPED(status) == 1);
195             TEST(WSTOPSIG(status) == SIGSTOP);
196             kill(pid, SIGCONT);
197             break;
198     }
199 
200     return;
201 }
202 
203 /**
204  * @tc.name     : fd_isset_0010
205  * @tc.desc     : test FD_ISSET with normal fd
206  * @tc.level    : Level 1
207  */
fd_isset_0010(void)208 static void fd_isset_0010(void)
209 {
210     fd_set readfds;
211     FD_ZERO(&readfds);
212     int sockfd = 0;
213     FD_SET(sockfd, &readfds);
214     int res = FD_ISSET(sockfd, &readfds);
215     EXPECT_EQ(fd_set_0010, res, 1);
216 
217     return;
218 }
219 
220 /**
221  * @tc.name     : fd_isset_0020
222  * @tc.desc     : test FD_ISSET with fd < 0
223  * @tc.level    : Level 2
224  */
fd_isset_0020(void)225 static void fd_isset_0020(void)
226 {
227     fd_set readfds;
228     FD_ZERO(&readfds);
229     int sockfd = -1;
230     int res = FD_ISSET(sockfd, &readfds);
231     EXPECT_EQ(fd_set_0010, res, 0);
232 
233     return;
234 }
235 
236 /**
237  * @tc.name     : fd_isset_0030
238  * @tc.desc     : test FD_ISSET with fd >= 1024
239  * @tc.level    : Level 2
240  */
fd_isset_0030(void)241 static void fd_isset_0030(void)
242 {
243     fd_set readfds;
244     FD_ZERO(&readfds);
245     int sockfd = 1024;
246     int res = FD_ISSET(sockfd, &readfds);
247     EXPECT_EQ(fd_set_0010, res, 0);
248 
249     return;
250 }
251 
main(int argc, char *argv[])252 int main(int argc, char *argv[])
253 {
254     remove_all_special_handler(SIGABRT);
255     fd_set_0010();
256     fd_set_0020();
257     fd_set_0030();
258     fd_clr_0010();
259     fd_clr_0020();
260     fd_clr_0030();
261     fd_isset_0010();
262     fd_isset_0020();
263     fd_isset_0030();
264     return t_status;
265 }