diff options
| author | djm <> | 2010-10-01 22:59:01 +0000 |
|---|---|---|
| committer | djm <> | 2010-10-01 22:59:01 +0000 |
| commit | 8922d4bc4a8b8893d72a48deb2cdf58215f98505 (patch) | |
| tree | 939b752540947d33507b3acc48d76a8bfb7c3dc3 /src/lib/libcrypto/dso/dso_dlfcn.c | |
| parent | 76262f7bf9262f965142b1b2b2105cb279c5c696 (diff) | |
| download | openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.tar.gz openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.tar.bz2 openbsd-8922d4bc4a8b8893d72a48deb2cdf58215f98505.zip | |
resolve conflicts, fix local changes
Diffstat (limited to 'src/lib/libcrypto/dso/dso_dlfcn.c')
| -rw-r--r-- | src/lib/libcrypto/dso/dso_dlfcn.c | 157 |
1 files changed, 135 insertions, 22 deletions
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c index 656cd496f8..5dceaf7b00 100644 --- a/src/lib/libcrypto/dso/dso_dlfcn.c +++ b/src/lib/libcrypto/dso/dso_dlfcn.c | |||
| @@ -56,6 +56,16 @@ | |||
| 56 | * | 56 | * |
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | /* We need to do this early, because stdio.h includes the header files | ||
| 60 | that handle _GNU_SOURCE and other similar macros. Defining it later | ||
| 61 | is simply too late, because those headers are protected from re- | ||
| 62 | inclusion. */ | ||
| 63 | #ifdef __linux | ||
| 64 | # ifndef _GNU_SOURCE | ||
| 65 | # define _GNU_SOURCE /* make sure dladdr is declared */ | ||
| 66 | # endif | ||
| 67 | #endif | ||
| 68 | |||
| 59 | #include <stdio.h> | 69 | #include <stdio.h> |
| 60 | #include "cryptlib.h" | 70 | #include "cryptlib.h" |
| 61 | #include <openssl/dso.h> | 71 | #include <openssl/dso.h> |
| @@ -68,7 +78,16 @@ DSO_METHOD *DSO_METHOD_dlfcn(void) | |||
| 68 | #else | 78 | #else |
| 69 | 79 | ||
| 70 | #ifdef HAVE_DLFCN_H | 80 | #ifdef HAVE_DLFCN_H |
| 71 | #include <dlfcn.h> | 81 | # ifdef __osf__ |
| 82 | # define __EXTENSIONS__ | ||
| 83 | # endif | ||
| 84 | # include <dlfcn.h> | ||
| 85 | # define HAVE_DLINFO 1 | ||
| 86 | # if defined(_AIX) || defined(__CYGWIN__) || \ | ||
| 87 | defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ | ||
| 88 | (defined(__OpenBSD__) && !defined(RTLD_SELF)) | ||
| 89 | # undef HAVE_DLINFO | ||
| 90 | # endif | ||
| 72 | #endif | 91 | #endif |
| 73 | 92 | ||
| 74 | /* Part of the hack in "dlfcn_load" ... */ | 93 | /* Part of the hack in "dlfcn_load" ... */ |
| @@ -87,6 +106,8 @@ static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); | |||
| 87 | static char *dlfcn_name_converter(DSO *dso, const char *filename); | 106 | static char *dlfcn_name_converter(DSO *dso, const char *filename); |
| 88 | static char *dlfcn_merger(DSO *dso, const char *filespec1, | 107 | static char *dlfcn_merger(DSO *dso, const char *filespec1, |
| 89 | const char *filespec2); | 108 | const char *filespec2); |
| 109 | static int dlfcn_pathbyaddr(void *addr,char *path,int sz); | ||
| 110 | static void *dlfcn_globallookup(const char *name); | ||
| 90 | 111 | ||
| 91 | static DSO_METHOD dso_meth_dlfcn = { | 112 | static DSO_METHOD dso_meth_dlfcn = { |
| 92 | "OpenSSL 'dlfcn' shared library method", | 113 | "OpenSSL 'dlfcn' shared library method", |
| @@ -103,7 +124,9 @@ static DSO_METHOD dso_meth_dlfcn = { | |||
| 103 | dlfcn_name_converter, | 124 | dlfcn_name_converter, |
| 104 | dlfcn_merger, | 125 | dlfcn_merger, |
| 105 | NULL, /* init */ | 126 | NULL, /* init */ |
| 106 | NULL /* finish */ | 127 | NULL, /* finish */ |
| 128 | dlfcn_pathbyaddr, | ||
| 129 | dlfcn_globallookup | ||
| 107 | }; | 130 | }; |
| 108 | 131 | ||
| 109 | DSO_METHOD *DSO_METHOD_dlfcn(void) | 132 | DSO_METHOD *DSO_METHOD_dlfcn(void) |
| @@ -163,7 +186,7 @@ static int dlfcn_load(DSO *dso) | |||
| 163 | ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); | 186 | ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); |
| 164 | goto err; | 187 | goto err; |
| 165 | } | 188 | } |
| 166 | if(!sk_push(dso->meth_data, (char *)ptr)) | 189 | if(!sk_void_push(dso->meth_data, (char *)ptr)) |
| 167 | { | 190 | { |
| 168 | DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); | 191 | DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); |
| 169 | goto err; | 192 | goto err; |
| @@ -188,15 +211,15 @@ static int dlfcn_unload(DSO *dso) | |||
| 188 | DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); | 211 | DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); |
| 189 | return(0); | 212 | return(0); |
| 190 | } | 213 | } |
| 191 | if(sk_num(dso->meth_data) < 1) | 214 | if(sk_void_num(dso->meth_data) < 1) |
| 192 | return(1); | 215 | return(1); |
| 193 | ptr = (void *)sk_pop(dso->meth_data); | 216 | ptr = sk_void_pop(dso->meth_data); |
| 194 | if(ptr == NULL) | 217 | if(ptr == NULL) |
| 195 | { | 218 | { |
| 196 | DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); | 219 | DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); |
| 197 | /* Should push the value back onto the stack in | 220 | /* Should push the value back onto the stack in |
| 198 | * case of a retry. */ | 221 | * case of a retry. */ |
| 199 | sk_push(dso->meth_data, (char *)ptr); | 222 | sk_void_push(dso->meth_data, ptr); |
| 200 | return(0); | 223 | return(0); |
| 201 | } | 224 | } |
| 202 | /* For now I'm not aware of any errors associated with dlclose() */ | 225 | /* For now I'm not aware of any errors associated with dlclose() */ |
| @@ -213,12 +236,12 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname) | |||
| 213 | DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); | 236 | DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); |
| 214 | return(NULL); | 237 | return(NULL); |
| 215 | } | 238 | } |
| 216 | if(sk_num(dso->meth_data) < 1) | 239 | if(sk_void_num(dso->meth_data) < 1) |
| 217 | { | 240 | { |
| 218 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); | 241 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); |
| 219 | return(NULL); | 242 | return(NULL); |
| 220 | } | 243 | } |
| 221 | ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); | 244 | ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); |
| 222 | if(ptr == NULL) | 245 | if(ptr == NULL) |
| 223 | { | 246 | { |
| 224 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); | 247 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); |
| @@ -237,32 +260,35 @@ static void *dlfcn_bind_var(DSO *dso, const char *symname) | |||
| 237 | static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) | 260 | static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) |
| 238 | { | 261 | { |
| 239 | void *ptr; | 262 | void *ptr; |
| 240 | DSO_FUNC_TYPE sym, *tsym = &sym; | 263 | union { |
| 264 | DSO_FUNC_TYPE sym; | ||
| 265 | void *dlret; | ||
| 266 | } u; | ||
| 241 | 267 | ||
| 242 | if((dso == NULL) || (symname == NULL)) | 268 | if((dso == NULL) || (symname == NULL)) |
| 243 | { | 269 | { |
| 244 | DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); | 270 | DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); |
| 245 | return(NULL); | 271 | return(NULL); |
| 246 | } | 272 | } |
| 247 | if(sk_num(dso->meth_data) < 1) | 273 | if(sk_void_num(dso->meth_data) < 1) |
| 248 | { | 274 | { |
| 249 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); | 275 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); |
| 250 | return(NULL); | 276 | return(NULL); |
| 251 | } | 277 | } |
| 252 | ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); | 278 | ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); |
| 253 | if(ptr == NULL) | 279 | if(ptr == NULL) |
| 254 | { | 280 | { |
| 255 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); | 281 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); |
| 256 | return(NULL); | 282 | return(NULL); |
| 257 | } | 283 | } |
| 258 | *(void **)(tsym) = dlsym(ptr, symname); | 284 | u.dlret = dlsym(ptr, symname); |
| 259 | if(sym == NULL) | 285 | if(u.dlret == NULL) |
| 260 | { | 286 | { |
| 261 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); | 287 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); |
| 262 | ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); | 288 | ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); |
| 263 | return(NULL); | 289 | return(NULL); |
| 264 | } | 290 | } |
| 265 | return(sym); | 291 | return u.sym; |
| 266 | } | 292 | } |
| 267 | 293 | ||
| 268 | static char *dlfcn_merger(DSO *dso, const char *filespec1, | 294 | static char *dlfcn_merger(DSO *dso, const char *filespec1, |
| @@ -279,14 +305,13 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, | |||
| 279 | } | 305 | } |
| 280 | /* If the first file specification is a rooted path, it rules. | 306 | /* If the first file specification is a rooted path, it rules. |
| 281 | same goes if the second file specification is missing. */ | 307 | same goes if the second file specification is missing. */ |
| 282 | if (!filespec2 || filespec1[0] == '/') | 308 | if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) |
| 283 | { | 309 | { |
| 284 | len = strlen(filespec1) + 1; | 310 | len = strlen(filespec1) + 1; |
| 285 | merged = OPENSSL_malloc(len); | 311 | merged = OPENSSL_malloc(len); |
| 286 | if(!merged) | 312 | if(!merged) |
| 287 | { | 313 | { |
| 288 | DSOerr(DSO_F_DLFCN_MERGER, | 314 | DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); |
| 289 | ERR_R_MALLOC_FAILURE); | ||
| 290 | return(NULL); | 315 | return(NULL); |
| 291 | } | 316 | } |
| 292 | strlcpy(merged, filespec1, len); | 317 | strlcpy(merged, filespec1, len); |
| @@ -313,7 +338,7 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, | |||
| 313 | { | 338 | { |
| 314 | int spec2len, len; | 339 | int spec2len, len; |
| 315 | 340 | ||
| 316 | spec2len = (filespec2 ? strlen(filespec2) : 0); | 341 | spec2len = strlen(filespec2); |
| 317 | len = spec2len + (filespec1 ? strlen(filespec1) : 0); | 342 | len = spec2len + (filespec1 ? strlen(filespec1) : 0); |
| 318 | 343 | ||
| 319 | if(filespec2 && filespec2[spec2len - 1] == '/') | 344 | if(filespec2 && filespec2[spec2len - 1] == '/') |
| @@ -335,6 +360,15 @@ static char *dlfcn_merger(DSO *dso, const char *filespec1, | |||
| 335 | return(merged); | 360 | return(merged); |
| 336 | } | 361 | } |
| 337 | 362 | ||
| 363 | #ifdef OPENSSL_SYS_MACOSX | ||
| 364 | #define DSO_ext ".dylib" | ||
| 365 | #define DSO_extlen 6 | ||
| 366 | #else | ||
| 367 | #define DSO_ext ".so" | ||
| 368 | #define DSO_extlen 3 | ||
| 369 | #endif | ||
| 370 | |||
| 371 | |||
| 338 | static char *dlfcn_name_converter(DSO *dso, const char *filename) | 372 | static char *dlfcn_name_converter(DSO *dso, const char *filename) |
| 339 | { | 373 | { |
| 340 | char *translated; | 374 | char *translated; |
| @@ -345,8 +379,8 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename) | |||
| 345 | transform = (strstr(filename, "/") == NULL); | 379 | transform = (strstr(filename, "/") == NULL); |
| 346 | if(transform) | 380 | if(transform) |
| 347 | { | 381 | { |
| 348 | /* We will convert this to "%s.so" or "lib%s.so" */ | 382 | /* We will convert this to "%s.so" or "lib%s.so" etc */ |
| 349 | rsize += 3; /* The length of ".so" */ | 383 | rsize += DSO_extlen; /* The length of ".so" */ |
| 350 | if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) | 384 | if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) |
| 351 | rsize += 3; /* The length of "lib" */ | 385 | rsize += 3; /* The length of "lib" */ |
| 352 | } | 386 | } |
| @@ -360,13 +394,92 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename) | |||
| 360 | if(transform) | 394 | if(transform) |
| 361 | { | 395 | { |
| 362 | if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) | 396 | if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) |
| 363 | snprintf(translated, rsize, "lib%s.so", filename); | 397 | snprintf(translated, rsize, "lib%s" DSO_ext, filename); |
| 364 | else | 398 | else |
| 365 | snprintf(translated, rsize, "%s.so", filename); | 399 | snprintf(translated, rsize, "%s" DSO_ext, filename); |
| 366 | } | 400 | } |
| 367 | else | 401 | else |
| 368 | snprintf(translated, rsize, "%s", filename); | 402 | snprintf(translated, rsize, "%s", filename); |
| 369 | return(translated); | 403 | return(translated); |
| 370 | } | 404 | } |
| 371 | 405 | ||
| 406 | #if defined(__sgi) && !defined(__OpenBSD__) | ||
| 407 | /* | ||
| 408 | This is a quote from IRIX manual for dladdr(3c): | ||
| 409 | |||
| 410 | <dlfcn.h> does not contain a prototype for dladdr or definition of | ||
| 411 | Dl_info. The #include <dlfcn.h> in the SYNOPSIS line is traditional, | ||
| 412 | but contains no dladdr prototype and no IRIX library contains an | ||
| 413 | implementation. Write your own declaration based on the code below. | ||
| 414 | |||
| 415 | The following code is dependent on internal interfaces that are not | ||
| 416 | part of the IRIX compatibility guarantee; however, there is no future | ||
| 417 | intention to change this interface, so on a practical level, the code | ||
| 418 | below is safe to use on IRIX. | ||
| 419 | */ | ||
| 420 | #include <rld_interface.h> | ||
| 421 | #ifndef _RLD_INTERFACE_DLFCN_H_DLADDR | ||
| 422 | #define _RLD_INTERFACE_DLFCN_H_DLADDR | ||
| 423 | typedef struct Dl_info { | ||
| 424 | const char * dli_fname; | ||
| 425 | void * dli_fbase; | ||
| 426 | const char * dli_sname; | ||
| 427 | void * dli_saddr; | ||
| 428 | int dli_version; | ||
| 429 | int dli_reserved1; | ||
| 430 | long dli_reserved[4]; | ||
| 431 | } Dl_info; | ||
| 432 | #else | ||
| 433 | typedef struct Dl_info Dl_info; | ||
| 434 | #endif | ||
| 435 | #define _RLD_DLADDR 14 | ||
| 436 | |||
| 437 | static int dladdr(void *address, Dl_info *dl) | ||
| 438 | { | ||
| 439 | void *v; | ||
| 440 | v = _rld_new_interface(_RLD_DLADDR,address,dl); | ||
| 441 | return (int)v; | ||
| 442 | } | ||
| 443 | #endif /* __sgi */ | ||
| 444 | |||
| 445 | static int dlfcn_pathbyaddr(void *addr,char *path,int sz) | ||
| 446 | { | ||
| 447 | #ifdef HAVE_DLINFO | ||
| 448 | Dl_info dli; | ||
| 449 | int len; | ||
| 450 | |||
| 451 | if (addr == NULL) | ||
| 452 | { | ||
| 453 | union { int(*f)(void*,char*,int); void *p; } t = | ||
| 454 | { dlfcn_pathbyaddr }; | ||
| 455 | addr = t.p; | ||
| 456 | } | ||
| 457 | |||
| 458 | if (dladdr(addr,&dli)) | ||
| 459 | { | ||
| 460 | len = (int)strlen(dli.dli_fname); | ||
| 461 | if (sz <= 0) return len+1; | ||
| 462 | if (len >= sz) len=sz-1; | ||
| 463 | memcpy(path,dli.dli_fname,len); | ||
| 464 | path[len++]=0; | ||
| 465 | return len; | ||
| 466 | } | ||
| 467 | |||
| 468 | ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror()); | ||
| 469 | #endif | ||
| 470 | return -1; | ||
| 471 | } | ||
| 472 | |||
| 473 | static void *dlfcn_globallookup(const char *name) | ||
| 474 | { | ||
| 475 | void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY); | ||
| 476 | |||
| 477 | if (handle) | ||
| 478 | { | ||
| 479 | ret = dlsym(handle,name); | ||
| 480 | dlclose(handle); | ||
| 481 | } | ||
| 482 | |||
| 483 | return ret; | ||
| 484 | } | ||
| 372 | #endif /* DSO_DLFCN */ | 485 | #endif /* DSO_DLFCN */ |
