Partial revert of 3d8b2ec42 to add back DSO_pathbyaddr
authorMatt Caswell <matt@openssl.org>
Sat, 15 Oct 2016 14:23:03 +0000 (15:23 +0100)
committerMatt Caswell <matt@openssl.org>
Wed, 2 Nov 2016 23:32:50 +0000 (23:32 +0000)
Commit 3d8b2ec42 removed various unused functions. However now we need to
use one of them! This commit resurrects DSO_pathbyaddr(). We're not going to
resurrect the Windows version though because what we need to achieve can be
done a different way on Windows.

Reviewed-by: Tim Hudson <tjh@openssl.org>
crypto/dso/dso_dl.c
crypto/dso/dso_dlfcn.c
crypto/dso/dso_err.c
crypto/dso/dso_lib.c
crypto/dso/dso_locl.h
crypto/dso/dso_vms.c
crypto/dso/dso_win32.c
include/internal/dso.h
util/libcrypto.num

index bc29fb23e03955b12a12a2e5f09318f06d02395d..d80bf562c7f225223ba1a4d5b08c626c08f0dfd7 100644 (file)
@@ -22,6 +22,7 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
 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 void *dl_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dl = {
@@ -34,6 +35,7 @@ static DSO_METHOD dso_meth_dl = {
     dl_merger,
     NULL,                       /* init */
     NULL,                       /* finish */
+    dl_pathbyaddr,
     dl_globallookup
 };
 
@@ -235,6 +237,38 @@ static char *dl_name_converter(DSO *dso, const char *filename)
     return (translated);
 }
 
+static int dl_pathbyaddr(void *addr, char *path, int sz)
+{
+    struct shl_descriptor inf;
+    int i, len;
+
+    if (addr == NULL) {
+        union {
+            int (*f) (void *, char *, int);
+            void *p;
+        } t = {
+            dl_pathbyaddr
+        };
+        addr = t.p;
+    }
+
+    for (i = -1; shl_get_r(i, &inf) == 0; i++) {
+        if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
+            ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) {
+            len = (int)strlen(inf.filename);
+            if (sz <= 0)
+                return len + 1;
+            if (len >= sz)
+                len = sz - 1;
+            memcpy(path, inf.filename, len);
+            path[len++] = 0;
+            return len;
+        }
+    }
+
+    return -1;
+}
+
 static void *dl_globallookup(const char *name)
 {
     void *ret;
index 624052b86a310d8e254fcca3db33cd5cc6bf37cb..a4b0cdd95b5d78c16fd9c224f6ea5ceac392c343 100644 (file)
@@ -44,6 +44,7 @@ static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
 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 void *dlfcn_globallookup(const char *name);
 
 static DSO_METHOD dso_meth_dlfcn = {
@@ -56,6 +57,7 @@ static DSO_METHOD dso_meth_dlfcn = {
     dlfcn_merger,
     NULL,                       /* init */
     NULL,                       /* finish */
+    dlfcn_pathbyaddr,
     dlfcn_globallookup
 };
 
@@ -306,6 +308,38 @@ static int dladdr(void *address, Dl_info *dl)
 }
 # endif                         /* __sgi */
 
+static int dlfcn_pathbyaddr(void *addr, char *path, int sz)
+{
+# ifdef HAVE_DLINFO
+    Dl_info dli;
+    int len;
+
+    if (addr == NULL) {
+        union {
+            int (*f) (void *, char *, int);
+            void *p;
+        } t = {
+            dlfcn_pathbyaddr
+        };
+        addr = t.p;
+    }
+
+    if (dladdr(addr, &dli)) {
+        len = (int)strlen(dli.dli_fname);
+        if (sz <= 0)
+            return len + 1;
+        if (len >= sz)
+            len = sz - 1;
+        memcpy(path, dli.dli_fname, len);
+        path[len++] = 0;
+        return len;
+    }
+
+    ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
+# endif
+    return -1;
+}
+
 static void *dlfcn_globallookup(const char *name)
 {
     void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
index a1805807597db75859c55caf0de4647f347f4b40..07588d5c3993305ab7c986ed910654697dd51c30 100644 (file)
@@ -38,6 +38,7 @@ static ERR_STRING_DATA DSO_str_functs[] = {
     {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
     {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
     {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
+    {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"},
     {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
     {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
     {ERR_FUNC(DSO_F_VMS_BIND_SYM), "vms_bind_sym"},
@@ -50,6 +51,7 @@ static ERR_STRING_DATA DSO_str_functs[] = {
     {ERR_FUNC(DSO_F_WIN32_LOAD), "win32_load"},
     {ERR_FUNC(DSO_F_WIN32_MERGER), "win32_merger"},
     {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "win32_name_converter"},
+    {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "win32_pathbyaddr"},
     {ERR_FUNC(DSO_F_WIN32_SPLITTER), "win32_splitter"},
     {ERR_FUNC(DSO_F_WIN32_UNLOAD), "win32_unload"},
     {0, NULL}
index bea8776d71b83bc2afd8b559ea1a464ddf9c2fbb..2dac20082ceecdddacc8fd89567166917156014e 100644 (file)
@@ -304,6 +304,18 @@ char *DSO_convert_filename(DSO *dso, const char *filename)
     return (result);
 }
 
+int DSO_pathbyaddr(void *addr, char *path, int sz)
+{
+    DSO_METHOD *meth = default_DSO_meth;
+    if (meth == NULL)
+        meth = DSO_METHOD_openssl();
+    if (meth->pathbyaddr == NULL) {
+        DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
+        return -1;
+    }
+    return (*meth->pathbyaddr) (addr, path, sz);
+}
+
 void *DSO_global_lookup(const char *name)
 {
     DSO_METHOD *meth = default_DSO_meth;
index 19767871fa6f1430cdc2fb1bb339d3996577a1af..fbfad0544a73d1e63c1f1b352388d3d95f2cce69 100644 (file)
@@ -99,6 +99,8 @@ struct dso_meth_st {
     /* [De]Initialisation handlers. */
     int (*init) (DSO *dso);
     int (*finish) (DSO *dso);
+    /* Return pathname of the module containing location */
+    int (*pathbyaddr) (void *addr, char *path, int sz);
     /* Perform global symbol lookup, i.e. among *all* modules */
     void *(*globallookup) (const char *symname);
 };
index 2e0d84cb538aa055633346d4776e2de2834c425c..e3c157bf57926b332e6b9ba5489163b6fe216b08 100644 (file)
@@ -50,7 +50,9 @@ static DSO_METHOD dso_meth_vms = {
     vms_name_converter,
     vms_merger,
     NULL,                       /* init */
-    NULL                        /* finish */
+    NULL,                       /* finish */
+    NULL,                       /* pathbyaddr */
+    NULL                        /* globallookup */
 };
 
 /*
index 4ac6e7176d726952079e54f5d7db30ce52167f3a..4a4c34abb65817eeb30524153669cbbbf473b99a 100644 (file)
@@ -77,6 +77,7 @@ static DSO_METHOD dso_meth_win32 = {
     win32_merger,
     NULL,                       /* init */
     NULL,                       /* finish */
+    NULL,                       /* pathbyaddr */
     win32_globallookup
 };
 
index 79d98f4785390c48c1391a44235f773cfbaf09ed..6f50f005a997867aec972105e71dfbcb4ca5440d 100644 (file)
@@ -130,6 +130,17 @@ DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
  */
 DSO_METHOD *DSO_METHOD_openssl(void);
 
+/*
+ * This function writes null-terminated pathname of DSO module containing
+ * 'addr' into 'sz' large caller-provided 'path' and returns the number of
+ * characters [including trailing zero] written to it. If 'sz' is 0 or
+ * negative, 'path' is ignored and required amount of charachers [including
+ * trailing zero] to accommodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero return value
+ * denotes error.
+ */
+int DSO_pathbyaddr(void *addr, char *path, int 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
@@ -171,6 +182,7 @@ int ERR_load_DSO_strings(void);
 # define DSO_F_DSO_LOAD                                   112
 # define DSO_F_DSO_MERGE                                  132
 # define DSO_F_DSO_NEW_METHOD                             113
+# define DSO_F_DSO_PATHBYADDR                             105
 # define DSO_F_DSO_SET_FILENAME                           129
 # define DSO_F_DSO_UP_REF                                 114
 # define DSO_F_VMS_BIND_SYM                               115
@@ -183,6 +195,7 @@ int ERR_load_DSO_strings(void);
 # define DSO_F_WIN32_LOAD                                 120
 # define DSO_F_WIN32_MERGER                               134
 # define DSO_F_WIN32_NAME_CONVERTER                       125
+# define DSO_F_WIN32_PATHBYADDR                           109
 # define DSO_F_WIN32_SPLITTER                             136
 # define DSO_F_WIN32_UNLOAD                               121
 
index e04580c4859d9fa1f4c9dd69ca92a474dadc119b..3645c1ad1c74936584a3749df2c92c92117d14d2 100644 (file)
@@ -4216,3 +4216,4 @@ BIO_meth_get_read_ex                    4166      1_1_1   EXIST::FUNCTION:
 BIO_write_ex                            4167   1_1_1   EXIST::FUNCTION:
 BIO_meth_get_write_ex                   4168   1_1_1   EXIST::FUNCTION:
 BIO_meth_set_write_ex                   4169   1_1_1   EXIST::FUNCTION:
+DSO_pathbyaddr                          4170   1_1_0c  EXIST::FUNCTION: