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 <fcntl.h>
17 #include <signal.h>
18 #include <string.h>
19 #include <sys/wait.h>
20 #include <sigchain.h>
21 #include "fortify_test.h"
22 #include "functionalext.h"
23 #include "test.h"
24 
25 #define FILE_MODE_ALL (0777)
26 
27 #ifdef open64
28 #undef open64
29 #endif
30 
31 #ifdef openat64
32 #undef openat64
33 #endif
34 
35 /**
36  * @tc.name     : open_0010
37  * @tc.desc     : test open normal condition
38  * @tc.level    : Level 0
39  */
open_0010(void)40 static void open_0010(void)
41 {
42     int fd = open("/proc/version", O_RDWR | O_CREAT, FILE_MODE_ALL);
43     TEST(fd != -1);
44     close(fd);
45 
46     return;
47 }
48 
49 /**
50  * @tc.name     : open_0020
51  * @tc.desc     : test open O_CREAT without mode
52  * @tc.level    : Level 2
53  */
open_0020(void)54 static void open_0020(void)
55 {
56     struct sigaction sigabrt = {
57         .sa_handler = SignalHandler,
58     };
59     sigaction(SIGABRT, &sigabrt, NULL);
60 
61     int flags = O_CREAT;
62     int status;
63     int pid = fork();
64     switch (pid) {
65         case -1:
66             t_error("fork failed: %s\n", strerror(errno));
67             break;
68         case 0:
69             open("/proc/version", flags);
70             exit(0);
71         default:
72             waitpid(pid, &status, WUNTRACED);
73             TEST(WIFEXITED(status) == 0);
74             TEST(WIFSTOPPED(status) == 1);
75             TEST(WSTOPSIG(status) == SIGSTOP);
76             kill(pid, SIGCONT);
77             break;
78     }
79 
80     return;
81 }
82 
83 /**
84  * @tc.name     : open_0030
85  * @tc.desc     : test open O_TMPFILE without mode
86  * @tc.level    : Level 2
87  */
open_0030(void)88 static void open_0030(void)
89 {
90     struct sigaction sigabrt = {
91         .sa_handler = SignalHandler,
92     };
93     sigaction(SIGABRT, &sigabrt, NULL);
94 
95     int flags = O_TMPFILE;
96     int status;
97     int pid = fork();
98     switch (pid) {
99         case -1:
100             t_error("fork failed: %s\n", strerror(errno));
101             break;
102         case 0:
103             open("/proc/version", flags);
104             exit(0);
105         default:
106             waitpid(pid, &status, WUNTRACED);
107             TEST(WIFEXITED(status) == 0);
108             TEST(WIFSTOPPED(status) == 1);
109             TEST(WSTOPSIG(status) == SIGSTOP);
110             kill(pid, SIGCONT);
111             break;
112     }
113 
114     return;
115 }
116 
117 /**
118  * @tc.name     : open_0040
119  * @tc.desc     : test open only O_RDWR
120  * @tc.level    : Level 1
121  */
open_0040(void)122 static void open_0040(void)
123 {
124     int fd = open("/proc/version", O_RDWR);
125     EXPECT_NE(open_0040, fd, -1);
126     close(fd);
127 
128     return;
129 }
130 
131 /**
132  * @tc.name     : openat_0010
133  * @tc.desc     : test openat normal condition
134  * @tc.level    : Level 0
135  */
openat_0010(void)136 static void openat_0010(void)
137 {
138     int fd = openat(AT_FDCWD, "/proc/version", O_RDWR | O_CREAT, FILE_MODE_ALL);
139     TEST(fd != -1);
140     close(fd);
141 
142     return;
143 }
144 
145 /**
146  * @tc.name     : openat_0020
147  * @tc.desc     : test openat O_CREAT without mode
148  * @tc.level    : Level 2
149  */
openat_0020(void)150 static void openat_0020(void)
151 {
152     struct sigaction sigabrt = {
153         .sa_handler = SignalHandler,
154     };
155     sigaction(SIGABRT, &sigabrt, NULL);
156 
157     int flags = O_CREAT;
158     int status;
159     int pid = fork();
160     switch (pid) {
161         case -1:
162             t_error("fork failed: %s\n", strerror(errno));
163             break;
164         case 0:
165             openat(AT_FDCWD, "/proc/version", flags);
166             exit(0);
167         default:
168             waitpid(pid, &status, WUNTRACED);
169             TEST(WIFEXITED(status) == 0);
170             TEST(WIFSTOPPED(status) == 1);
171             TEST(WSTOPSIG(status) == SIGSTOP);
172             kill(pid, SIGCONT);
173             break;
174     }
175 
176     return;
177 }
178 
179 /**
180  * @tc.name     : openat_0030
181  * @tc.desc     : test openat O_TMPFILE without mode
182  * @tc.level    : Level 2
183  */
openat_0030(void)184 static void openat_0030(void)
185 {
186     struct sigaction sigabrt = {
187         .sa_handler = SignalHandler,
188     };
189     sigaction(SIGABRT, &sigabrt, NULL);
190 
191     int flags = O_TMPFILE;
192     int status;
193     int pid = fork();
194     switch (pid) {
195         case -1:
196             t_error("fork failed: %s\n", strerror(errno));
197             break;
198         case 0:
199             openat(AT_FDCWD, "/proc/version", flags);
200             exit(0);
201         default:
202             waitpid(pid, &status, WUNTRACED);
203             TEST(WIFEXITED(status) == 0);
204             TEST(WIFSTOPPED(status) == 1);
205             TEST(WSTOPSIG(status) == SIGSTOP);
206             kill(pid, SIGCONT);
207             break;
208     }
209 
210     return;
211 }
212 
213 /**
214  * @tc.name     : openat_0040
215  * @tc.desc     : test openat only O_RDWR
216  * @tc.level    : Level 1
217  */
openat_0040(void)218 static void openat_0040(void)
219 {
220     int fd = openat(AT_FDCWD, "/proc/version", O_RDWR);
221     EXPECT_NE(openat_0040, fd, -1);
222     close(fd);
223 
224     return;
225 }
226 
227 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
228 /**
229  * @tc.name     : open64_0010
230  * @tc.desc     : test open64 normal condition
231  * @tc.level    : Level 0
232  */
open64_0010(void)233 static void open64_0010(void)
234 {
235     int fd = open64("/proc/version", O_RDWR | O_CREAT, FILE_MODE_ALL);
236     TEST(fd != -1);
237     close(fd);
238 
239     return;
240 }
241 
242 /**
243  * @tc.name     : open64_0020
244  * @tc.desc     : test open64 O_CREAT without mode
245  * @tc.level    : Level 2
246  */
open64_0020(void)247 static void open64_0020(void)
248 {
249     struct sigaction sigabrt = {
250         .sa_handler = SignalHandler,
251     };
252     sigaction(SIGABRT, &sigabrt, NULL);
253 
254     int flags = O_CREAT;
255     int status;
256     int pid = fork();
257     switch (pid) {
258         case -1:
259             t_error("fork failed: %s\n", strerror(errno));
260             break;
261         case 0:
262             open64("/proc/version", flags);
263             exit(0);
264         default:
265             waitpid(pid, &status, WUNTRACED);
266             TEST(WIFEXITED(status) == 0);
267             TEST(WIFSTOPPED(status) == 1);
268             TEST(WSTOPSIG(status) == SIGSTOP);
269             kill(pid, SIGCONT);
270             break;
271     }
272 
273     return;
274 }
275 
276 /**
277  * @tc.name     : open64_0030
278  * @tc.desc     : test open64 O_TMPFILE without mode
279  * @tc.level    : Level 2
280  */
open64_0030(void)281 static void open64_0030(void)
282 {
283     struct sigaction sigabrt = {
284         .sa_handler = SignalHandler,
285     };
286     sigaction(SIGABRT, &sigabrt, NULL);
287 
288     int flags = O_TMPFILE;
289     int status;
290     int pid = fork();
291     switch (pid) {
292         case -1:
293             t_error("fork failed: %s\n", strerror(errno));
294             break;
295         case 0:
296             open64("/proc/version", flags);
297             exit(0);
298         default:
299             waitpid(pid, &status, WUNTRACED);
300             TEST(WIFEXITED(status) == 0);
301             TEST(WIFSTOPPED(status) == 1);
302             TEST(WSTOPSIG(status) == SIGSTOP);
303             kill(pid, SIGCONT);
304             break;
305     }
306 
307     return;
308 }
309 
310 /**
311  * @tc.name     : open64_0040
312  * @tc.desc     : test open64 only O_RDWR
313  * @tc.level    : Level 1
314  */
open64_0040(void)315 static void open64_0040(void)
316 {
317     int fd = open64("/proc/version", O_RDWR);
318     EXPECT_NE(open64_0040, fd, -1);
319     close(fd);
320 
321     return;
322 }
323 
324 /**
325  * @tc.name     : openat64_0010
326  * @tc.desc     : test openat64 normal condition
327  * @tc.level    : Level 0
328  */
openat64_0010(void)329 static void openat64_0010(void)
330 {
331     int fd = openat64(AT_FDCWD, "/proc/version", O_RDWR | O_CREAT, FILE_MODE_ALL);
332     TEST(fd != -1);
333     close(fd);
334 
335     return;
336 }
337 
338 /**
339  * @tc.name     : openat64_0020
340  * @tc.desc     : test openat64 O_CREAT without mode
341  * @tc.level    : Level 2
342  */
openat64_0020(void)343 static void openat64_0020(void)
344 {
345     struct sigaction sigabrt = {
346         .sa_handler = SignalHandler,
347     };
348     sigaction(SIGABRT, &sigabrt, NULL);
349 
350     int flags = O_CREAT;
351     int status;
352     int pid = fork();
353     switch (pid) {
354         case -1:
355             t_error("fork failed: %s\n", strerror(errno));
356             break;
357         case 0:
358             openat64(AT_FDCWD, "/proc/version", flags);
359             exit(0);
360         default:
361             waitpid(pid, &status, WUNTRACED);
362             TEST(WIFEXITED(status) == 0);
363             TEST(WIFSTOPPED(status) == 1);
364             TEST(WSTOPSIG(status) == SIGSTOP);
365             kill(pid, SIGCONT);
366             break;
367     }
368 
369     return;
370 }
371 
372 /**
373  * @tc.name     : openat64_0030
374  * @tc.desc     : test openat64 O_TMPFILE without mode
375  * @tc.level    : Level 2
376  */
openat64_0030(void)377 static void openat64_0030(void)
378 {
379     struct sigaction sigabrt = {
380         .sa_handler = SignalHandler,
381     };
382     sigaction(SIGABRT, &sigabrt, NULL);
383 
384     int flags = O_TMPFILE;
385     int status;
386     int pid = fork();
387     switch (pid) {
388         case -1:
389             t_error("fork failed: %s\n", strerror(errno));
390             break;
391         case 0:
392             openat64(AT_FDCWD, "/proc/version", flags);
393             exit(0);
394         default:
395             waitpid(pid, &status, WUNTRACED);
396             TEST(WIFEXITED(status) == 0);
397             TEST(WIFSTOPPED(status) == 1);
398             TEST(WSTOPSIG(status) == SIGSTOP);
399             kill(pid, SIGCONT);
400             break;
401     }
402 
403     return;
404 }
405 
406 /**
407  * @tc.name     : openat64_0040
408  * @tc.desc     : test openat64 only O_RDWR
409  * @tc.level    : Level 1
410  */
openat64_0040(void)411 static void openat64_0040(void)
412 {
413     int fd = openat64(AT_FDCWD, "/proc/version", O_RDWR);
414     EXPECT_NE(openat64_0040, fd, -1);
415     close(fd);
416 
417     return;
418 }
419 #endif
420 
main(int argc, char *argv[])421 int main(int argc, char *argv[]) {
422     remove_all_special_handler(SIGABRT);
423     open_0010();
424     open_0020();
425     open_0030();
426     open_0040();
427     openat_0010();
428     openat_0020();
429     openat_0030();
430     openat_0040();
431 #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
432     open64_0010();
433     open64_0020();
434     open64_0030();
435     open64_0040();
436     openat64_0010();
437     openat64_0020();
438     openat64_0030();
439     openat64_0040();
440 #endif
441     return t_status;
442 }