diff options
| author | djm <> | 2008-09-06 12:17:54 +0000 |
|---|---|---|
| committer | djm <> | 2008-09-06 12:17:54 +0000 |
| commit | 6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda (patch) | |
| tree | 7ccc28afe1789ea3dbedf72365f955d5b8e105b5 /src/lib/libcrypto/dso/dso_dlfcn.c | |
| parent | 89181603212b41e95cde36b1be5a146ce8fb2935 (diff) | |
| download | openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.gz openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.tar.bz2 openbsd-6b62d1fdd8a4fd35acfcc0c4bb1bf8b757fa8cda.zip | |
resolve conflicts
Diffstat (limited to 'src/lib/libcrypto/dso/dso_dlfcn.c')
| -rw-r--r-- | src/lib/libcrypto/dso/dso_dlfcn.c | 114 |
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); | |||
| 89 | static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); | 85 | static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); |
| 90 | #endif | 86 | #endif |
| 91 | static char *dlfcn_name_converter(DSO *dso, const char *filename); | 87 | static char *dlfcn_name_converter(DSO *dso, const char *filename); |
| 88 | static char *dlfcn_merger(DSO *dso, const char *filespec1, | ||
| 89 | const char *filespec2); | ||
| 92 | 90 | ||
| 93 | static DSO_METHOD dso_meth_dlfcn = { | 91 | static 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 | ||
| 268 | static 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 | |||
| 263 | static char *dlfcn_name_converter(DSO *dso, const char *filename) | 335 | static 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 | ||
| 298 | static void dlfcn_ref_point(){} | ||
| 299 | |||
| 300 | int 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 */ |
