• 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 
16 #include <dlfcn_ext.h>
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <sys/mman.h>
21 #include <sys/wait.h>
22 #include <stdbool.h>
23 
24 #include "functionalext.h"
25 #include "test.h"
26 
27 #define LIB_NAME "/data/tests/libc-test/src/libdlopen_ext_relro_dso.so"
28 #define RELRO_FILE_PATH "./TemporaryFile-XXXXXX"
29 #define RESERVED_ADDRESS_SIZE (64 * 1024 * 1024)
30 #define MIN_RESERVED_ADDRESS_SIZE 4096
31 
32 const char *RELRO_NS_PATH = "./";
33 const int RELRO_INVALID_FLAG = 0x20;
34 const int LIB_PATH_SIZE = 512;
35 typedef void (*TEST_FUN)(void);
36 
create_temp_relro_file(char * path)37 static int create_temp_relro_file(char *path)
38 {
39     int fd = -1;
40 #if defined(_WIN32)
41     fd = mkstemp(path, strlen(RELRO_FILE_PATH) + 1);
42 #else
43     fd = mkstemp(path);
44 #endif
45     if (fd != -1) {
46         close(fd);
47     }
48     return 0;
49 }
50 
tear_down(const int fd,const char * relro_path)51 static void tear_down(const int fd, const char *relro_path)
52 {
53     if (fd != -1) {
54         close(fd);
55     }
56 
57     if (relro_path != NULL) {
58         unlink(relro_path);
59     }
60 }
61 
clear_handle(void * handle)62 static void clear_handle(void *handle)
63 {
64     if (handle) {
65         dlclose(handle);
66     }
67 }
68 
test_write_relro_file(const char * lib,const int relro_fd)69 static void test_write_relro_file(const char *lib, const int relro_fd)
70 {
71     pid_t pid = fork();
72     if (pid == 0) {
73         dl_extinfo extinfo = {
74             .flag = DL_EXT_WRITE_RELRO,
75             .relro_fd = relro_fd,
76         };
77         void *handle = dlopen_ext(lib, RTLD_NOW, &extinfo);
78         EXPECT_PTRNE(__FUNCTION__, handle, NULL);
79         clear_handle(handle);
80         exit(-1);
81     }
82     int status = 0;
83     waitpid(pid, &status, 0);
84 }
85 
test_write_relro_file_ext(const char * lib,const int relro_fd,const int flag,void * addr,const size_t map_size)86 static void test_write_relro_file_ext(
87     const char *lib, const int relro_fd, const int flag, void *addr, const size_t map_size)
88 {
89     pid_t pid = fork();
90     if (pid == 0) {
91         dl_extinfo extinfo = {
92             .flag = flag,
93             .relro_fd = relro_fd,
94             .reserved_addr = addr,
95             .reserved_size = map_size,
96         };
97         void *handle = dlopen_ext(lib, RTLD_NOW, &extinfo);
98         EXPECT_PTRNE(__FUNCTION__, handle, NULL);
99         clear_handle(handle);
100         exit(-1);
101     }
102     int status = 0;
103     waitpid(pid, &status, 0);
104 }
105 
106 /**
107  * @tc.name      : dlopen_ext_relro_0100
108  * @tc.desc      : extinfo is NULL, call dlopen_ext, return handle is not NULL.
109  * @tc.level     : Level 1
110  */
dlopen_ext_relro_0100(void)111 static void dlopen_ext_relro_0100(void)
112 {
113     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, NULL);
114     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
115     clear_handle(handle);
116 }
117 
118 /**
119  * @tc.name      : dlopen_ext_relro_0200
120  * @tc.desc      : extinfo flag is 0, call dlopen_ext, return handle is not NULL.
121  * @tc.level     : Level 1
122  */
dlopen_ext_relro_0200(void)123 static void dlopen_ext_relro_0200(void)
124 {
125     dl_extinfo extinfo = {
126         .flag = 0,
127         .relro_fd = -1,
128     };
129     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
130     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
131     clear_handle(handle);
132 }
133 
134 /**
135  * @tc.name      : dlopen_ext_relro_0300
136  * @tc.desc      : extinfo flag is 20, call dlopen_ext, return handle is NULL.
137  * @tc.level     : Level 2
138  */
dlopen_ext_relro_0300(void)139 static void dlopen_ext_relro_0300(void)
140 {
141     dl_extinfo extinfo = {
142         .flag = RELRO_INVALID_FLAG,
143         .relro_fd = -1,
144     };
145     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
146     EXPECT_EQ(__FUNCTION__, handle, NULL);
147     clear_handle(handle);
148 }
149 
150 /**
151  * @tc.name      : dlopen_ext_relro_0400
152  * @tc.desc      : extinfo flag is DL_EXT_WRITE_RELRO, relro_fd is valid, call dlopen_ext, return handle is not NULL.
153  * @tc.level     : Level 1
154  */
dlopen_ext_relro_0400(void)155 static void dlopen_ext_relro_0400(void)
156 {
157     char relro_file[] = RELRO_FILE_PATH;
158     if (create_temp_relro_file(relro_file) < 0) {
159         return;
160     }
161     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
162     if (relro_fd < 0) {
163         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
164         return;
165     }
166     dl_extinfo extinfo = {
167         .flag = DL_EXT_WRITE_RELRO,
168         .relro_fd = relro_fd,
169     };
170     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
171     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
172     tear_down(relro_fd, relro_file);
173     clear_handle(handle);
174 }
175 
176 /**
177  * @tc.name      : dlopen_ext_relro_0500
178  * @tc.desc      : extinfo flag is DL_EXT_WRITE_RELRO, relro_fd is not valid, call dlopen_ext, return handle is NULL.
179  * @tc.level     : Level 2
180  */
dlopen_ext_relro_0500(void)181 static void dlopen_ext_relro_0500(void)
182 {
183     dl_extinfo extinfo = {
184         .flag = DL_EXT_WRITE_RELRO,
185         .relro_fd = -1,
186     };
187     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
188     EXPECT_EQ(__FUNCTION__, handle, NULL);
189     clear_handle(handle);
190 }
191 
192 /**
193  * @tc.name      : dlopen_ext_relro_0600
194  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO, relro_fd is valid, call dlopen_ext, return handle is not NULL.
195  * @tc.level     : Level 1
196  */
dlopen_ext_relro_0600(void)197 static void dlopen_ext_relro_0600(void)
198 {
199     char relro_file[] = RELRO_FILE_PATH;
200     if (create_temp_relro_file(relro_file) < 0) {
201         return;
202     }
203     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
204     if (relro_fd < 0) {
205         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
206         return;
207     }
208     test_write_relro_file(LIB_NAME, relro_fd);
209     dl_extinfo extinfo = {
210         .flag = DL_EXT_USE_RELRO,
211         .relro_fd = relro_fd,
212     };
213     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
214     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
215     tear_down(relro_fd, relro_file);
216     clear_handle(handle);
217 }
218 
219 /**
220  * @tc.name      : dlopen_ext_relro_0700
221  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO, relro_fd is not valid, call dlopen_ext, return handle is NULL.
222  * @tc.level     : Level 2
223  */
dlopen_ext_relro_0700(void)224 static void dlopen_ext_relro_0700(void)
225 {
226     char relro_file[] = RELRO_FILE_PATH;
227     if (create_temp_relro_file(relro_file) < 0) {
228         return;
229     }
230     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
231     if (relro_fd < 0) {
232         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
233         return;
234     }
235     test_write_relro_file(LIB_NAME, relro_fd);
236     dl_extinfo extinfo = {
237         .flag = DL_EXT_USE_RELRO,
238         .relro_fd = -1,
239     };
240     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
241     EXPECT_EQ(__FUNCTION__, handle, NULL);
242     tear_down(relro_fd, relro_file);
243     clear_handle(handle);
244 }
245 
246 /**
247  * @tc.name      : dlopen_ext_relro_0800
248  * @tc.desc      : extinfo flag is DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE, relro_fd is valid,
249  *                 call dlopen_ext, return handle is not NULL.
250  * @tc.level     : Level 1
251  */
dlopen_ext_relro_0800(void)252 static void dlopen_ext_relro_0800(void)
253 {
254     char relro_file[] = RELRO_FILE_PATH;
255     if (create_temp_relro_file(relro_file) < 0) {
256         return;
257     }
258     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
259     if (relro_fd < 0) {
260         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
261         return;
262     }
263     dl_extinfo extinfo = {
264         .flag = DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
265         .relro_fd = relro_fd,
266     };
267     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
268     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
269     tear_down(relro_fd, relro_file);
270     clear_handle(handle);
271 }
272 
273 /**
274  * @tc.name      : dlopen_ext_relro_0900
275  * @tc.desc      : extinfo flag is DL_EXT_WRITE_RELRO, relro_fd is not valid, call dlopen_ext, return handle is NULL.
276  * @tc.level     : Level 2
277  */
dlopen_ext_relro_0900(void)278 static void dlopen_ext_relro_0900(void)
279 {
280     dl_extinfo extinfo = {
281         .flag = DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
282         .relro_fd = -1,
283     };
284     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
285     EXPECT_EQ(__FUNCTION__, handle, NULL);
286     clear_handle(handle);
287 }
288 
289 /**
290  * @tc.name      : dlopen_ext_relro_1000
291  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE, relro_fd is valid,
292  *                 call dlopen_ext, return handle is not NULL.
293  * @tc.level     : Level 1
294  */
dlopen_ext_relro_1000(void)295 static void dlopen_ext_relro_1000(void)
296 {
297     char relro_file[] = RELRO_FILE_PATH;
298     if (create_temp_relro_file(relro_file) < 0) {
299         return;
300     }
301     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
302     if (relro_fd < 0) {
303         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
304         return;
305     }
306     test_write_relro_file(LIB_NAME, relro_fd);
307     dl_extinfo extinfo = {
308         .flag = DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
309         .relro_fd = relro_fd,
310     };
311     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
312     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
313     tear_down(relro_fd, relro_file);
314     clear_handle(handle);
315 }
316 
317 /**
318  * @tc.name      : dlopen_ext_relro_1100
319  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE, relro_fd is not valid,
320  *                 call dlopen_ext, return handle is NULL.
321  * @tc.level     : Level 2
322  */
dlopen_ext_relro_1100(void)323 static void dlopen_ext_relro_1100(void)
324 {
325     char relro_file[] = RELRO_FILE_PATH;
326     if (create_temp_relro_file(relro_file) < 0) {
327         return;
328     }
329     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
330     if (relro_fd < 0) {
331         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
332         return;
333     }
334     test_write_relro_file(LIB_NAME, relro_fd);
335     dl_extinfo extinfo = {
336         .flag = DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
337         .relro_fd = -1,
338     };
339     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
340     EXPECT_EQ(__FUNCTION__, handle, NULL);
341     tear_down(relro_fd, relro_file);
342     clear_handle(handle);
343 }
344 
345 /**
346  * @tc.name      : dlopen_ext_relro_1200
347  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO when relro file do not write,
348  *                 when call dlopen_ext, return handle is NULL.
349  * @tc.level     : Level 2
350  */
dlopen_ext_relro_1200(void)351 static void dlopen_ext_relro_1200(void)
352 {
353     char relro_file[] = RELRO_FILE_PATH;
354     if (create_temp_relro_file(relro_file) < 0) {
355         return;
356     }
357     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
358     if (relro_fd < 0) {
359         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
360         return;
361     }
362     dl_extinfo extinfo = {
363         .flag = DL_EXT_USE_RELRO,
364         .relro_fd = relro_fd,
365     };
366     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
367     EXPECT_EQ(__FUNCTION__, handle, NULL);
368     tear_down(relro_fd, relro_file);
369     clear_handle(handle);
370 }
371 
372 /**
373  * @tc.name      : dlopen_ext_relro_1500
374  * @tc.desc      : extinfo flag is DL_EXT_USE_RELRO | DL_EXT_WRITE_RELRO, relro_fd is valid,
375  *                 call dlopen_ext, return handle is not NULL.
376  * @tc.level     : Level 1
377  */
dlopen_ext_relro_1500(void)378 static void dlopen_ext_relro_1500(void)
379 {
380     char relro_file[] = RELRO_FILE_PATH;
381     if (create_temp_relro_file(relro_file) < 0) {
382         return;
383     }
384     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
385     if (relro_fd < 0) {
386         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
387         return;
388     }
389     test_write_relro_file(LIB_NAME, relro_fd);
390     dl_extinfo extinfo = {
391         .flag = DL_EXT_WRITE_RELRO | DL_EXT_USE_RELRO,
392         .relro_fd = relro_fd,
393     };
394     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
395     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
396     tear_down(relro_fd, relro_file);
397     clear_handle(handle);
398 }
399 
400 /**
401  * @tc.name      : dlopen_ext_relro_1600
402  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS, relro_fd is valid, reserved address size is enough,
403  *                 call dlopen_ext, return handle is not NULL.
404  * @tc.level     : Level 1
405  */
dlopen_ext_relro_1600(void)406 static void dlopen_ext_relro_1600(void)
407 {
408     char relro_file[] = RELRO_FILE_PATH;
409     if (create_temp_relro_file(relro_file) < 0) {
410         return;
411     }
412     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
413     if (relro_fd < 0) {
414         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
415         return;
416     }
417     size_t map_size = RESERVED_ADDRESS_SIZE;
418     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
419     if (map == MAP_FAILED) {
420         t_error("%s map reserved address failed.\n", __FUNCTION__);
421         tear_down(relro_fd, relro_file);
422         return;
423     }
424     dl_extinfo extinfo = {
425         .flag = DL_EXT_RESERVED_ADDRESS,
426         .relro_fd = relro_fd,
427         .reserved_addr = map,
428         .reserved_size = map_size,
429     };
430     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
431     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
432     tear_down(relro_fd, relro_file);
433     clear_handle(handle);
434     munmap(map, map_size);
435 }
436 
437 /**
438  * @tc.name      : dlopen_ext_relro_1700
439  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS_HINT, relro_fd is valid, reserved address size is enough,
440  *                 call dlopen_ext, return handle is not NULL.
441  * @tc.level     : Level 1
442  */
dlopen_ext_relro_1700(void)443 static void dlopen_ext_relro_1700(void)
444 {
445     char relro_file[] = RELRO_FILE_PATH;
446     if (create_temp_relro_file(relro_file) < 0) {
447         return;
448     }
449     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
450     if (relro_fd < 0) {
451         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
452         return;
453     }
454     size_t map_size = RESERVED_ADDRESS_SIZE;
455     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
456     if (map == MAP_FAILED) {
457         t_error("%s map reserved address failed.\n", __FUNCTION__);
458         tear_down(relro_fd, relro_file);
459         return;
460     }
461     dl_extinfo extinfo = {
462         .flag = DL_EXT_RESERVED_ADDRESS_HINT,
463         .relro_fd = relro_fd,
464         .reserved_addr = map,
465         .reserved_size = map_size,
466     };
467     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
468     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
469     tear_down(relro_fd, relro_file);
470     clear_handle(handle);
471     munmap(map, map_size);
472 }
473 
474 /**
475  * @tc.name      : dlopen_ext_relro_1800
476  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS | DL_EXT_RESERVED_ADDRESS_RECURSIVE, relro_fd is valid,
477  *                 reserved address size is enough, call dlopen_ext, return handle is not NULL.
478  * @tc.level     : Level 1
479  */
dlopen_ext_relro_1800(void)480 static void dlopen_ext_relro_1800(void)
481 {
482     char relro_file[] = RELRO_FILE_PATH;
483     if (create_temp_relro_file(relro_file) < 0) {
484         return;
485     }
486     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
487     if (relro_fd < 0) {
488         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
489         return;
490     }
491     size_t map_size = RESERVED_ADDRESS_SIZE;
492     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
493     if (map == MAP_FAILED) {
494         t_error("%s map reserved address failed.\n", __FUNCTION__);
495         tear_down(relro_fd, relro_file);
496         return;
497     }
498     dl_extinfo extinfo = {.flag = DL_EXT_RESERVED_ADDRESS | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
499         .relro_fd = relro_fd,
500         .reserved_addr = map,
501         .reserved_size = map_size
502 
503     };
504     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
505     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
506     tear_down(relro_fd, relro_file);
507     clear_handle(handle);
508     munmap(map, map_size);
509 }
510 
511 /**
512  * @tc.name      : dlopen_ext_relro_1900
513  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS_HINT | DL_EXT_RESERVED_ADDRESS_RECURSIVE, relro_fd is valid,
514  *                 reserved address size is enough, call dlopen_ext, return handle is not NULL.
515  * @tc.level     : Level 1
516  */
dlopen_ext_relro_1900(void)517 static void dlopen_ext_relro_1900(void)
518 {
519     char relro_file[] = RELRO_FILE_PATH;
520     if (create_temp_relro_file(relro_file) < 0) {
521         return;
522     }
523     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
524     if (relro_fd < 0) {
525         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
526         return;
527     }
528     size_t map_size = RESERVED_ADDRESS_SIZE;
529     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
530     if (map == MAP_FAILED) {
531         t_error("%s map reserved address failed.\n", __FUNCTION__);
532         tear_down(relro_fd, relro_file);
533         return;
534     }
535     dl_extinfo extinfo = {.flag = DL_EXT_RESERVED_ADDRESS_HINT | DL_EXT_RESERVED_ADDRESS_RECURSIVE,
536         .relro_fd = relro_fd,
537         .reserved_addr = map,
538         .reserved_size = map_size};
539     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
540     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
541     tear_down(relro_fd, relro_file);
542     clear_handle(handle);
543     munmap(map, map_size);
544 }
545 
546 /**
547  * @tc.name      : dlopen_ext_relro_2000
548  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS, relro_fd is valid, reserved address size is not enough
549  *                 call dlopen_ext, return handle is NULL.
550  * @tc.level     : Level 2
551  */
dlopen_ext_relro_2000(void)552 static void dlopen_ext_relro_2000(void)
553 {
554     char relro_file[] = RELRO_FILE_PATH;
555     if (create_temp_relro_file(relro_file) < 0) {
556         return;
557     }
558     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
559     if (relro_fd < 0) {
560         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
561         return;
562     }
563     size_t map_size = MIN_RESERVED_ADDRESS_SIZE;
564     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
565     if (map == MAP_FAILED) {
566         t_error("%s map reserved address failed.\n", __FUNCTION__);
567         tear_down(relro_fd, relro_file);
568         return;
569     }
570     dl_extinfo extinfo = {
571         .flag = DL_EXT_RESERVED_ADDRESS,
572         .relro_fd = relro_fd,
573         .reserved_addr = map,
574         .reserved_size = map_size,
575     };
576     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
577     EXPECT_PTREQ(__FUNCTION__, handle, NULL);
578     tear_down(relro_fd, relro_file);
579     clear_handle(handle);
580     munmap(map, map_size);
581 }
582 
583 /**
584  * @tc.name      : dlopen_ext_relro_2100
585  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS_HINT, relro_fd is valid, reserved address size is not enough
586  *                 call dlopen_ext, return handle is not NULL.
587  * @tc.level     : Level 1
588  */
dlopen_ext_relro_2100(void)589 static void dlopen_ext_relro_2100(void)
590 {
591     char relro_file[] = RELRO_FILE_PATH;
592     if (create_temp_relro_file(relro_file) < 0) {
593         return;
594     }
595     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
596     if (relro_fd < 0) {
597         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
598         return;
599     }
600     size_t map_size = MIN_RESERVED_ADDRESS_SIZE;
601     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
602     if (map == MAP_FAILED) {
603         t_error("%s map reserved address failed.\n", __FUNCTION__);
604         tear_down(relro_fd, relro_file);
605         return;
606     }
607     dl_extinfo extinfo = {
608         .flag = DL_EXT_RESERVED_ADDRESS_HINT,
609         .relro_fd = relro_fd,
610         .reserved_addr = map,
611         .reserved_size = map_size,
612     };
613     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
614     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
615     tear_down(relro_fd, relro_file);
616     clear_handle(handle);
617     munmap(map, map_size);
618 }
619 
620 /**
621  * @tc.name      : dlopen_ext_relro_2300
622  * @tc.desc      : child process extinfo flag is DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS,
623  *                 parent process extinfo flag is DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS,
624  *                 relro_fd is valid, reserved address size is enough, call dlopen_ext, return handle is not NULL.
625  * @tc.level     : Level 1
626  */
dlopen_ext_relro_2200(void)627 static void dlopen_ext_relro_2200(void)
628 {
629     char relro_file[] = RELRO_FILE_PATH;
630     if (create_temp_relro_file(relro_file) < 0) {
631         return;
632     }
633     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
634     if (relro_fd < 0) {
635         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
636         return;
637     }
638     size_t map_size = RESERVED_ADDRESS_SIZE;
639     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
640     if (map == MAP_FAILED) {
641         t_error("%s map reserved address failed.\n", __FUNCTION__);
642         tear_down(relro_fd, relro_file);
643         return;
644     }
645     test_write_relro_file_ext(LIB_NAME, relro_fd, DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS, map, map_size);
646     dl_extinfo extinfo = {
647         .flag = DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS,
648         .relro_fd = relro_fd,
649         .reserved_addr = map,
650         .reserved_size = map_size,
651     };
652     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
653     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
654     tear_down(relro_fd, relro_file);
655     clear_handle(handle);
656     munmap(map, map_size);
657 }
658 
659 /**
660  * @tc.name      : dlopen_ext_relro_2300
661  * @tc.desc      : child process extinfo flag is DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS_HINT,
662  *                 parent process extinfo flag is DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_HINT,
663  *                 relro_fd is valid, reserved address size is enough, call dlopen_ext, return handle is not NULL.
664  * @tc.level     : Level 1
665  */
dlopen_ext_relro_2300(void)666 static void dlopen_ext_relro_2300(void)
667 {
668     char relro_file[] = RELRO_FILE_PATH;
669     if (create_temp_relro_file(relro_file) < 0) {
670         return;
671     }
672     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
673     if (relro_fd < 0) {
674         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
675         return;
676     }
677     size_t map_size = RESERVED_ADDRESS_SIZE;
678     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
679     if (map == MAP_FAILED) {
680         t_error("%s map reserved address failed.\n", __FUNCTION__);
681         tear_down(relro_fd, relro_file);
682         return;
683     }
684     test_write_relro_file_ext(LIB_NAME, relro_fd, DL_EXT_WRITE_RELRO | DL_EXT_RESERVED_ADDRESS_HINT, map, map_size);
685     dl_extinfo extinfo = {
686         .flag = DL_EXT_USE_RELRO | DL_EXT_RESERVED_ADDRESS_HINT,
687         .relro_fd = relro_fd,
688         .reserved_addr = map,
689         .reserved_size = map_size,
690     };
691     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
692     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
693     tear_down(relro_fd, relro_file);
694     clear_handle(handle);
695     munmap(map, map_size);
696 }
697 
698 /**
699  * @tc.name      : dlopen_ext_relro_2400
700  * @tc.desc      : extinfo flag is DL_EXT_RESERVED_ADDRESS, relro_fd is valid, reserved addresses are not page aligned,
701  *                 reserved address size is enough, call dlopen_ext, return handle is not NULL.
702  * @tc.level     : Level 1
703  */
dlopen_ext_relro_2400(void)704 static void dlopen_ext_relro_2400(void)
705 {
706     char relro_file[] = RELRO_FILE_PATH;
707     if (create_temp_relro_file(relro_file) < 0) {
708         return;
709     }
710     int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
711     if (relro_fd < 0) {
712         t_error("%s relro file %s open failed error is : %s \n", __FUNCTION__, relro_file, dlerror());
713         return;
714     }
715     size_t map_size = RESERVED_ADDRESS_SIZE;
716     void *map = mmap(NULL, map_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
717     if (map == MAP_FAILED) {
718         t_error("%s map reserved address failed.\n", __FUNCTION__);
719         tear_down(relro_fd, relro_file);
720         return;
721     }
722     void *start_addr = (uint8_t *)map + 0x1;
723     dl_extinfo extinfo = {
724         .flag = DL_EXT_RESERVED_ADDRESS,
725         .relro_fd = relro_fd,
726         .reserved_addr = start_addr,
727         .reserved_size = map_size,
728     };
729     void *handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
730     EXPECT_PTRNE(__FUNCTION__, handle, NULL);
731     tear_down(relro_fd, relro_file);
732     clear_handle(handle);
733     munmap(map, map_size);
734 }
735 
736 TEST_FUN g_fun_array[] = {
737     dlopen_ext_relro_0100,
738     dlopen_ext_relro_0200,
739     dlopen_ext_relro_0300,
740     dlopen_ext_relro_0400,
741     dlopen_ext_relro_0500,
742     dlopen_ext_relro_0600,
743     dlopen_ext_relro_0700,
744     dlopen_ext_relro_0800,
745     dlopen_ext_relro_0900,
746     dlopen_ext_relro_1000,
747     dlopen_ext_relro_1100,
748     dlopen_ext_relro_1200,
749     dlopen_ext_relro_1500,
750     dlopen_ext_relro_1600,
751     dlopen_ext_relro_1700,
752     dlopen_ext_relro_1800,
753     dlopen_ext_relro_1900,
754     dlopen_ext_relro_2000,
755     dlopen_ext_relro_2100,
756     dlopen_ext_relro_2200,
757     dlopen_ext_relro_2300,
758     dlopen_ext_relro_2400,
759 };
760 
main(int argc,char * argv[])761 int main(int argc, char *argv[])
762 {
763     int num = sizeof(g_fun_array) / sizeof(TEST_FUN);
764     for (int pos = 0; pos < num; ++pos) {
765         g_fun_array[pos]();
766     }
767     return t_status;
768 }