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 }