• 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 <errno.h>
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/wait.h>
24 
25 #include "functionalext.h"
26 
27 #define PIPE_FD 2
28 #define LEN_OF_POINTER 8
29 #define BASE_NUM 11
30 #define TEST_COUNTS 32
31 
32 const char *LIB_NAME = "./libldso_randomization_dep.so";
33 const char *LIB_NAME_A = "./libldso_randomization_dep_a.so";
34 typedef void (*TEST_FUNC)(void);
35 
36 int g_test = BASE_NUM;
test_f(void)37 extern void test_f(void)
38 {
39     ++g_test;
40 }
41 
42 /**
43  * @tc.name      : dlopen_randomization_0100
44  * @tc.desc      : Call the dlopen interface to load a valid dynamic library
45  * @tc.level     : Level0
46  */
dlopen_randomization_0100(void)47 static void dlopen_randomization_0100(void)
48 {
49     void *handle = dlopen(LIB_NAME, RTLD_NOW);
50     EXPECT_PTRNE(__FUNCTION__, handle, 0);
51     if (handle) {
52         EXPECT_EQ(__FUNCTION__, dlclose(handle), 0);
53     }
54 }
55 
56 /**
57  * @tc.name      : dlopen_randomization_0200
58  * @tc.desc      : Call the dlopen interface to load NULL
59  * @tc.level     : Level1
60  */
dlopen_randomization_0200(void)61 static void dlopen_randomization_0200(void)
62 {
63     void *handle = dlopen(NULL, RTLD_NOW);
64     EXPECT_PTRNE(__FUNCTION__, handle, 0);
65     if (!handle) {
66         return;
67     };
68     int *i = dlsym(handle, "g_test");
69     EXPECT_PTRNE(__FUNCTION__, i, 0);
70     if (!i) {
71         dlclose(handle);
72         return;
73     }
74     EXPECT_EQ(__FUNCTION__, BASE_NUM, *i);
75     TEST_FUNC test = (TEST_FUNC)dlsym(handle, "test_f");
76     EXPECT_PTRNE(__FUNCTION__, test, 0);
77     if (!test) {
78         dlclose(handle);
79         return;
80     }
81     test();
82     EXPECT_EQ(__FUNCTION__, BASE_NUM + 1, g_test);
83     g_test = BASE_NUM;
84     dlclose(handle);
85 }
86 
87 /**
88  * @tc.name      : dlopen_randomization_0300
89  * @tc.desc      : Call the dlopen interface to load a invalid dynamic library
90  * @tc.level     : Level2
91  */
dlopen_randomization_0300(void)92 static void dlopen_randomization_0300(void)
93 {
94     void *handle = dlopen("test_invaild.so", RTLD_NOW);
95     EXPECT_PTREQ(__FUNCTION__, handle, 0);
96     if (handle) {
97         dlclose(handle);
98     }
99 }
100 
101 /**
102  * @tc.name      : dlopen_randomization_0400
103  * @tc.desc      : Repeatedly calling the dlopen interface to load the same dynamic library
104  * @tc.level     : Level1
105  */
dlopen_randomization_0400(void)106 static void dlopen_randomization_0400(void)
107 {
108     void *ori_handle = dlopen(LIB_NAME, RTLD_NOW);
109     void *handle = 0;
110     EXPECT_PTRNE(__FUNCTION__, ori_handle, 0);
111     if (!ori_handle) {
112         return;
113     }
114     int i = TEST_COUNTS;
115     while (i--) {
116         handle = dlopen(LIB_NAME, RTLD_NOW);
117         EXPECT_PTREQ(__FUNCTION__, ori_handle, handle);
118     }
119     i = TEST_COUNTS + 1;
120     while (i--) {
121         dlclose(ori_handle);
122     }
123 }
124 
125 /**
126  * @tc.name      : dlopen_randomization_0600
127  * @tc.desc      : Call the dlopen interface to load a invalid dynamic library,
128  *                 and call the dlsym interface to get symbol address
129  * @tc.level     : Level1
130  */
dlopen_randomization_0600(void)131 static void dlopen_randomization_0600(void)
132 {
133     void *handle;
134     int *i;
135     TEST_FUNC test;
136     handle = dlopen(LIB_NAME, RTLD_NOW);
137     EXPECT_PTRNE(__FUNCTION__, handle, 0);
138     if (!handle) {
139         return;
140     }
141     i = dlsym(handle, "i");
142     EXPECT_PTRNE(__FUNCTION__, i, 0);
143     if (!i) {
144         dlclose(handle);
145         return;
146     }
147     EXPECT_EQ(__FUNCTION__, *i, 0);
148     test = (TEST_FUNC)dlsym(handle, "test");
149     EXPECT_PTRNE(__FUNCTION__, test, 0);
150     if (!test) {
151         dlclose(handle);
152         return;
153     }
154     test();
155     EXPECT_EQ(__FUNCTION__, *i, 1);
156     dlclose(handle);
157 }
158 
159 /**
160  * @tc.name      : dlopen_ext_randomization_0100
161  * @tc.desc      : Call the dlopen_ext interface to load a valid dynamic library
162  * @tc.level     : Level0
163  */
dlopen_ext_randomization_0100(void)164 static void dlopen_ext_randomization_0100(void)
165 {
166     dl_extinfo extinfo = {0};
167     void *handle = dlopen_ext(LIB_NAME_A, RTLD_NOW, &extinfo);
168     EXPECT_PTRNE(__FUNCTION__, handle, 0);
169     if (handle) {
170         EXPECT_EQ(__FUNCTION__, dlclose(handle), 0);
171     }
172 }
173 
174 /**
175  * @tc.name      : dlopen_ext_randomization_0200
176  * @tc.desc      : Call the dlopen interface to load NULL
177  * @tc.level     : Level1
178  */
dlopen_ext_randomization_0200(void)179 static void dlopen_ext_randomization_0200(void)
180 {
181     dl_extinfo extinfo = {0};
182     void *handle = dlopen_ext(NULL, RTLD_NOW, &extinfo);
183     EXPECT_PTRNE(__FUNCTION__, handle, 0);
184     if (!handle) {
185         return;
186     }
187     int *i = dlsym(handle, "g_test");
188     EXPECT_PTRNE(__FUNCTION__, i, 0);
189     if (!i) {
190         dlclose(handle);
191         return;
192     }
193     EXPECT_EQ(__FUNCTION__, BASE_NUM, *i);
194     TEST_FUNC test = (TEST_FUNC)dlsym(handle, "test_f");
195     EXPECT_PTRNE(__FUNCTION__, test, 0);
196     if (!test) {
197         dlclose(handle);
198         return;
199     }
200     test();
201     EXPECT_EQ(__FUNCTION__, BASE_NUM + 1, g_test);
202     g_test = BASE_NUM;
203     dlclose(handle);
204 }
205 
206 /**
207  * @tc.name      : dlopen_ext_randomization_0300
208  * @tc.desc      : Call the dlopen interface to load a invalid dynamic library
209  * @tc.level     : Level2
210  */
dlopen_ext_randomization_0300(void)211 static void dlopen_ext_randomization_0300(void)
212 {
213     dl_extinfo extinfo = {0};
214     void *handle = dlopen_ext("test_invaild.so", RTLD_NOW, &extinfo);
215     EXPECT_PTREQ(__FUNCTION__, handle, 0);
216     if (handle) {
217         dlclose(handle);
218     }
219 }
220 
221 /**
222  * @tc.name      : dlopen_ext_randomization_0400
223  * @tc.desc      : Repeatedly calling the dlopen_ext interface to load the same dynamic library
224  * @tc.level     : Level1
225  */
dlopen_ext_randomization_0400(void)226 static void dlopen_ext_randomization_0400(void)
227 {
228     dl_extinfo extinfo = {0};
229     void *ori_handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
230     void *handle = 0;
231     EXPECT_PTRNE(__FUNCTION__, ori_handle, 0);
232     if (!ori_handle) {
233         return;
234     }
235     int i = TEST_COUNTS;
236     while (i--) {
237         handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
238         EXPECT_PTREQ(__FUNCTION__, ori_handle, handle);
239     }
240     i = TEST_COUNTS + 1;
241     while (i--) {
242         dlclose(ori_handle);
243     }
244 }
245 
246 /**
247  * @tc.name      : dlopen_ext_randomization_0600
248  * @tc.desc      : Call the dlopen_ext interface to load a invalid dynamic library,
249  *                 and call the dlsym interface to get symbol address
250  * @tc.level     : Level1
251  */
dlopen_ext_randomization_0600(void)252 static void dlopen_ext_randomization_0600(void)
253 {
254     void *handle;
255     int *i;
256     TEST_FUNC test;
257     dl_extinfo extinfo = {0};
258     handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
259     EXPECT_PTRNE(__FUNCTION__, handle, 0);
260     if (!handle) {
261         return;
262     }
263     i = dlsym(handle, "i");
264     EXPECT_PTRNE(__FUNCTION__, i, 0);
265     if (!i) {
266         dlclose(handle);
267         return;
268     }
269     EXPECT_EQ(__FUNCTION__, *i, 0);
270     test = (TEST_FUNC)dlsym(handle, "test");
271     EXPECT_PTRNE(__FUNCTION__, test, 0);
272     if (!test) {
273         dlclose(handle);
274         return;
275     }
276     test();
277     EXPECT_EQ(__FUNCTION__, *i, 1);
278     dlclose(handle);
279 }
280 
281 /**
282  * @tc.name      : dlopen_ext_randomization_0800
283  * @tc.desc      : The flag of dl_extinfo is set to DL_EXT_RESERVED_ADDRESS_RECURSIVE,
284  *                 call the dlopen_ext interface to load a valid dynamic library
285  * @tc.level     : Level1
286  */
dlopen_ext_randomization_0800(void)287 static void dlopen_ext_randomization_0800(void)
288 {
289     dl_extinfo extinfo = {
290         .flag = DL_EXT_RESERVED_ADDRESS_RECURSIVE,
291     };
292     void *handle = dlopen_ext(NULL, RTLD_NOW, &extinfo);
293     EXPECT_PTRNE(__FUNCTION__, handle, 0);
294     if (!handle) {
295         return;
296     }
297     int *i = dlsym(handle, "g_test");
298     EXPECT_PTRNE(__FUNCTION__, i, 0);
299     if (!i) {
300         dlclose(handle);
301         return;
302     }
303     EXPECT_EQ(__FUNCTION__, BASE_NUM, *i);
304     TEST_FUNC test = (TEST_FUNC)dlsym(handle, "test_f");
305     EXPECT_PTRNE(__FUNCTION__, test, 0);
306     if (!test) {
307         dlclose(handle);
308         return;
309     }
310     test();
311     EXPECT_EQ(__FUNCTION__, BASE_NUM + 1, *i);
312     g_test = BASE_NUM;
313     dlclose(handle);
314 }
315 
316 /**
317  * @tc.name      : dlopen_ext_randomization_0900
318  * @tc.desc      : Different processes call the dlopen_ext interface to load a dynamic library,
319  *                 the flag of dl_extinfo is set to DL_EXT_RESERVED_ADDRESS_RECURSIVE,
320  *                 and then call the dlsym interface to get symbol address
321  * @tc.level     : Level1
322  */
dlopen_ext_randomization_0900(void)323 static void dlopen_ext_randomization_0900(void)
324 {
325     void *parent_handle = 0;
326     void *child_handle = 0;
327     void *parent_sym = 0;
328     void *child_sym = 0;
329     void *get_child_sym = 0;
330     int fd[PIPE_FD];
331     if (pipe(fd) < 0) {
332         EXPECT_FALSE(__FUNCTION__, true);
333         return;
334     }
335     dl_extinfo extinfo = {
336         .flag = DL_EXT_RESERVED_ADDRESS_RECURSIVE,
337     };
338     pid_t pid = fork();
339     if (pid == 0) {
340         child_handle = dlopen_ext(LIB_NAME_A, RTLD_NOW, &extinfo);
341         EXPECT_PTRNE(__FUNCTION__, child_handle, 0);
342         if (!child_handle) {
343             exit(-1);
344         }
345         child_sym = dlsym(child_handle, "test");
346         write(fd[1], &child_sym, sizeof(void *));
347         dlclose(child_handle);
348         exit(0);
349     }
350     parent_handle = dlopen_ext(LIB_NAME_A, RTLD_NOW, &extinfo);
351     EXPECT_PTRNE(__FUNCTION__, parent_handle, 0);
352     if (!parent_handle) {
353         return;
354     };
355     parent_sym = dlsym(parent_handle, "test");
356     dlclose(parent_handle);
357     int status;
358     waitpid(pid, &status, 0);
359     read(fd[0], &get_child_sym, sizeof(void *));
360     EXPECT_PTREQ(__FUNCTION__, parent_sym, get_child_sym);
361     close(fd[0]);
362     close(fd[1]);
363 }
364 
365 /**
366  * @tc.name      : dlopen_ns_randomization_0100
367  * @tc.desc      : Call the dlopen_ns interface to load a valid dynamic library
368  * @tc.level     : Level0
369  */
dlopen_ns_randomization_0100(void)370 static void dlopen_ns_randomization_0100(void)
371 {
372     Dl_namespace dlns;
373     dlns_init(&dlns, __FUNCTION__);
374     dlns_create(&dlns, "./");
375     void *handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
376     EXPECT_PTRNE(__FUNCTION__, handle, 0);
377     if (handle) {
378         EXPECT_EQ(__FUNCTION__, dlclose(handle), 0);
379     }
380 }
381 
382 /**
383  * @tc.name      : dlopen_ns_randomization_0200
384  * @tc.desc      : Call the dlopen_ns interface to load NULL
385  * @tc.level     : Level1
386  */
dlopen_ns_randomization_0200(void)387 static void dlopen_ns_randomization_0200(void)
388 {
389     Dl_namespace dlns;
390     dlns_init(&dlns, __FUNCTION__);
391     dlns_create(&dlns, "./");
392     void *handle = dlopen_ns(&dlns, NULL, RTLD_NOW);
393     EXPECT_PTRNE(__FUNCTION__, handle, 0);
394     if (!handle) {
395         return;
396     }
397     int *i = dlsym(handle, "g_test");
398     EXPECT_PTRNE(__FUNCTION__, i, 0);
399     if (!i) {
400         dlclose(handle);
401         return;
402     }
403     EXPECT_EQ(__FUNCTION__, BASE_NUM, *i);
404     TEST_FUNC test = (TEST_FUNC)dlsym(handle, "test_f");
405     EXPECT_PTRNE(__FUNCTION__, test, 0);
406     if (!test) {
407         dlclose(handle);
408         return;
409     }
410     test();
411     EXPECT_EQ(__FUNCTION__, BASE_NUM + 1, g_test);
412     g_test = BASE_NUM;
413     dlclose(handle);
414 }
415 
416 /**
417  * @tc.name      : dlopen_ns_randomization_0300
418  * @tc.desc      : Call the dlopen_ns interface to load a invalid dynamic library
419  * @tc.level     : Level2
420  */
dlopen_ns_randomization_0300(void)421 static void dlopen_ns_randomization_0300(void)
422 {
423     Dl_namespace dlns;
424     dlns_init(&dlns, __FUNCTION__);
425     dlns_create(&dlns, "./");
426     void *handle = dlopen_ns(&dlns, "test_invaild.so", RTLD_NOW);
427     EXPECT_PTREQ(__FUNCTION__, handle, 0);
428     if (handle) {
429         dlclose(handle);
430     }
431 }
432 
433 /**
434  * @tc.name      : dlopen_ns_randomization_0400
435  * @tc.desc      : Repeatedly calling the dlopen_ns interface to load the same dynamic library
436  * @tc.level     : Level1
437  */
dlopen_ns_randomization_0400(void)438 static void dlopen_ns_randomization_0400(void)
439 {
440     Dl_namespace dlns;
441     dlns_init(&dlns, __FUNCTION__);
442     dlns_create(&dlns, "./");
443     void *ori_handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
444     void *handle = 0;
445     EXPECT_PTRNE(__FUNCTION__, ori_handle, 0);
446     if (!ori_handle) {
447         return;
448     }
449     int i = TEST_COUNTS;
450     while (i--) {
451         handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
452         EXPECT_PTREQ(__FUNCTION__, ori_handle, handle);
453     }
454     i = TEST_COUNTS + 1;
455     while (i--) {
456         dlclose(ori_handle);
457     }
458 }
459 
460 /**
461  * @tc.name      : dlopen_ns_randomization_0600
462  * @tc.desc      : Call the dlopen_ns interface to load a invalid dynamic library,
463  *                 and call the dlsym interface to get symbol address
464  * @tc.level     : Level1
465  */
dlopen_ns_randomization_0600(void)466 static void dlopen_ns_randomization_0600(void)
467 {
468     Dl_namespace dlns;
469     dlns_init(&dlns, __FUNCTION__);
470     dlns_create(&dlns, "./");
471     void *handle;
472     int *i;
473     TEST_FUNC test;
474     handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
475     EXPECT_PTRNE(__FUNCTION__, handle, 0);
476     if (!handle) {
477         return;
478     }
479     i = dlsym(handle, "i");
480     EXPECT_PTRNE(__FUNCTION__, i, 0);
481     if (!i) {
482         dlclose(handle);
483         return;
484     }
485     EXPECT_EQ(__FUNCTION__, *i, 0);
486     test = (TEST_FUNC)dlsym(handle, "test");
487     EXPECT_PTRNE(__FUNCTION__, test, 0);
488     if (!test) {
489         dlclose(handle);
490         return;
491     }
492     test();
493     EXPECT_EQ(__FUNCTION__, *i, 1);
494     dlclose(handle);
495 }
496 
497 /**
498  * @tc.name      : dlsym_randomization_0300
499  * @tc.desc      : Call the dlsym interface to get symbol address, handle is invalid
500  * @tc.level     : Level2
501  */
dlsym_randomization_0300(void)502 static void dlsym_randomization_0300(void)
503 {
504     void *sym = dlsym((void *)0xFFFF, "invalid_function");
505     EXPECT_PTREQ(__FUNCTION__, sym, NULL);
506 }
507 
508 /**
509  * @tc.name      : dlsym_randomization_0400
510  * @tc.desc      : Call the dlsym interface to get symbol address, handle is setted to RTLD_DEFAULT, and name is valid
511  * @tc.level     : Level1
512  */
dlsym_randomization_0400(void)513 static void dlsym_randomization_0400(void)
514 {
515     void *sym = dlsym(RTLD_DEFAULT, "fopen");
516     EXPECT_PTRNE(__FUNCTION__, sym, NULL);
517 }
518 
519 /**
520  * @tc.name      : dlsym_randomization_0500
521  * @tc.desc      : Call the dlsym interface to get symbol address, handle is setted to RTLD_DEFAULT, and name is invalid
522  * @tc.level     : Level2
523  */
dlsym_randomization_0500(void)524 static void dlsym_randomization_0500(void)
525 {
526     void *sym = dlsym(RTLD_DEFAULT, "invalid_func");
527     EXPECT_PTREQ(__FUNCTION__, sym, NULL);
528 }
529 
530 
531 /**
532  * @tc.name      : dlsym_randomization_0600
533  * @tc.desc      : Call the dlsym interface to get symbol address, handle is setted to RTLD_NEXT, and name is valid
534  * @tc.level     : Level1
535  */
dlsym_randomization_0600(void)536 static void dlsym_randomization_0600(void)
537 {
538     void *sym = dlsym(RTLD_NEXT, "fopen");
539     EXPECT_PTRNE(__FUNCTION__, sym, NULL);
540 }
541 
542 /**
543  * @tc.name      : dlsym_randomization_0700
544  * @tc.desc      : Call the dlsym interface to get symbol address, handle is setted to RTLD_NEXT, and name is invalid
545  * @tc.level     : Level2
546  */
dlsym_randomization_0700(void)547 static void dlsym_randomization_0700(void)
548 {
549     void *sym = dlsym(RTLD_NEXT, "invalid_func");
550     EXPECT_PTREQ(__FUNCTION__, sym, NULL);
551 }
552 
553 /**
554  * @tc.name      : dlclose_randomization_0100
555  * @tc.desc      : Call the dlclose interface to unload dynamic library
556  * @tc.level     : Level2
557  */
dlclose_randomization_0100(void)558 static void dlclose_randomization_0100(void)
559 {
560     int ret = dlclose(NULL);
561     EXPECT_EQ(__FUNCTION__, -1, ret);
562 }
563 
564 /**
565  * @tc.name      : dlopen_randomization_0800
566  * @tc.desc      : Call the dlopen interface to load libc.so
567  * @tc.level     : Level1
568  */
dlopen_randomization_0800(void)569 static void dlopen_randomization_0800(void)
570 {
571     if (sizeof(void *) == LEN_OF_POINTER) {
572         system("cp /system/lib64/libc.so .");
573     } else {
574         system("cp /system/lib/libc.so .");
575     }
576     void *handle = dlopen("./libc.so", RTLD_NOW);
577     EXPECT_PTRNE(__FUNCTION__, handle, 0);
578     system("rm ./libc.so");
579 }
580 
581 /**
582  * @tc.name      : dlopen_randomization_0900
583  * @tc.desc      : Call the dlopen interface to load ld.so
584  * @tc.level     : Level1
585  */
dlopen_randomization_0900(void)586 static void dlopen_randomization_0900(void)
587 {
588     void *handle = NULL;
589     if (sizeof(void *) == LEN_OF_POINTER) {
590         system("cp /system/lib/ld-musl-aarch64.so.1 .");
591         handle = dlopen("./ld-musl-aarch64.so.1", RTLD_NOW);
592         system("rm ld-musl-aarch64.so.1");
593     } else {
594         system("cp /system/lib/ld-musl-arm.so.1 .");
595         handle = dlopen("./ld-musl-arm.so.1", RTLD_NOW);
596         system("rm ./ld-musl-arm.so.1");
597     }
598     EXPECT_PTRNE(__FUNCTION__, handle, 0);
599 }
600 
601 TEST_FUNC test_cases[] = {
602     dlopen_randomization_0100,
603     dlopen_randomization_0200,
604     dlopen_randomization_0300,
605     dlopen_randomization_0400,
606     dlopen_randomization_0600,
607     dlopen_ext_randomization_0100,
608     dlopen_ext_randomization_0200,
609     dlopen_ext_randomization_0300,
610     dlopen_ext_randomization_0400,
611     dlopen_ext_randomization_0600,
612     dlopen_ext_randomization_0800,
613     dlopen_ext_randomization_0900,
614     dlopen_ns_randomization_0100,
615     dlopen_ns_randomization_0200,
616     dlopen_ns_randomization_0300,
617     dlopen_ns_randomization_0400,
618     dlopen_ns_randomization_0600,
619     dlsym_randomization_0300,
620     dlsym_randomization_0400,
621     dlsym_randomization_0500,
622     dlsym_randomization_0600,
623     dlsym_randomization_0700,
624     dlclose_randomization_0100,
625     dlopen_randomization_0800,
626     dlopen_randomization_0900,
627 };
628 
main(int argc,char * argv[])629 int main(int argc, char *argv[])
630 {
631     size_t case_counts = sizeof(test_cases) / sizeof(TEST_FUNC);
632     for (size_t case_num = 0; case_num < case_counts; case_num++) {
633         test_cases[case_num]();
634     }
635     return t_status;
636 }