diff --git a/crypto/buffer/buf_str.c b/crypto/buffer/buf_str.c index 1e8d7f6f10..bca363c28e 100644 --- a/crypto/buffer/buf_str.c +++ b/crypto/buffer/buf_str.c @@ -57,6 +57,7 @@ */ #include +#include #include "internal/cryptlib.h" #include @@ -85,12 +86,18 @@ char *BUF_strndup(const char *str, size_t siz) siz = BUF_strnlen(str, siz); + if (siz >= INT_MAX) + return (NULL); + ret = OPENSSL_malloc(siz + 1); if (ret == NULL) { BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE); return (NULL); } - BUF_strlcpy(ret, str, siz + 1); + + memcpy(ret, str, siz); + ret[siz] = '\0'; + return (ret); } diff --git a/include/openssl/buffer.h b/include/openssl/buffer.h index af30a90b86..61cff9ca36 100644 --- a/include/openssl/buffer.h +++ b/include/openssl/buffer.h @@ -90,7 +90,13 @@ size_t BUF_MEM_grow(BUF_MEM *str, size_t len); size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len); size_t BUF_strnlen(const char *str, size_t maxlen); char *BUF_strdup(const char *str); + +/* + * Returns a pointer to a new string which is a duplicate of the string |str|, + * but guarantees to never read past the first |siz| bytes of |str|. + */ char *BUF_strndup(const char *str, size_t siz); + void *BUF_memdup(const void *data, size_t siz); void BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);