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@openssl.org>
This commit is contained in:
parent
a93e0e78db
commit
7d37818dac
4 changed files with 37 additions and 7 deletions
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue