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)
|
static int kmip_node_get_length(struct kmip_node *node, size_t *length)
|
||||||
{
|
{
|
||||||
struct kmip_node *element;
|
struct kmip_node *element;
|
||||||
size_t len;
|
size_t len, prev_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (node == NULL || length == NULL)
|
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)
|
if (rc != 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
prev_len = *length;
|
||||||
*length += KMIP_TTLV_HEADER_LENGTH + len;
|
*length += KMIP_TTLV_HEADER_LENGTH + len;
|
||||||
if ((len % KMIP_TTLV_BLOCK_LENGTH) != 0)
|
if ((len % KMIP_TTLV_BLOCK_LENGTH) != 0)
|
||||||
*length += KMIP_TTLV_BLOCK_LENGTH -
|
*length += KMIP_TTLV_BLOCK_LENGTH -
|
||||||
(len % KMIP_TTLV_BLOCK_LENGTH);
|
(len % KMIP_TTLV_BLOCK_LENGTH);
|
||||||
|
if (*length < prev_len)
|
||||||
|
return -EOVERFLOW;
|
||||||
|
|
||||||
element = element->next;
|
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)
|
int kmip_format_bignum(const BIGNUM *bn, bool prefix, char **str)
|
||||||
{
|
{
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
uint32_t len;
|
uint32_t len, prev_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
len = kmip_encode_bignum_length(bn);
|
len = kmip_encode_bignum_length(bn);
|
||||||
/* BIG INTEGERS must be a multiple of 8 bytes long */
|
/* 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 -
|
||||||
(len % KMIP_BIG_INTEGER_BLOCK_LENGTH);
|
(len % KMIP_BIG_INTEGER_BLOCK_LENGTH);
|
||||||
|
if (len < prev_len)
|
||||||
|
return -EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
buf = malloc(len);
|
buf = malloc(len);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
@@ -407,10 +411,10 @@ int kmip_parse_mask(enum kmip_tag tag, const char *str, char separator,
|
|||||||
return rc;
|
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)
|
const char *append)
|
||||||
{
|
{
|
||||||
int new_len;
|
size_t new_len;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
if (str == NULL || str_len == NULL)
|
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)
|
if (append != NULL)
|
||||||
new_len += strlen(append);
|
new_len += strlen(append);
|
||||||
|
|
||||||
|
if (new_len < *str_len)
|
||||||
|
return -EOVERFLOW;
|
||||||
|
|
||||||
tmp = realloc(*str, new_len);
|
tmp = realloc(*str, new_len);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -451,8 +458,9 @@ int kmip_format_mask(enum kmip_tag tag, int32_t value, char separator,
|
|||||||
char **str)
|
char **str)
|
||||||
{
|
{
|
||||||
const struct kmip_enum *info;
|
const struct kmip_enum *info;
|
||||||
int rc = 0, i, s_len = 0;
|
|
||||||
char *s = NULL, *tmp;
|
char *s = NULL, *tmp;
|
||||||
|
size_t s_len = 0;
|
||||||
|
int rc = 0, i;
|
||||||
|
|
||||||
info = kmip_enum_info_by_tag(tag);
|
info = kmip_enum_info_by_tag(tag);
|
||||||
if (info == NULL || value == 0)
|
if (info == NULL || value == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user