diff --git a/libkmipclient/ttlv.c b/libkmipclient/ttlv.c index 7d1dacde..42b72e0b 100644 --- a/libkmipclient/ttlv.c +++ b/libkmipclient/ttlv.c @@ -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; } diff --git a/libkmipclient/utils.c b/libkmipclient/utils.c index fcbeeec7..30b58aa5 100644 --- a/libkmipclient/utils.c +++ b/libkmipclient/utils.c @@ -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)