• 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 <stdint.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <sys/wait.h>
21 
22 #include "test.h"
23 
24 #define PIPE_FD 2
25 #define TEST_COUNTS 32
26 
27 const char *LIB_NAME = "./libldso_randomization_dep.so";
28 const char *LIB_NAME_A = "./libldso_randomization_dep_a.so";
29 typedef void (*TEST_FUNC)(void);
30 
compare(const void * a,const void * b)31 static uintptr_t compare(const void *a, const void *b)
32 {
33     return (*(uintptr_t *)a - *(uintptr_t *)b);
34 }
35 
check_address(void ** array,size_t length)36 static bool check_address(void **array, size_t length)
37 {
38     qsort(array, length, sizeof(void *), (void *)compare);
39     for (size_t i = 0, j = 1; j < length; i++, j++) {
40         if (array[i] == array[j]) {
41             return false;
42         }
43     }
44     return true;
45 }
46 
47 /**
48  * @tc.name      : dlopen_randomization_0500
49  * @tc.desc      : Repeatedly calling the dlopen interface to load the dynamic library,
50  *                 and calling dlclose to unload each time
51  * @tc.level     : Level3
52  */
dlopen_randomization_0500(void)53 static void dlopen_randomization_0500(void)
54 {
55     void *handles[TEST_COUNTS] = {0};
56     void *handle = 0;
57     int i = TEST_COUNTS;
58     do {
59         handle = dlopen(LIB_NAME, RTLD_NOW);
60         handles[--i] = handle;
61         if (handle) {
62             dlclose(handle);
63         }
64     } while (i);
65     if (check_address(handles, TEST_COUNTS)) {
66         t_printf("%s handles are randomized\n", __FUNCTION__);
67     } else {
68         t_printf("%s exists the same handle!!!!\n", __FUNCTION__);
69     }
70 }
71 
72 /**
73  * @tc.name      : dlopen_randomization_0700
74  * @tc.desc      : Different processes call the dlopen interface to load dynamic libraries
75  * @tc.level     : Level3
76  */
dlopen_randomization_0700(void)77 static void dlopen_randomization_0700(void)
78 {
79     void *parent_handle = 0;
80     void *get_child_handle = 0;
81     int fd[PIPE_FD];
82     if (pipe(fd) < 0) {
83         t_printf("%s create pipe error!\n", __FUNCTION__);
84         return;
85     }
86     pid_t pid = fork();
87     if (pid == 0) {
88         void *child_handle = dlopen(LIB_NAME, RTLD_NOW);
89         t_printf("%s child handle is %p \n", __FUNCTION__, child_handle);
90         if (child_handle) {
91             dlclose(child_handle);
92         }
93         write(fd[1], &child_handle, sizeof(void *));
94         exit(0);
95     }
96     parent_handle = dlopen(LIB_NAME, RTLD_NOW);
97     t_printf("%s parent handle is %p \n", __FUNCTION__, parent_handle);
98     if (parent_handle) {
99         dlclose(parent_handle);
100     }
101     int status;
102     waitpid(pid, &status, 0);
103     read(fd[0], &get_child_handle, sizeof(void *));
104     t_printf("%s get child handle is %p\n", __FUNCTION__, get_child_handle);
105     if (parent_handle == get_child_handle) {
106         t_printf("%s the parent handle is the same as the child handle!!!!\n", __FUNCTION__);
107     } else {
108         t_printf("%s the parent handle is different form the child handle.\n", __FUNCTION__);
109     }
110     close(fd[0]);
111     close(fd[1]);
112 }
113 
114 /**
115  * @tc.name      : dlopen_ext_randomization_0500
116  * @tc.desc      : Repeatedly calling the dlopen_ext interface to load the dynamic library,
117  *                 and calling dlclose to unload each time
118  * @tc.level     : Level3
119  */
dlopen_ext_randomization_0500(void)120 static void dlopen_ext_randomization_0500(void)
121 {
122     dl_extinfo extinfo = {0};
123     void *handles[TEST_COUNTS] = {0};
124     void *handle = 0;
125     int i = TEST_COUNTS;
126     do {
127         handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
128         handles[--i] = handle;
129         if (handle) {
130             dlclose(handle);
131         }
132     } while (i);
133     if (check_address(handles, TEST_COUNTS)) {
134         t_printf("%s handles are randomized\n", __FUNCTION__);
135     } else {
136         t_printf("%s exists the same handle!!!!\n", __FUNCTION__);
137     }
138 }
139 
140 /**
141  * @tc.name      : dlopen_ext_randomization_0700
142  * @tc.desc      : Different processes call the dlopen_ext interface to load dynamic libraries
143  * @tc.level     : Level3
144  */
dlopen_ext_randomization_0700(void)145 static void dlopen_ext_randomization_0700(void)
146 {
147     void *parent_handle = 0;
148     void *get_child_handle = 0;
149     dl_extinfo extinfo = {0};
150     int fd[PIPE_FD];
151     if (pipe(fd) < 0) {
152         t_printf("%s create pipe error!\n", __FUNCTION__);
153         return;
154     }
155     pid_t pid = fork();
156     if (pid == 0) {
157         void *child_handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
158         t_printf("%s child handle is %p \n", __FUNCTION__, child_handle);
159         if (child_handle) {
160             dlclose(child_handle);
161         }
162         write(fd[1], &child_handle, sizeof(void *));
163         exit(0);
164     }
165     parent_handle = dlopen_ext(LIB_NAME, RTLD_NOW, &extinfo);
166     t_printf("%s parent handle is %p \n", __FUNCTION__, parent_handle);
167     if (parent_handle) {
168         dlclose(parent_handle);
169     }
170     int status;
171     waitpid(pid, &status, 0);
172     read(fd[0], &get_child_handle, sizeof(void *));
173     t_printf("%s get child handle is %p\n", __FUNCTION__, get_child_handle);
174     if (parent_handle == get_child_handle) {
175         t_printf("%s the parent handle is the same as the child handle!!!!\n", __FUNCTION__);
176     } else {
177         t_printf("%s the parent handle is different form the child handle.\n", __FUNCTION__);
178     }
179     close(fd[0]);
180     close(fd[1]);
181 }
182 
183 /**
184  * @tc.name      : dlopen_ns_randomization_0500
185  * @tc.desc      : Repeatedly calling the dlopen_ns interface to load the dynamic library,
186  *                 and calling dlclose to unload each time
187  * @tc.level     : Level3
188  */
dlopen_ns_randomization_0500(void)189 static void dlopen_ns_randomization_0500(void)
190 {
191     Dl_namespace dlns;
192     dlns_init(&dlns, __FUNCTION__);
193     dlns_create(&dlns, "./");
194 
195     void *handles[TEST_COUNTS] = {0};
196     void *handle = 0;
197     int i = TEST_COUNTS;
198     do {
199         handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
200         handles[--i] = handle;
201         if (handle) {
202             dlclose(handle);
203         }
204     } while (i);
205     if (check_address(handles, TEST_COUNTS)) {
206         t_printf("%s handles are randomized\n", __FUNCTION__);
207     } else {
208         t_printf("%s exists the same handle!!!!\n", __FUNCTION__);
209     }
210 }
211 
212 /**
213  * @tc.name      : dlopen_ns_randomization_0700
214  * @tc.desc      : Different processes call the dlopen_ns interface to load dynamic libraries
215  * @tc.level     : Level3
216  */
dlopen_ns_randomization_0700(void)217 static void dlopen_ns_randomization_0700(void)
218 {
219     Dl_namespace dlns;
220     dlns_init(&dlns, __FUNCTION__);
221     dlns_create(&dlns, "./");
222 
223     void *parent_handle = 0;
224     void *get_child_handle = 0;
225     int fd[PIPE_FD];
226     if (pipe(fd) < 0) {
227         t_printf("%s create pipe error!\n", __FUNCTION__);
228         return;
229     }
230     pid_t pid = fork();
231     if (pid == 0) {
232         void *child_handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
233         t_printf("%s child handle is %p \n", __FUNCTION__, child_handle);
234         if (child_handle) {
235             dlclose(child_handle);
236         }
237         write(fd[1], &child_handle, sizeof(void *));
238         exit(0);
239     }
240     parent_handle = dlopen_ns(&dlns, LIB_NAME, RTLD_NOW);
241     t_printf("%s parent handle is %p \n", __FUNCTION__, parent_handle);
242     if (parent_handle) {
243         dlclose(parent_handle);
244     }
245     int status;
246     waitpid(pid, &status, 0);
247     read(fd[0], &get_child_handle, sizeof(void *));
248     t_printf("%s get child handle is %p\n", __FUNCTION__, get_child_handle);
249     if (parent_handle == get_child_handle) {
250         t_printf("%s the parent handle is the same as the child handle!!!!\n", __FUNCTION__);
251     } else {
252         t_printf("%s the parent handle is different form the child handle.\n", __FUNCTION__);
253     }
254     close(fd[0]);
255     close(fd[1]);
256 }
257 
258 /**
259  * @tc.name      : dlsym_randomization_0100
260  * @tc.desc      : Repeatedly calling the dlsym interface to get symbol address, and calling dlclose to unload each time
261  * @tc.level     : Level3
262  */
dlsym_randomization_0100(void)263 static void dlsym_randomization_0100(void)
264 {
265     void *handle = dlopen(LIB_NAME, RTLD_NOW);
266     if (!handle) {
267         t_printf("%s dlopen failed: %s\n", __FUNCTION__, LIB_NAME);
268         return;
269     };
270     void *sym = dlsym(handle, "test");
271     t_printf("%s symbol address is %p\n", __FUNCTION__, sym);
272     dlclose(handle);
273 }
274 
275 /**
276  * @tc.name      : dlsym_randomization_0200
277  * @tc.desc      : Different processes call the dlsym interface to get symbol address
278  * @tc.level     : Level3
279  */
dlsym_randomization_0200(void)280 static void dlsym_randomization_0200(void)
281 {
282     void *parent_handle = 0;
283     void *child_handle = 0;
284     void *parent_sym = 0;
285     void *child_sym = 0;
286     void *get_child_sym = 0;
287     int fd[PIPE_FD];
288     if (pipe(fd) < 0) {
289         t_printf("%s create pipe error!\n", __FUNCTION__);
290         return;
291     }
292     pid_t pid = fork();
293     if (pid == 0) {
294         child_handle = dlopen(LIB_NAME_A, RTLD_NOW);
295         if (!child_handle) {
296             t_printf("%s child process dlopen failed: %s\n", __FUNCTION__, LIB_NAME_A);
297             exit(-1);
298         }
299         child_sym = dlsym(child_handle, "test");
300         t_printf("%s child sym is %p\n", __FUNCTION__, child_sym);
301         write(fd[1], &child_sym, sizeof(void *));
302         dlclose(child_handle);
303         exit(0);
304     }
305     parent_handle = dlopen(LIB_NAME_A, RTLD_NOW);
306     if (!parent_handle) {
307         t_printf("%s parent process dlopen failed: %s\n", __FUNCTION__, LIB_NAME_A);
308         return;
309     };
310     parent_sym = dlsym(parent_handle, "test");
311     t_printf("%s parent sym is %p\n", __FUNCTION__, parent_sym);
312     dlclose(parent_handle);
313     int status;
314     waitpid(pid, &status, 0);
315     read(fd[0], &get_child_sym, sizeof(void *));
316     if (parent_sym == get_child_sym) {
317         t_printf("%s the parent sym is the same as the child sym!!!!\n", __FUNCTION__);
318     } else {
319         t_printf("%s the parent sym is different form the child sym.\n", __FUNCTION__);
320     }
321     close(fd[0]);
322     close(fd[1]);
323 }
324 
325 TEST_FUNC test_cases[] = {
326     dlopen_randomization_0500,
327     dlopen_randomization_0700,
328     dlopen_ext_randomization_0500,
329     dlopen_ext_randomization_0700,
330     dlopen_ns_randomization_0500,
331     dlopen_ns_randomization_0700,
332     dlsym_randomization_0100,
333     dlsym_randomization_0200,
334 };
335 
main(int argc,char * argv[])336 int main(int argc, char *argv[])
337 {
338     size_t case_counts = sizeof test_cases / sizeof(TEST_FUNC);
339     for (size_t case_num = 0; case_num < case_counts; case_num++) {
340         test_cases[case_num]();
341     }
342     return t_status;
343 }