diff options
Diffstat (limited to 'src/lib/libcrypto/dso/dso_dl.c')
-rw-r--r-- | src/lib/libcrypto/dso/dso_dl.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/src/lib/libcrypto/dso/dso_dl.c b/src/lib/libcrypto/dso/dso_dl.c index 417abb6ea9..c3b4f6cf45 100644 --- a/src/lib/libcrypto/dso/dso_dl.c +++ b/src/lib/libcrypto/dso/dso_dl.c | |||
@@ -85,6 +85,8 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); | |||
85 | #endif | 85 | #endif |
86 | static char *dl_name_converter(DSO *dso, const char *filename); | 86 | static char *dl_name_converter(DSO *dso, const char *filename); |
87 | static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2); | 87 | static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2); |
88 | static int dl_pathbyaddr(void *addr,char *path,int sz); | ||
89 | static void *dl_globallookup(const char *name); | ||
88 | 90 | ||
89 | static DSO_METHOD dso_meth_dl = { | 91 | static DSO_METHOD dso_meth_dl = { |
90 | "OpenSSL 'dl' shared library method", | 92 | "OpenSSL 'dl' shared library method", |
@@ -101,7 +103,9 @@ static DSO_METHOD dso_meth_dl = { | |||
101 | dl_name_converter, | 103 | dl_name_converter, |
102 | dl_merger, | 104 | dl_merger, |
103 | NULL, /* init */ | 105 | NULL, /* init */ |
104 | NULL /* finish */ | 106 | NULL, /* finish */ |
107 | dl_pathbyaddr, | ||
108 | dl_globallookup | ||
105 | }; | 109 | }; |
106 | 110 | ||
107 | DSO_METHOD *DSO_METHOD_dl(void) | 111 | DSO_METHOD *DSO_METHOD_dl(void) |
@@ -255,18 +259,20 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) | |||
255 | same goes if the second file specification is missing. */ | 259 | same goes if the second file specification is missing. */ |
256 | if (!filespec2 || filespec1[0] == '/') | 260 | if (!filespec2 || filespec1[0] == '/') |
257 | { | 261 | { |
258 | merged = OPENSSL_malloc(strlen(filespec1) + 1); | 262 | size_t len = strlen(filespec1) + 1; |
263 | merged = OPENSSL_malloc(len); | ||
259 | if(!merged) | 264 | if(!merged) |
260 | { | 265 | { |
261 | DSOerr(DSO_F_DL_MERGER, | 266 | DSOerr(DSO_F_DL_MERGER, |
262 | ERR_R_MALLOC_FAILURE); | 267 | ERR_R_MALLOC_FAILURE); |
263 | return(NULL); | 268 | return(NULL); |
264 | } | 269 | } |
265 | strcpy(merged, filespec1); | 270 | memcpy(merged, filespec1, len); |
266 | } | 271 | } |
267 | /* If the first file specification is missing, the second one rules. */ | 272 | /* If the first file specification is missing, the second one rules. */ |
268 | else if (!filespec1) | 273 | else if (!filespec1) |
269 | { | 274 | { |
275 | size_t len = strlen(filespec2) + 1; | ||
270 | merged = OPENSSL_malloc(strlen(filespec2) + 1); | 276 | merged = OPENSSL_malloc(strlen(filespec2) + 1); |
271 | if(!merged) | 277 | if(!merged) |
272 | { | 278 | { |
@@ -274,7 +280,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) | |||
274 | ERR_R_MALLOC_FAILURE); | 280 | ERR_R_MALLOC_FAILURE); |
275 | return(NULL); | 281 | return(NULL); |
276 | } | 282 | } |
277 | strcpy(merged, filespec2); | 283 | memcpy(merged, filespec2, len); |
278 | } | 284 | } |
279 | else | 285 | else |
280 | /* This part isn't as trivial as it looks. It assumes that | 286 | /* This part isn't as trivial as it looks. It assumes that |
@@ -283,7 +289,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) | |||
283 | the concatenation of filespec2 followed by a slash followed | 289 | the concatenation of filespec2 followed by a slash followed |
284 | by filespec1. */ | 290 | by filespec1. */ |
285 | { | 291 | { |
286 | int spec2len, len; | 292 | size_t spec2len, len; |
287 | 293 | ||
288 | spec2len = (filespec2 ? strlen(filespec2) : 0); | 294 | spec2len = (filespec2 ? strlen(filespec2) : 0); |
289 | len = spec2len + (filespec1 ? strlen(filespec1) : 0); | 295 | len = spec2len + (filespec1 ? strlen(filespec1) : 0); |
@@ -300,9 +306,9 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) | |||
300 | ERR_R_MALLOC_FAILURE); | 306 | ERR_R_MALLOC_FAILURE); |
301 | return(NULL); | 307 | return(NULL); |
302 | } | 308 | } |
303 | strcpy(merged, filespec2); | 309 | strlcpy(merged, filespec2, len + 2); |
304 | merged[spec2len] = '/'; | 310 | merged[spec2len] = '/'; |
305 | strcpy(&merged[spec2len + 1], filespec1); | 311 | strlcpy(&merged[spec2len + 1], filespec1, 1 + len - spec2len); |
306 | } | 312 | } |
307 | return(merged); | 313 | return(merged); |
308 | } | 314 | } |
@@ -350,4 +356,40 @@ static char *dl_name_converter(DSO *dso, const char *filename) | |||
350 | return(translated); | 356 | return(translated); |
351 | } | 357 | } |
352 | 358 | ||
359 | static int dl_pathbyaddr(void *addr,char *path,int sz) | ||
360 | { | ||
361 | struct shl_descriptor inf; | ||
362 | int i,len; | ||
363 | |||
364 | if (addr == NULL) | ||
365 | { | ||
366 | union { int(*f)(void*,char*,int); void *p; } t = | ||
367 | { dl_pathbyaddr }; | ||
368 | addr = t.p; | ||
369 | } | ||
370 | |||
371 | for (i=-1;shl_get_r(i,&inf)==0;i++) | ||
372 | { | ||
373 | if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || | ||
374 | ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) | ||
375 | { | ||
376 | len = (int)strlen(inf.filename); | ||
377 | if (sz <= 0) return len+1; | ||
378 | if (len >= sz) len=sz-1; | ||
379 | memcpy(path,inf.filename,len); | ||
380 | path[len++] = 0; | ||
381 | return len; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | return -1; | ||
386 | } | ||
387 | |||
388 | static void *dl_globallookup(const char *name) | ||
389 | { | ||
390 | void *ret; | ||
391 | shl_t h = NULL; | ||
392 | |||
393 | return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret; | ||
394 | } | ||
353 | #endif /* DSO_DL */ | 395 | #endif /* DSO_DL */ |