From: Pierre Chifflier Date: Sat, 18 Apr 2015 12:24:45 +0000 (+0200) Subject: Fix possible wrap in uint32_t addition in DER parser X-Git-Tag: suricata-2.1beta4~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fa73a0bb8f312fd0a95cc70f6b3ee4e4997bdba7;p=thirdparty%2Fsuricata.git Fix possible wrap in uint32_t addition in DER parser Signed-off-by: Pierre Chifflier --- diff --git a/src/util-decode-der.c b/src/util-decode-der.c index 3e7324be9c..1687668bd5 100644 --- a/src/util-decode-der.c +++ b/src/util-decode-der.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 ANSSI + * Copyright (C) 2011-2015 ANSSI * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -466,8 +466,11 @@ static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_ return NULL; } } - if (length > max_size) + if (length == UINT32_MAX || length > max_size) { + if (errcode) + *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; return NULL; + } a = Asn1GenericNew(); if (a == NULL) @@ -508,8 +511,11 @@ static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint3 return NULL; } } - if (length > max_size) + if (length == UINT32_MAX || length > max_size) { + if (errcode) + *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; return NULL; + } a = Asn1GenericNew(); if (a == NULL) @@ -561,8 +567,11 @@ static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, u return NULL; } } - if (length > max_size) + if (length == UINT32_MAX || length > max_size) { + if (errcode) + *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; return NULL; + } a = Asn1GenericNew(); if (a == NULL) @@ -612,7 +621,9 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t } } node->length = d_length + (d_ptr - buffer); - if (node->length > max_size) { + if (node->length > max_size || node->length < d_length /* wrap */) { + if (errcode) + *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; SCFree(node); return NULL; } @@ -626,6 +637,10 @@ static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode); if (child == NULL) { + if (errcode && *errcode != 0) { + DerFree(node); + return NULL; + } break; } @@ -676,7 +691,7 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_ } node->length = d_length + (d_ptr - buffer); - if (node->length > max_size) { + if (node->length > max_size || node->length < d_length /* wrap */) { if (errcode) *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; SCFree(node); @@ -687,6 +702,10 @@ static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_ el_max_size = max_size - (d_ptr-buffer); child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode); + if (child == NULL) { + DerFree(node); + return NULL; + } node->data = child;