mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
libkmipclient: Detect possible length overflow situations
A deeply nested or pathologically large KMIP node tree crafted by a malicious server can wrap the length calculation around to a small value. Detect this and return an error in this case. Assisted-by: IBM Bob:2.0.0 Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Finn Callies <fcallies@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
66581d57f3
commit
7fd2421a2c
@@ -282,7 +282,7 @@ out:
|
||||
static int kmip_node_get_length(struct kmip_node *node, size_t *length)
|
||||
{
|
||||
struct kmip_node *element;
|
||||
size_t len;
|
||||
size_t len, prev_len;
|
||||
int rc;
|
||||
|
||||
if (node == NULL || length == NULL)
|
||||
@@ -297,10 +297,13 @@ static int kmip_node_get_length(struct kmip_node *node, size_t *length)
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
prev_len = *length;
|
||||
*length += KMIP_TTLV_HEADER_LENGTH + len;
|
||||
if ((len % KMIP_TTLV_BLOCK_LENGTH) != 0)
|
||||
*length += KMIP_TTLV_BLOCK_LENGTH -
|
||||
(len % KMIP_TTLV_BLOCK_LENGTH);
|
||||
if (*length < prev_len)
|
||||
return -EOVERFLOW;
|
||||
|
||||
element = element->next;
|
||||
}
|
||||
|
||||
@@ -225,14 +225,18 @@ int kmip_parse_bignum(const char *str, bool has_prefix, BIGNUM **bn)
|
||||
int kmip_format_bignum(const BIGNUM *bn, bool prefix, char **str)
|
||||
{
|
||||
unsigned char *buf;
|
||||
uint32_t len;
|
||||
uint32_t len, prev_len;
|
||||
int rc;
|
||||
|
||||
len = kmip_encode_bignum_length(bn);
|
||||
/* BIG INTEGERS must be a multiple of 8 bytes long */
|
||||
if ((len % KMIP_BIG_INTEGER_BLOCK_LENGTH) != 0)
|
||||
if ((len % KMIP_BIG_INTEGER_BLOCK_LENGTH) != 0) {
|
||||
prev_len = len;
|
||||
len += KMIP_BIG_INTEGER_BLOCK_LENGTH -
|
||||
(len % KMIP_BIG_INTEGER_BLOCK_LENGTH);
|
||||
if (len < prev_len)
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
buf = malloc(len);
|
||||
if (buf == NULL)
|
||||
@@ -407,10 +411,10 @@ int kmip_parse_mask(enum kmip_tag tag, const char *str, char separator,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int kmip_append_string(char **str, int *str_len, char separator,
|
||||
static int kmip_append_string(char **str, size_t *str_len, char separator,
|
||||
const char *append)
|
||||
{
|
||||
int new_len;
|
||||
size_t new_len;
|
||||
char *tmp;
|
||||
|
||||
if (str == NULL || str_len == NULL)
|
||||
@@ -427,6 +431,9 @@ static int kmip_append_string(char **str, int *str_len, char separator,
|
||||
if (append != NULL)
|
||||
new_len += strlen(append);
|
||||
|
||||
if (new_len < *str_len)
|
||||
return -EOVERFLOW;
|
||||
|
||||
tmp = realloc(*str, new_len);
|
||||
if (tmp == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -451,8 +458,9 @@ int kmip_format_mask(enum kmip_tag tag, int32_t value, char separator,
|
||||
char **str)
|
||||
{
|
||||
const struct kmip_enum *info;
|
||||
int rc = 0, i, s_len = 0;
|
||||
char *s = NULL, *tmp;
|
||||
size_t s_len = 0;
|
||||
int rc = 0, i;
|
||||
|
||||
info = kmip_enum_info_by_tag(tag);
|
||||
if (info == NULL || value == 0)
|
||||
|
||||
Reference in New Issue
Block a user