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 }