[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Mon May 23 22:27:38 UTC 2016


The branch master has been updated
       via  7d37818dacc87c21dfc9d2def5014657344875e3 (commit)
      from  a93e0e78db78e03bdcd29acf9bbc8a812ee50cb6 (commit)


- Log -----------------------------------------------------------------
commit 7d37818dacc87c21dfc9d2def5014657344875e3
Author: Matt Caswell <matt at openssl.org>
Date:   Mon May 23 13:52:29 2016 +0100

    Use strerror_r()/strerror_s() instead of strerror() where possible
    
    The function strerror() is not thread safe. We should use strerror_r()
    where possible, or strerror_s() on Windows.
    
    RT#2267
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 crypto/dso/dso_dl.c                |  8 ++++++--
 crypto/err/err.c                   |  6 +-----
 crypto/include/internal/cryptlib.h |  2 ++
 crypto/o_str.c                     | 28 ++++++++++++++++++++++++++++
 4 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/crypto/dso/dso_dl.c b/crypto/dso/dso_dl.c
index f5c51bf..bc29fb2 100644
--- a/crypto/dso/dso_dl.c
+++ b/crypto/dso/dso_dl.c
@@ -66,8 +66,10 @@ static int dl_load(DSO *dso)
                    (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 :
                     DYNAMIC_PATH), 0L);
     if (ptr == NULL) {
+        char errbuf[160];
         DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED);
-        ERR_add_error_data(4, "filename(", filename, "): ", strerror(errno));
+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+            ERR_add_error_data(4, "filename(", filename, "): ", errbuf);
         goto err;
     }
     if (!sk_push(dso->meth_data, (char *)ptr)) {
@@ -130,8 +132,10 @@ static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
         return (NULL);
     }
     if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
+        char errbuf[160];
         DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE);
-        ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno));
+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+            ERR_add_error_data(4, "symname(", symname, "): ", errbuf);
         return (NULL);
     }
     return ((DSO_FUNC_TYPE)sym);
diff --git a/crypto/err/err.c b/crypto/err/err.c
index 1035e4c..9b679d9 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -220,12 +220,8 @@ static void build_SYS_str_reasons(void)
         str->error = (unsigned long)i;
         if (str->string == NULL) {
             char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
-            char *src = strerror(i);
-            if (src != NULL) {
-                strncpy(*dest, src, sizeof(*dest));
-                (*dest)[sizeof(*dest) - 1] = '\0';
+            if (openssl_strerror_r(i, *dest, sizeof(*dest)))
                 str->string = *dest;
-            }
         }
         if (str->string == NULL)
             str->string = "unknown";
diff --git a/crypto/include/internal/cryptlib.h b/crypto/include/internal/cryptlib.h
index 1327dca..f2377d1 100644
--- a/crypto/include/internal/cryptlib.h
+++ b/crypto/include/internal/cryptlib.h
@@ -67,6 +67,8 @@ void OPENSSL_showfatal(const char *fmta, ...);
 extern int OPENSSL_NONPIC_relocated;
 void crypto_cleanup_all_ex_data_int(void);
 
+int openssl_strerror_r(int errnum, char *buf, size_t buflen);
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/crypto/o_str.c b/crypto/o_str.c
index 0ee2c86..98eb163 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -258,3 +258,31 @@ char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len)
 
     return tmp;
 }
+
+int openssl_strerror_r(int errnum, char *buf, size_t buflen)
+{
+#if defined(OPENSSL_SYS_WINDOWS)
+    if (strerror_s(buf, buflen, errnum) == EINVAL)
+        return 0;
+    return 1;
+#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
+    /*
+     * We can use "real" strerror_r. The OpenSSL version differs in that it
+     * gives 1 on success and 0 on failure for consistency with other OpenSSL
+     * functions. Real strerror_r does it the other way around
+     */
+    return !strerror_r(errnum, buf, buflen);
+#else
+    char *err;
+    /* Fall back to non-thread safe strerror()...its all we can do */
+    if (buflen < 2)
+        return 0;
+    err = strerror(errnum);
+    /* Can this ever happen? */
+    if (err == NULL)
+        return 0;
+    strncpy(buf, err, buflen - 1);
+    buf[buflen - 1] = '\0';
+    return 1;
+#endif
+}


More information about the openssl-commits mailing list