Make BUF_strndup() read-safe on arbitrary inputs
BUF_strndup was calling strlen through BUF_strlcpy, and ended up reading past the input if the input was not a C string. Make it explicitly part of BUF_strndup's contract to never read more than |siz| input bytes. This augments the standard strndup contract to be safer. The commit also adds a check for siz overflow and some brief documentation for BUF_strndup(). Reviewed-by: Matt Caswell <matt@openssl.org> (cherry picked from commit 110f7b37de9feecfb64950601cc7cec77cf6130b) (cherry picked from commit f61216ba9d17430fb5eb3e2b202a209960b9d51b)
This commit is contained in:
parent
9d1fcbebbc
commit
6905187488
@ -58,6 +58,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <limits.h>
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
char *BUF_strdup(const char *str)
|
||||
@ -74,12 +75,18 @@ char *BUF_strndup(const char *str, size_t siz)
|
||||
if (str == NULL)
|
||||
return (NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,13 @@ void BUF_MEM_free(BUF_MEM *a);
|
||||
int BUF_MEM_grow(BUF_MEM *str, size_t len);
|
||||
int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
|
||||
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, const unsigned char *in, size_t siz);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user