Add DSO_global_lookup_func implementation. See commentary in dso_lib.c
authorAndy Polyakov <appro@openssl.org>
Fri, 30 Dec 2005 22:53:59 +0000 (22:53 +0000)
committerAndy Polyakov <appro@openssl.org>
Fri, 30 Dec 2005 22:53:59 +0000 (22:53 +0000)
for further details.

crypto/dso/dso.h
crypto/dso/dso_dl.c
crypto/dso/dso_dlfcn.c
crypto/dso/dso_err.c
crypto/dso/dso_lib.c
crypto/dso/dso_win32.c

index 5da0a55..10efa4a 100644 (file)
@@ -173,6 +173,9 @@ typedef struct dso_meth_st
 
        /* Return pathname of the module containing location */
        int (*pathbyaddr)(void *addr,char *path,int sz);
+       /* Perform global symbol lookup, i.e. among *all* modules,
+        * see commentray in dso_lib.c for further details. */
+       DSO_FUNC_TYPE (*globallookup)(const char *symname);
        } DSO_METHOD;
 
 /**********************************************************************/
@@ -357,6 +360,7 @@ void ERR_load_DSO_strings(void);
 #define DSO_F_WIN32_SPLITTER                            136
 #define DSO_F_WIN32_UNLOAD                              121
 #define DSO_F_PATHBYADDR                                137
+#define DSO_F_GLOBAL_LOOKUP_FUNC                        138
 
 /* Reason codes. */
 #define DSO_R_CTRL_FAILED                               100
index dccb8e7..7c123c8 100644 (file)
@@ -86,6 +86,7 @@ static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
 static char *dl_name_converter(DSO *dso, const char *filename);
 static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
 static int dl_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE dl_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dl = {
        "OpenSSL 'dl' shared library method",
@@ -103,7 +104,8 @@ static DSO_METHOD dso_meth_dl = {
        dl_merger,
        NULL, /* init */
        NULL, /* finish */
-       dl_pathbyaddr
+       dl_pathbyaddr,
+       dl_globallookup
        };
 
 DSO_METHOD *DSO_METHOD_dl(void)
@@ -380,4 +382,12 @@ static int dl_pathbyaddr(void *addr,char *path,int sz)
 
        return -1;
        }
+
+static DSO_FUNC_TYPE dl_globallookup(const char *name)
+       {
+       DSO_FUNC_TYPE ret;
+       shl_t h = NULL;
+
+       return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
+       }
 #endif /* DSO_DL */
index 6d6ee75..a4ab38f 100644 (file)
@@ -99,6 +99,7 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename);
 static char *dlfcn_merger(DSO *dso, const char *filespec1,
        const char *filespec2);
 static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE dlfcn_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dlfcn = {
        "OpenSSL 'dlfcn' shared library method",
@@ -116,7 +117,8 @@ static DSO_METHOD dso_meth_dlfcn = {
        dlfcn_merger,
        NULL, /* init */
        NULL, /* finish */
-       dlfcn_pathbyaddr
+       dlfcn_pathbyaddr,
+       dlfcn_globallookup
        };
 
 DSO_METHOD *DSO_METHOD_dlfcn(void)
@@ -443,4 +445,18 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
        ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
        return -1;
        }
+
+static DSO_FUNC_TYPE dlfcn_globallookup(const char *name)
+       {
+       union { void *p; DSO_FUNC_TYPE f; } ret = { NULL };
+       void *handle = dlopen(NULL,RTLD_LAZY);
+       
+       if (handle)
+               {
+               ret.p = dlsym(handle,name);
+               dlclose(handle);
+               }
+
+       return ret.f;
+       }
 #endif /* DSO_DLFCN */
index a88db0d..009a543 100644 (file)
@@ -108,6 +108,7 @@ static ERR_STRING_DATA DSO_str_functs[]=
 {ERR_FUNC(DSO_F_WIN32_SPLITTER),       "WIN32_SPLITTER"},
 {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"},
 {ERR_FUNC(DSO_F_PATHBYADDR),   "DSO_pathbyaddr"},
+{ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC),   "DSO_global_lookup_func"},
 {0,NULL}
        };
 
index 12ad097..8330c7d 100644 (file)
@@ -289,6 +289,7 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
                DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED);
                return(NULL);
                }
+fprintf(stderr,"boo\n");
        if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL)
                {
                DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE);
@@ -476,3 +477,23 @@ int DSO_pathbyaddr(void *addr,char *path,int sz)
                }
        return (*meth->pathbyaddr)(addr,path,sz);
        }
+
+/* This function should be used with caution! It looks up symbols in
+ * *all* loaded modules and if module gets unloaded by somebody else
+ * attempt to dereference the pointer is doomed to have fatal
+ * consequences. Primary usage for this function is to probe *core*
+ * system functionality, e.g. check if getnameinfo(3) is available
+ * at run-time without bothering about OS-specific details such as
+ * libc.so.versioning or where does it actually reside: in libc
+ * itself or libsocket. */
+DSO_FUNC_TYPE DSO_global_lookup_func(const char *name)
+       {
+       DSO_METHOD *meth = default_DSO_meth;
+       if (meth == NULL) meth = DSO_METHOD_openssl();
+       if (meth->globallookup == NULL)
+               {
+               DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+               return NULL;
+               }
+       return (*meth->globallookup)(name);
+       }
index b44f25c..73ffe36 100644 (file)
@@ -129,6 +129,7 @@ static char *win32_name_converter(DSO *dso, const char *filename);
 static char *win32_merger(DSO *dso, const char *filespec1,
        const char *filespec2);
 static int win32_pathbyaddr(void *addr,char *path,int sz);
+static DSO_FUNC_TYPE win32_globallookup(const char *name);
 
 static const char *openssl_strnchr(const char *string, int c, size_t len);
 
@@ -148,7 +149,8 @@ static DSO_METHOD dso_meth_win32 = {
        win32_merger,
        NULL, /* init */
        NULL, /* finish */
-       win32_pathbyaddr
+       win32_pathbyaddr,
+       win32_globallookup
        };
 
 DSO_METHOD *DSO_METHOD_win32(void)
@@ -770,4 +772,65 @@ static int win32_pathbyaddr(void *addr,char *path,int sz)
        FreeLibrary(dll);
        return 0;
        }
+
+static DSO_FUNC_TYPE win32_globallookup(const char *name)
+       {
+       HMODULE dll;
+       HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+       MODULEENTRY32 me32;
+       CREATETOOLHELP32SNAPSHOT create_snap;
+       CLOSETOOLHELP32SNAPSHOT  close_snap;
+       MODULE32 module_first, module_next;
+       FARPROC ret=NULL;
+
+       dll = LoadLibrary(TEXT(DLLNAME));
+       if (dll == NULL)
+               {
+               DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+               return NULL;
+               }
+
+       create_snap = (CREATETOOLHELP32SNAPSHOT)
+               GetProcAddress(dll,"CreateToolhelp32Snapshot");
+       if (create_snap == NULL)
+               {
+               FreeLibrary(dll);
+               DSOerr(DSO_F_GLOBAL_LOOKUP_FUNC,DSO_R_UNSUPPORTED);
+               return NULL;
+               }
+       /* We take the rest for granted... */
+#ifdef _WIN32_WCE
+       close_snap = (CLOSETOOLHELP32SNAPSHOT)
+               GetProcAddress(dll,"CloseToolhelp32Snapshot");
+#else
+       close_snap = (CLOSETOOLHELP32SNAPSHOT)CloseHandle;
+#endif
+       module_first = (MODULE32)GetProcAddress(dll,"Module32First");
+       module_next  = (MODULE32)GetProcAddress(dll,"Module32Next");
+
+       hModuleSnap = (*create_snap)(TH32CS_SNAPMODULE,0);
+       if( hModuleSnap == INVALID_HANDLE_VALUE ) return NULL;
+
+       me32.dwSize = sizeof(me32);
+
+       if (!(*module_first)(hModuleSnap,&me32))
+               {
+               (*close_snap)(hModuleSnap);
+               FreeLibrary(dll);
+               return NULL;
+               }
+
+       do      {
+               if (ret = GetProcAddress(me32.hModule,fname))
+                       {
+                       (*close_snap)(hModuleSnap);
+                       FreeLibrary(dll);
+                       return ret;
+                       }
+               } while((*module_next)(hModuleSnap,&me32));
+
+       (*close_snap)(hModuleSnap); 
+       FreeLibrary(dll);
+       return NULL;
+       }
 #endif /* DSO_WIN32 */