Commit 7d37818d authored by Matt Caswell's avatar Matt Caswell
Browse files

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: default avatarRichard Levitte <levitte@openssl.org>
parent a93e0e78
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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);
+1 −5
Original line number Diff line number Diff line
@@ -220,13 +220,9 @@ 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";
    }
+2 −0
Original line number Diff line number Diff line
@@ -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
+28 −0
Original line number Diff line number Diff line
@@ -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
}