openssl_strerror_r: Fix handling of GNU strerror_r
GNU strerror_r may return either a pointer to a string that the function stores in buf, or a pointer to some (immutable) static string in which case buf is unused. In such a case we need to set buf manually. Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8371)
This commit is contained in:
parent
68ad17e874
commit
e3b35d2b29
1 changed files with 22 additions and 3 deletions
|
@ -223,7 +223,26 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
|
|||
#if defined(_MSC_VER) && _MSC_VER>=1400
|
||||
return !strerror_s(buf, buflen, errnum);
|
||||
#elif defined(_GNU_SOURCE)
|
||||
return strerror_r(errnum, buf, buflen) != NULL;
|
||||
char *err;
|
||||
|
||||
/*
|
||||
* GNU strerror_r may not actually set buf.
|
||||
* It can return a pointer to some (immutable) static string in which case
|
||||
* buf is left unused.
|
||||
*/
|
||||
err = strerror_r(errnum, buf, buflen);
|
||||
if (err == NULL)
|
||||
return 0;
|
||||
/*
|
||||
* If err is statically allocated, err != buf and we need to copy the data.
|
||||
* If err points somewhere inside buf, OPENSSL_strlcpy can handle this,
|
||||
* since src and dest are not annotated with __restrict and the function
|
||||
* reads src byte for byte and writes to dest.
|
||||
* If err == buf we do not have to copy anything.
|
||||
*/
|
||||
if (err != buf)
|
||||
OPENSSL_strlcpy(buf, err, buflen);
|
||||
return 1;
|
||||
#elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
|
||||
(defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
|
||||
/*
|
||||
|
@ -234,6 +253,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
|
|||
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;
|
||||
|
@ -241,8 +261,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
|
|||
/* Can this ever happen? */
|
||||
if (err == NULL)
|
||||
return 0;
|
||||
strncpy(buf, err, buflen - 1);
|
||||
buf[buflen - 1] = '\0';
|
||||
OPENSSL_strlcpy(buf, err, buflen);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue