OpenCoverage

dso_dlfcn.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/dso/dso_dlfcn.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: dso_dlfcn.c,v 1.29 2017/01/29 17:49:23 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;
never executed: return ((void *)0) ;
0
70}-
71#else-
72-
73#ifdef HAVE_DLFCN_H-
74# include <dlfcn.h>-
75# define HAVE_DLINFO 1-
76#endif-
77-
78/* Part of the hack in "dlfcn_load" ... */-
79#define DSO_MAX_TRANSLATED_SIZE 256-
80-
81static int dlfcn_load(DSO *dso);-
82static int dlfcn_unload(DSO *dso);-
83static void *dlfcn_bind_var(DSO *dso, const char *symname);-
84static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);-
85static char *dlfcn_name_converter(DSO *dso, const char *filename);-
86static char *dlfcn_merger(DSO *dso, const char *filespec1,-
87 const char *filespec2);-
88static int dlfcn_pathbyaddr(void *addr, char *path, int sz);-
89static void *dlfcn_globallookup(const char *name);-
90-
91static DSO_METHOD dso_meth_dlfcn = {-
92 .name = "OpenSSL 'dlfcn' shared library method",-
93 .dso_load = dlfcn_load,-
94 .dso_unload = dlfcn_unload,-
95 .dso_bind_var = dlfcn_bind_var,-
96 .dso_bind_func = dlfcn_bind_func,-
97 .dso_name_converter = dlfcn_name_converter,-
98 .dso_merger = dlfcn_merger,-
99 .pathbyaddr = dlfcn_pathbyaddr,-
100 .globallookup = dlfcn_globallookup-
101};-
102-
103DSO_METHOD *-
104DSO_METHOD_dlfcn(void)-
105{-
106 return (&dso_meth_dlfcn);-
107}-
108-
109/* For this DSO_METHOD, our meth_data STACK will contain;-
110 * (i) the handle (void*) returned from dlopen().-
111 */-
112-
113static int-
114dlfcn_load(DSO *dso)-
115{-
116 void *ptr = NULL;-
117 /* See applicable comments in dso_dl.c */-
118 char *filename = DSO_convert_filename(dso, NULL);-
119 int flags = RTLD_LAZY;-
120-
121 if (filename == NULL) {-
122 DSOerror(DSO_R_NO_FILENAME);-
123 goto err;-
124 }-
125-
126 if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)-
127 flags |= RTLD_GLOBAL;-
128 ptr = dlopen(filename, flags);-
129 if (ptr == NULL) {-
130 DSOerror(DSO_R_LOAD_FAILED);-
131 ERR_asprintf_error_data("filename(%s): %s", filename,-
132 dlerror());-
133 goto err;-
134 }-
135 if (!sk_void_push(dso->meth_data, (char *)ptr)) {-
136 DSOerror(DSO_R_STACK_ERROR);-
137 goto err;-
138 }-
139 /* Success */-
140 dso->loaded_filename = filename;-
141 return (1);-
142-
143err:-
144 /* Cleanup! */-
145 free(filename);-
146 if (ptr != NULL)-
147 dlclose(ptr);-
148 return (0);-
149}-
150-
151static int-
152dlfcn_unload(DSO *dso)-
153{-
154 void *ptr;-
155 if (dso == NULL) {-
156 DSOerror(ERR_R_PASSED_NULL_PARAMETER);-
157 return (0);-
158 }-
159 if (sk_void_num(dso->meth_data) < 1)-
160 return (1);-
161 ptr = sk_void_pop(dso->meth_data);-
162 if (ptr == NULL) {-
163 DSOerror(DSO_R_NULL_HANDLE);-
164 /* Should push the value back onto the stack in-
165 * case of a retry. */-
166 sk_void_push(dso->meth_data, ptr);-
167 return (0);-
168 }-
169 /* For now I'm not aware of any errors associated with dlclose() */-
170 dlclose(ptr);-
171 return (1);-
172}-
173-
174static void *-
175dlfcn_bind_var(DSO *dso, const char *symname)-
176{-
177 void *ptr, *sym;-
178-
179 if ((dso == NULL) || (symname == NULL)) {-
180 DSOerror(ERR_R_PASSED_NULL_PARAMETER);-
181 return (NULL);-
182 }-
183 if (sk_void_num(dso->meth_data) < 1) {-
184 DSOerror(DSO_R_STACK_ERROR);-
185 return (NULL);-
186 }-
187 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);-
188 if (ptr == NULL) {-
189 DSOerror(DSO_R_NULL_HANDLE);-
190 return (NULL);-
191 }-
192 sym = dlsym(ptr, symname);-
193 if (sym == NULL) {-
194 DSOerror(DSO_R_SYM_FAILURE);-
195 ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());-
196 return (NULL);-
197 }-
198 return (sym);-
199}-
200-
201static DSO_FUNC_TYPE-
202dlfcn_bind_func(DSO *dso, const char *symname)-
203{-
204 void *ptr;-
205 union {-
206 DSO_FUNC_TYPE sym;-
207 void *dlret;-
208 } u;-
209-
210 if ((dso == NULL) || (symname == NULL)) {-
211 DSOerror(ERR_R_PASSED_NULL_PARAMETER);-
212 return (NULL);-
213 }-
214 if (sk_void_num(dso->meth_data) < 1) {-
215 DSOerror(DSO_R_STACK_ERROR);-
216 return (NULL);-
217 }-
218 ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);-
219 if (ptr == NULL) {-
220 DSOerror(DSO_R_NULL_HANDLE);-
221 return (NULL);-
222 }-
223 u.dlret = dlsym(ptr, symname);-
224 if (u.dlret == NULL) {-
225 DSOerror(DSO_R_SYM_FAILURE);-
226 ERR_asprintf_error_data("symname(%s): %s", symname, dlerror());-
227 return (NULL);-
228 }-
229 return u.sym;-
230}-
231-
232static char *-
233dlfcn_merger(DSO *dso, const char *filespec1, const char *filespec2)-
234{-
235 char *merged;-
236-
237 if (!filespec1 && !filespec2) {-
238 DSOerror(ERR_R_PASSED_NULL_PARAMETER);-
239 return (NULL);-
240 }-
241 /* If the first file specification is a rooted path, it rules.-
242 same goes if the second file specification is missing. */-
243 if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {-
244 merged = strdup(filespec1);-
245 if (!merged) {-
246 DSOerror(ERR_R_MALLOC_FAILURE);-
247 return (NULL);-
248 }-
249 }-
250 /* If the first file specification is missing, the second one rules. */-
251 else if (!filespec1) {-
252 merged = strdup(filespec2);-
253 if (!merged) {-
254 DSOerror(ERR_R_MALLOC_FAILURE);-
255 return (NULL);-
256 }-
257 } else-
258 /* This part isn't as trivial as it looks. It assumes that-
259 the second file specification really is a directory, and-
260 makes no checks whatsoever. Therefore, the result becomes-
261 the concatenation of filespec2 followed by a slash followed-
262 by filespec1. */-
263 {-
264 size_t spec2len, len;-
265-
266 spec2len = strlen(filespec2);-
267 len = spec2len + (filespec1 ? strlen(filespec1) : 0);-
268-
269 if (filespec2 && filespec2[spec2len - 1] == '/') {-
270 spec2len--;-
271 len--;-
272 }-
273 merged = malloc(len + 2);-
274 if (!merged) {-
275 DSOerror(ERR_R_MALLOC_FAILURE);-
276 return (NULL);-
277 }-
278 strlcpy(merged, filespec2, len + 2);-
279 merged[spec2len] = '/';-
280 strlcpy(&merged[spec2len + 1], filespec1, len + 1 - spec2len);-
281 }-
282 return (merged);-
283}-
284-
285#define DSO_ext ".so"-
286#define DSO_extlen 3-
287-
288static char *-
289dlfcn_name_converter(DSO *dso, const char *filename)-
290{-
291 char *translated;-
292 int ret;-
293-
294 if (strchr(filename, '/') == NULL) {-
295 /* Bare name, so convert to "%s.so" or "lib%s.so" */-
296 if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)-
297 ret = asprintf(&translated, "lib%s" DSO_ext, filename);-
298 else-
299 ret = asprintf(&translated, "%s" DSO_ext, filename);-
300 if (ret == -1)-
301 translated = NULL;-
302 } else {-
303 /* Full path, so just duplicate it */-
304 translated = strdup(filename);-
305 }-
306-
307 if (translated == NULL)-
308 DSOerror(DSO_R_NAME_TRANSLATION_FAILED);-
309 return (translated);-
310}-
311-
312static int-
313dlfcn_pathbyaddr(void *addr, char *path, int sz)-
314{-
315 Dl_info dli;-
316 int len;-
317-
318 if (addr == NULL) {-
319 union{-
320 int(*f)(void*, char*, int);-
321 void *p;-
322 } t = { dlfcn_pathbyaddr };-
323 addr = t.p;-
324 }-
325-
326 if (dladdr(addr, &dli)) {-
327 len = (int)strlen(dli.dli_fname);-
328 if (sz <= 0)-
329 return len + 1;-
330 if (len >= sz)-
331 len = sz - 1;-
332 memcpy(path, dli.dli_fname, len);-
333 path[len++] = 0;-
334 return len;-
335 }-
336-
337 ERR_asprintf_error_data("dlfcn_pathbyaddr(): %s", dlerror());-
338 return -1;-
339}-
340-
341static void *-
342dlfcn_globallookup(const char *name)-
343{-
344 void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);-
345-
346 if (handle) {-
347 ret = dlsym(handle, name);-
348 dlclose(handle);-
349 }-
350-
351 return ret;-
352}-
353#endif /* DSO_DLFCN */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2