summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dso/dso_dlfcn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/dso/dso_dlfcn.c')
-rw-r--r--src/lib/libcrypto/dso/dso_dlfcn.c355
1 files changed, 0 insertions, 355 deletions
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
deleted file mode 100644
index 77c19aa27e..0000000000
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ /dev/null
@@ -1,355 +0,0 @@
1/* $OpenBSD: dso_dlfcn.c,v 1.30 2023/07/08 07:22:58 beck Exp $ */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/dso.h>
63#include <openssl/err.h>
64
65#ifndef DSO_DLFCN
66DSO_METHOD *
67DSO_METHOD_dlfcn(void)
68{
69 return NULL;
70}
71LCRYPTO_ALIAS(DSO_METHOD_dlfcn);
72#else
73
74#ifdef HAVE_DLFCN_H
75# include <dlfcn.h>
76# define HAVE_DLINFO 1
77#endif
78
79/* Part of the hack in "dlfcn_load" ... */
80#define DSO_MAX_TRANSLATED_SIZE 256
81
82static int dlfcn_load(DSO *dso);
83static int dlfcn_unload(DSO *dso);
84static void *dlfcn_bind_var(DSO *dso, const char *symname);
85static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
86static char *dlfcn_name_converter(DSO *dso, const char *filename);
87static char *dlfcn_merger(DSO *dso, const char *filespec1,
88 const char *filespec2);
89static int dlfcn_pathbyaddr(void *addr, char *path, int sz);
90static void *dlfcn_globallookup(const char *name);
91
92static DSO_METHOD dso_meth_dlfcn = {
93 .name = "OpenSSL 'dlfcn' shared library method",
94 .dso_load = dlfcn_load,
95 .dso_unload = dlfcn_unload,
96 .dso_bind_var = dlfcn_bind_var,
97 .dso_bind_func = dlfcn_bind_func,
98 .dso_name_converter = dlfcn_name_converter,
99 .dso_merger = dlfcn_merger,
100 .pathbyaddr = dlfcn_pathbyaddr,
101 .globallookup = dlfcn_globallookup
102};
103
104DSO_METHOD *
105DSO_METHOD_dlfcn(void)
106{
107 return (&dso_meth_dlfcn);
108}
109LCRYPTO_ALIAS(DSO_METHOD_dlfcn);
110
111/* For this DSO_METHOD, our meth_data STACK will contain;
112 * (i) the handle (void*) returned from dlopen().
113 */
114
115static int
116dlfcn_load(DSO *dso)
117{
118 void *ptr = NULL;
119 /* See applicable comments in dso_dl.c */
120 char *filename = DSO_convert_filename(dso, NULL);
121 int flags = RTLD_LAZY;
122
123 if (filename == NULL) {
124 DSOerror(DSO_R_NO_FILENAME);
125 goto err;
126 }
127
128 if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
129 flags |= RTLD_GLOBAL;
130 ptr = dlopen(filename, flags);
131 if (ptr == NULL) {
132 DSOerror(DSO_R_LOAD_FAILED);
133 ERR_asprintf_error_data("filename(%s): %s", filename,
134 dlerror());
135 goto err;
136 }
137 if (!sk_void_push(dso->meth_data, (char *)ptr)) {
138 DSOerror(DSO_R_STACK_ERROR);
139 goto err;
140 }
141 /* Success */
142 dso->loaded_filename = filename;
143 return (1);
144
145err:
146 /* Cleanup! */
147 free(filename);
148 if (ptr != NULL)
149 dlclose(ptr);
150 return (0);
151}
152
153static int
154dlfcn_unload(DSO *dso)
155{
156 void *ptr;
157 if (dso == NULL) {
158 DSOerror(ERR_R_PASSED_NULL_PARAMETER);
159 return (0);
160 }
161 if (sk_void_num(dso->meth_data) < 1)
162 return (1);
163 ptr = sk_void_pop(dso->meth_data);
164 if (ptr == NULL) {
165 DSOerror(DSO_R_NULL_HANDLE);
166 /* Should push the value back onto the stack in
167 * case of a retry. */
168 sk_void_push(dso->meth_data, ptr);
169 return (0);
170 }
171 /* For now I'm not aware of any errors associated with dlclose() */
172 dlclose(ptr);
173 return (1);
174}
175
176static void *
177dlfcn_bind_var(DSO *dso, const char *symname)
178{
179 void *ptr, *sym;
180
181 if ((dso == NULL) || (symname == NULL)) {
182 DSOerror(ERR_R_PASSED_NULL_PARAMETER);
183 return (NULL);
184 }
185 if (sk_void_num(dso->meth_data) < 1) {
186 DSOerror(DSO_R_STACK_ERROR);
187 return (NULL);
188 }
189 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
190 if (ptr == NULL) {
191 DSOerror(DSO_R_NULL_HANDLE);
192 return (NULL);
193 }
194 sym = dlsym(ptr, symname);
195 if (sym == NULL) {
196 DSOerror(DSO_R_SYM_FAILURE);
197 ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());
198 return (NULL);
199 }
200 return (sym);
201}
202
203static DSO_FUNC_TYPE
204dlfcn_bind_func(DSO *dso, const char *symname)
205{
206 void *ptr;
207 union {
208 DSO_FUNC_TYPE sym;
209 void *dlret;
210 } u;
211
212 if ((dso == NULL) || (symname == NULL)) {
213 DSOerror(ERR_R_PASSED_NULL_PARAMETER);
214 return (NULL);
215 }
216 if (sk_void_num(dso->meth_data) < 1) {
217 DSOerror(DSO_R_STACK_ERROR);
218 return (NULL);
219 }
220 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
221 if (ptr == NULL) {
222 DSOerror(DSO_R_NULL_HANDLE);
223 return (NULL);
224 }
225 u.dlret = dlsym(ptr, symname);
226 if (u.dlret == NULL) {
227 DSOerror(DSO_R_SYM_FAILURE);
228 ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());
229 return (NULL);
230 }
231 return u.sym;
232}
233
234static char *
235dlfcn_merger(DSO *dso, const char *filespec1, const char *filespec2)
236{
237 char *merged;
238
239 if (!filespec1 && !filespec2) {
240 DSOerror(ERR_R_PASSED_NULL_PARAMETER);
241 return (NULL);
242 }
243 /* If the first file specification is a rooted path, it rules.
244 same goes if the second file specification is missing. */
245 if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {
246 merged = strdup(filespec1);
247 if (!merged) {
248 DSOerror(ERR_R_MALLOC_FAILURE);
249 return (NULL);
250 }
251 }
252 /* If the first file specification is missing, the second one rules. */
253 else if (!filespec1) {
254 merged = strdup(filespec2);
255 if (!merged) {
256 DSOerror(ERR_R_MALLOC_FAILURE);
257 return (NULL);
258 }
259 } else
260 /* This part isn't as trivial as it looks. It assumes that
261 the second file specification really is a directory, and
262 makes no checks whatsoever. Therefore, the result becomes
263 the concatenation of filespec2 followed by a slash followed
264 by filespec1. */
265 {
266 size_t spec2len, len;
267
268 spec2len = strlen(filespec2);
269 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
270
271 if (filespec2 && filespec2[spec2len - 1] == '/') {
272 spec2len--;
273 len--;
274 }
275 merged = malloc(len + 2);
276 if (!merged) {
277 DSOerror(ERR_R_MALLOC_FAILURE);
278 return (NULL);
279 }
280 strlcpy(merged, filespec2, len + 2);
281 merged[spec2len] = '/';
282 strlcpy(&merged[spec2len + 1], filespec1, len + 1 - spec2len);
283 }
284 return (merged);
285}
286
287#define DSO_ext ".so"
288#define DSO_extlen 3
289
290static char *
291dlfcn_name_converter(DSO *dso, const char *filename)
292{
293 char *translated;
294 int ret;
295
296 if (strchr(filename, '/') == NULL) {
297 /* Bare name, so convert to "%s.so" or "lib%s.so" */
298 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
299 ret = asprintf(&translated, "lib%s" DSO_ext, filename);
300 else
301 ret = asprintf(&translated, "%s" DSO_ext, filename);
302 if (ret == -1)
303 translated = NULL;
304 } else {
305 /* Full path, so just duplicate it */
306 translated = strdup(filename);
307 }
308
309 if (translated == NULL)
310 DSOerror(DSO_R_NAME_TRANSLATION_FAILED);
311 return (translated);
312}
313
314static int
315dlfcn_pathbyaddr(void *addr, char *path, int sz)
316{
317 Dl_info dli;
318 int len;
319
320 if (addr == NULL) {
321 union{
322 int(*f)(void*, char*, int);
323 void *p;
324 } t = { dlfcn_pathbyaddr };
325 addr = t.p;
326 }
327
328 if (dladdr(addr, &dli)) {
329 len = (int)strlen(dli.dli_fname);
330 if (sz <= 0)
331 return len + 1;
332 if (len >= sz)
333 len = sz - 1;
334 memcpy(path, dli.dli_fname, len);
335 path[len++] = 0;
336 return len;
337 }
338
339 ERR_asprintf_error_data("dlfcn_pathbyaddr(): %s", dlerror());
340 return -1;
341}
342
343static void *
344dlfcn_globallookup(const char *name)
345{
346 void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
347
348 if (handle) {
349 ret = dlsym(handle, name);
350 dlclose(handle);
351 }
352
353 return ret;
354}
355#endif /* DSO_DLFCN */