• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include <errno.h>
16 #include <poll.h>
17 #include <signal.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/wait.h>
21 #include <unistd.h>
22 #include <sigchain.h>
23 #include "fortify_test.h"
24 #include "functionalext.h"
25 #include "test.h"
26 
27 #define PPOLL_TIMESPEC_NSEC (100)
28 
29 /**
30  * @tc.name     : poll_0010
31  * @tc.desc     : test poll normal condition
32  * @tc.level    : Level 0
33  */
poll_0010(void)34 static void poll_0010(void)
35 {
36     errno = 0;
37     TEST(poll(NULL, 0, 1) == 0);
38     TEST(errno == 0);
39     return;
40 }
41 
42 /**
43  * @tc.name     : poll_0020
44  * @tc.desc     : test poll suppress compiler optimizations
45  * @tc.level    : Level 2
46  */
poll_0020(void)47 static void poll_0020(void)
48 {
49     struct sigaction sigabrt = {
50         .sa_handler = SignalHandler,
51     };
52     sigaction(SIGABRT, &sigabrt, NULL);
53 
54     nfds_t fd_count = atoi("2");
55     struct pollfd buf[1] = {{0, POLLIN, 0}};
56 
57     int status;
58     int pid = fork();
59     switch (pid) {
60         case -1:
61             t_error("fork failed: %s\n", strerror(errno));
62             break;
63         case 0:
64             // Set timeout to 0 to prevent waiting for polling if hardening tests fail.
65             poll(buf, fd_count, 0);
66             exit(0);
67         default:
68             waitpid(pid, &status, WUNTRACED);
69             TEST(WIFEXITED(status) == 0);
70             TEST(WIFSTOPPED(status) == 1);
71             TEST(WSTOPSIG(status) == SIGSTOP);
72             kill(pid, SIGCONT);
73             break;
74     }
75 
76     return;
77 }
78 
79 /**
80  * @tc.name     : poll_0030
81  * @tc.desc     : test poll with buf's size greater than fd_count, return fd_count
82  * @tc.level    : Level 1
83  */
poll_0030(void)84 static void poll_0030(void)
85 {
86     int fd[2];
87     int res = pipe(fd);
88     if (res != 0) {
89         EXPECT_TRUE("poll_0030 pipe", 0);
90     }
91     int pid = fork();
92     if (pid == -1) {
93         EXPECT_TRUE("poll_0030 fork", 0);
94     } else if (pid == 0) {
95         // child process: send msg to master process
96         close(fd[0]);
97         const char* message = "";
98         write(fd[1], message, strlen(message) + 1);
99         close(fd[1]);
100         exit(0);
101     } else {
102         // master process: wait events from child process
103         close(fd[1]);
104         struct pollfd buf[2] = {{fd[0], POLLIN, 0}, {fd[0], POLLIN, 0}};
105         int result = poll(buf, 1, 100);
106         char buff;
107         while (read(fd[0], &buff, 1) > 0);
108         close(fd[0]);
109         EXPECT_EQ("poll_0030", result, 1);
110     }
111     return;
112 }
113 
114 
115 #ifdef _GNU_SOURCE
116 /**
117  * @tc.name     : ppoll_0010
118  * @tc.desc     : test ppoll normal condition
119  * @tc.level    : Level 0
120  */
ppoll_0010(void)121 static void ppoll_0010(void)
122 {
123     errno = 0;
124     struct timespec ts = { .tv_nsec = PPOLL_TIMESPEC_NSEC };
125     TEST(ppoll(NULL, 0, &ts, NULL) == 0);
126     TEST(errno == 0);
127     return;
128 }
129 
130 /**
131  * @tc.name     : ppoll_0020
132  * @tc.desc     : test ppoll suppress compiler optimizations
133  * @tc.level    : Level 2
134  */
ppoll_0020(void)135 static void ppoll_0020(void)
136 {
137     struct sigaction sigabrt = {
138         .sa_handler = SignalHandler,
139     };
140     sigaction(SIGABRT, &sigabrt, NULL);
141 
142     nfds_t fd_count = atoi("2");
143     struct pollfd buf[1] = {{0, POLLIN, 0}};
144     // Set timeout to zero to prevent waiting in ppoll when fortify test fails.
145     struct timespec timeout;
146     timeout.tv_sec = timeout.tv_nsec = 0;
147 
148     int status;
149     int pid = fork();
150     switch (pid) {
151         case -1:
152             t_error("fork failed: %s\n", strerror(errno));
153             break;
154         case 0:
155             ppoll(buf, fd_count, &timeout, NULL);
156             exit(0);
157         default:
158             waitpid(pid, &status, WUNTRACED);
159             TEST(WIFEXITED(status) == 0);
160             TEST(WIFSTOPPED(status) == 1);
161             TEST(WSTOPSIG(status) == SIGSTOP);
162             kill(pid, SIGCONT);
163             break;
164     }
165 
166     return;
167 }
168 
169 /**
170  * @tc.name     : ppoll_0030
171  * @tc.desc     : test poll with buf's size greater than fd_count, return fd_count
172  * @tc.level    : Level 1
173  */
ppoll_0030(void)174 static void ppoll_0030(void)
175 {
176 
177     int fd[2];
178     int res = pipe(fd);
179     if (res != 0) {
180         EXPECT_TRUE("poll_0030 pipe", 0);
181     }
182     int pid = fork();
183     if (pid == -1) {
184         EXPECT_TRUE("poll_0030 fork", 0);
185     } else if (pid == 0) {
186         // child process: send msg to master process
187         close(fd[0]);
188         const char* message = "";
189         write(fd[1], message, strlen(message) + 1);
190         close(fd[1]);
191         exit(0);
192     } else {
193         // master process: wait events from child process
194         close(fd[1]);
195         struct pollfd buf[2] = {{fd[0], POLLIN, 0}, {fd[0], POLLIN, 0}};
196         struct timespec ts = { .tv_nsec = 100000000 };
197         int result = ppoll(buf, 1, &ts, NULL);
198         char buff;
199         while (read(fd[0], &buff, 1) > 0);
200         close(fd[0]);
201         EXPECT_EQ("ppoll_0030", result, 1);
202     }
203     return;
204 }
205 
206 #endif
207 
main(int argc,char * argv[])208 int main(int argc, char *argv[]) {
209     remove_all_special_handler(SIGABRT);
210     poll_0010();
211     poll_0020();
212     poll_0030();
213 #ifdef _GNU_SOURCE
214     ppoll_0010();
215     ppoll_0020();
216     ppoll_0030();
217 #endif
218 
219     return t_status;
220 }