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.c114
1 files changed, 79 insertions, 35 deletions
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c
index d48b4202f2..f734c1c6b7 100644
--- a/src/lib/libcrypto/dso/dso_dlfcn.c
+++ b/src/lib/libcrypto/dso/dso_dlfcn.c
@@ -1,4 +1,4 @@
1/* dso_dlfcn.c */ 1/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL 2/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -56,10 +56,6 @@
56 * 56 *
57 */ 57 */
58 58
59#ifdef __linux
60#define _GNU_SOURCE
61#endif
62
63#include <stdio.h> 59#include <stdio.h>
64#include "cryptlib.h" 60#include "cryptlib.h"
65#include <openssl/dso.h> 61#include <openssl/dso.h>
@@ -89,6 +85,8 @@ static int dlfcn_finish(DSO *dso);
89static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); 85static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
90#endif 86#endif
91static char *dlfcn_name_converter(DSO *dso, const char *filename); 87static char *dlfcn_name_converter(DSO *dso, const char *filename);
88static char *dlfcn_merger(DSO *dso, const char *filespec1,
89 const char *filespec2);
92 90
93static DSO_METHOD dso_meth_dlfcn = { 91static DSO_METHOD dso_meth_dlfcn = {
94 "OpenSSL 'dlfcn' shared library method", 92 "OpenSSL 'dlfcn' shared library method",
@@ -103,6 +101,7 @@ static DSO_METHOD dso_meth_dlfcn = {
103#endif 101#endif
104 NULL, /* ctrl */ 102 NULL, /* ctrl */
105 dlfcn_name_converter, 103 dlfcn_name_converter,
104 dlfcn_merger,
106 NULL, /* init */ 105 NULL, /* init */
107 NULL /* finish */ 106 NULL /* finish */
108 }; 107 };
@@ -145,13 +144,19 @@ static int dlfcn_load(DSO *dso)
145 void *ptr = NULL; 144 void *ptr = NULL;
146 /* See applicable comments in dso_dl.c */ 145 /* See applicable comments in dso_dl.c */
147 char *filename = DSO_convert_filename(dso, NULL); 146 char *filename = DSO_convert_filename(dso, NULL);
147 int flags = DLOPEN_FLAG;
148 148
149 if(filename == NULL) 149 if(filename == NULL)
150 { 150 {
151 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME); 151 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
152 goto err; 152 goto err;
153 } 153 }
154 ptr = dlopen(filename, DLOPEN_FLAG); 154
155#ifdef RTLD_GLOBAL
156 if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
157 flags |= RTLD_GLOBAL;
158#endif
159 ptr = dlopen(filename, flags);
155 if(ptr == NULL) 160 if(ptr == NULL)
156 { 161 {
157 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED); 162 DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
@@ -250,7 +255,7 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
250 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); 255 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
251 return(NULL); 256 return(NULL);
252 } 257 }
253 *(void**)(tsym) = dlsym(ptr, symname); 258 *(void **)(tsym) = dlsym(ptr, symname);
254 if(sym == NULL) 259 if(sym == NULL)
255 { 260 {
256 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); 261 DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
@@ -260,6 +265,73 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
260 return(sym); 265 return(sym);
261 } 266 }
262 267
268static char *dlfcn_merger(DSO *dso, const char *filespec1,
269 const char *filespec2)
270 {
271 char *merged;
272
273 if(!filespec1 && !filespec2)
274 {
275 DSOerr(DSO_F_DLFCN_MERGER,
276 ERR_R_PASSED_NULL_PARAMETER);
277 return(NULL);
278 }
279 /* If the first file specification is a rooted path, it rules.
280 same goes if the second file specification is missing. */
281 if (!filespec2 || filespec1[0] == '/')
282 {
283 merged = OPENSSL_malloc(strlen(filespec1) + 1);
284 if(!merged)
285 {
286 DSOerr(DSO_F_DLFCN_MERGER,
287 ERR_R_MALLOC_FAILURE);
288 return(NULL);
289 }
290 strcpy(merged, filespec1);
291 }
292 /* If the first file specification is missing, the second one rules. */
293 else if (!filespec1)
294 {
295 merged = OPENSSL_malloc(strlen(filespec2) + 1);
296 if(!merged)
297 {
298 DSOerr(DSO_F_DLFCN_MERGER,
299 ERR_R_MALLOC_FAILURE);
300 return(NULL);
301 }
302 strcpy(merged, filespec2);
303 }
304 else
305 /* This part isn't as trivial as it looks. It assumes that
306 the second file specification really is a directory, and
307 makes no checks whatsoever. Therefore, the result becomes
308 the concatenation of filespec2 followed by a slash followed
309 by filespec1. */
310 {
311 int spec2len, len;
312
313 spec2len = (filespec2 ? strlen(filespec2) : 0);
314 len = spec2len + (filespec1 ? strlen(filespec1) : 0);
315
316 if(filespec2 && filespec2[spec2len - 1] == '/')
317 {
318 spec2len--;
319 len--;
320 }
321 merged = OPENSSL_malloc(len + 2);
322 if(!merged)
323 {
324 DSOerr(DSO_F_DLFCN_MERGER,
325 ERR_R_MALLOC_FAILURE);
326 return(NULL);
327 }
328 strcpy(merged, filespec2);
329 merged[spec2len] = '/';
330 strcpy(&merged[spec2len + 1], filespec1);
331 }
332 return(merged);
333 }
334
263static char *dlfcn_name_converter(DSO *dso, const char *filename) 335static char *dlfcn_name_converter(DSO *dso, const char *filename)
264 { 336 {
265 char *translated; 337 char *translated;
@@ -294,32 +366,4 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename)
294 return(translated); 366 return(translated);
295 } 367 }
296 368
297#ifdef OPENSSL_FIPS
298static void dlfcn_ref_point(){}
299
300int DSO_pathbyaddr(void *addr,char *path,int sz)
301 {
302 Dl_info dli;
303 int len;
304
305 if (addr == NULL)
306 {
307 union { void(*f)(void); void *p; } t = { dlfcn_ref_point };
308 addr = t.p;
309 }
310
311 if (dladdr(addr,&dli))
312 {
313 len = (int)strlen(dli.dli_fname);
314 if (sz <= 0) return len+1;
315 if (len >= sz) len=sz-1;
316 memcpy(path,dli.dli_fname,len);
317 path[len++]=0;
318 return len;
319 }
320
321 ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
322 return -1;
323 }
324#endif
325#endif /* DSO_DLFCN */ 369#endif /* DSO_DLFCN */