]>
Commit | Line | Data |
---|---|---|
8dcb6d0a FW |
1 | /* Check the usability of <dlfcn.h> functions in audit modules. Audit module. |
2 | Copyright (C) 2022 Free Software Foundation, Inc. | |
3 | This file is part of the GNU C Library. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <https://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include <dlfcn.h> | |
20 | #include <first-versions.h> | |
21 | #include <gnu/lib-names.h> | |
22 | #include <link.h> | |
23 | #include <stdio.h> | |
24 | #include <string.h> | |
25 | #include <unistd.h> | |
26 | ||
27 | #include <support/check.h> | |
28 | #include <support/xdlfcn.h> | |
29 | ||
30 | unsigned int | |
31 | la_version (unsigned int current) | |
32 | { | |
33 | /* Exercise various <dlfcn.h> functions. */ | |
34 | ||
35 | /* Check dlopen, dlsym, dlclose. */ | |
36 | void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW); | |
37 | void *ptr = xdlsym (handle, "sincos"); | |
38 | TEST_VERIFY (ptr != NULL); | |
39 | ptr = dlsym (handle, "SINCOS"); | |
40 | TEST_VERIFY (ptr == NULL); | |
41 | const char *message = dlerror (); | |
42 | TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL); | |
43 | ptr = dlsym (handle, "SINCOS"); | |
44 | TEST_VERIFY (ptr == NULL); | |
45 | xdlclose (handle); | |
46 | TEST_COMPARE_STRING (dlerror (), NULL); | |
47 | ||
48 | handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD); | |
49 | ||
50 | /* Check dlvsym. _exit is unlikely to gain another symbol | |
51 | version. */ | |
52 | TEST_VERIFY (xdlsym (handle, "_exit") | |
53 | == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING)); | |
54 | ||
55 | /* Check dlinfo. */ | |
56 | { | |
57 | void *handle2 = NULL; | |
58 | TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0); | |
59 | TEST_VERIFY (handle2 == handle); | |
60 | } | |
61 | ||
62 | /* Check dladdr and dladdr1. */ | |
63 | Dl_info info = { }; | |
64 | TEST_VERIFY (dladdr (&_exit, &info) != 0); | |
65 | if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */ | |
66 | TEST_COMPARE_STRING (info.dli_sname, "_exit"); | |
67 | TEST_VERIFY (info.dli_saddr == &_exit); | |
68 | TEST_VERIFY (strstr (info.dli_fname, LIBC_SO)); | |
69 | void *extra_info; | |
70 | memset (&info, 0, sizeof (info)); | |
71 | TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0); | |
72 | TEST_VERIFY (extra_info == handle); | |
73 | ||
74 | /* Verify that dlmopen creates a new namespace. */ | |
75 | void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); | |
76 | TEST_VERIFY (dlmopen_handle != handle); | |
77 | memset (&info, 0, sizeof (info)); | |
78 | extra_info = NULL; | |
79 | ptr = xdlsym (dlmopen_handle, "_exit"); | |
80 | TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0); | |
81 | TEST_VERIFY (extra_info == dlmopen_handle); | |
82 | xdlclose (dlmopen_handle); | |
83 | ||
84 | /* Terminate the process with an error state. This does not happen | |
85 | automatically because the audit module state is not shared with | |
86 | the main program. */ | |
87 | if (support_record_failure_is_failed ()) | |
88 | { | |
89 | fflush (stdout); | |
90 | fflush (stderr); | |
91 | _exit (1); | |
92 | } | |
93 | ||
94 | return LAV_CURRENT; | |
95 | } | |
96 | ||
97 | char * | |
98 | la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) | |
99 | { | |
100 | if (strcmp (name, "mapped to libc") == 0) | |
101 | return (char *) LIBC_SO; | |
102 | else | |
103 | return (char *) name; | |
104 | } |