DRBG: fix reseeding via RAND_add()/RAND_seed() with large input
[openssl.git] / crypto / dso / dso_dl.c
index bc29fb23e03955b12a12a2e5f09318f06d02395d..290d73cf3575ba2081c7db91dd7c34ddc030e12a 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
 };
 
@@ -81,13 +83,13 @@ static int dl_load(DSO *dso)
      * (it also serves as the indicator that we are currently loaded).
      */
     dso->loaded_filename = filename;
-    return (1);
+    return 1;
  err:
     /* Cleanup! */
     OPENSSL_free(filename);
     if (ptr != NULL)
         shl_unload(ptr);
-    return (0);
+    return 0;
 }
 
 static int dl_unload(DSO *dso)
@@ -95,10 +97,10 @@ static int dl_unload(DSO *dso)
     shl_t ptr;
     if (dso == NULL) {
         DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
-        return (0);
+        return 0;
     }
     if (sk_num(dso->meth_data) < 1)
-        return (1);
+        return 1;
     /* Is this statement legal? */
     ptr = (shl_t) sk_pop(dso->meth_data);
     if (ptr == NULL) {
@@ -107,10 +109,10 @@ static int dl_unload(DSO *dso)
          * Should push the value back onto the stack in case of a retry.
          */
         sk_push(dso->meth_data, (char *)ptr);
-        return (0);
+        return 0;
     }
     shl_unload(ptr);
-    return (1);
+    return 1;
 }
 
 static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
@@ -120,25 +122,25 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
 
     if ((dso == NULL) || (symname == NULL)) {
         DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
-        return (NULL);
+        return NULL;
     }
     if (sk_num(dso->meth_data) < 1) {
         DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR);
-        return (NULL);
+        return NULL;
     }
     ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
     if (ptr == NULL) {
         DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE);
-        return (NULL);
+        return NULL;
     }
     if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
         char errbuf[160];
         DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE);
         if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
             ERR_add_error_data(4, "symname(", symname, "): ", errbuf);
-        return (NULL);
+        return NULL;
     }
-    return ((DSO_FUNC_TYPE)sym);
+    return (DSO_FUNC_TYPE)sym;
 }
 
 static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
@@ -147,7 +149,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
 
     if (!filespec1 && !filespec2) {
         DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER);
-        return (NULL);
+        return NULL;
     }
     /*
      * If the first file specification is a rooted path, it rules. same goes
@@ -157,7 +159,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
         merged = OPENSSL_strdup(filespec1);
         if (merged == NULL) {
             DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-            return (NULL);
+            return NULL;
         }
     }
     /*
@@ -167,7 +169,7 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
         merged = OPENSSL_strdup(filespec2);
         if (merged == NULL) {
             DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-            return (NULL);
+            return NULL;
         }
     } else
         /*
@@ -190,13 +192,13 @@ static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
         merged = OPENSSL_malloc(len + 2);
         if (merged == NULL) {
             DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
-            return (NULL);
+            return NULL;
         }
         strcpy(merged, filespec2);
         merged[spec2len] = '/';
         strcpy(&merged[spec2len + 1], filespec1);
     }
-    return (merged);
+    return merged;
 }
 
 /*
@@ -223,7 +225,7 @@ static char *dl_name_converter(DSO *dso, const char *filename)
     translated = OPENSSL_malloc(rsize);
     if (translated == NULL) {
         DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
-        return (NULL);
+        return NULL;
     }
     if (transform) {
         if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
@@ -232,7 +234,39 @@ static char *dl_name_converter(DSO *dso, const char *filename)
             sprintf(translated, "%s%s", filename, DSO_EXTENSION);
     } else
         sprintf(translated, "%s", filename);
-    return (translated);
+    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)