From: Nikos Mavrogiannopoulos Date: Wed, 4 Jan 2017 13:42:03 +0000 (+0100) Subject: opencdk: read_attribute: added more precise checks when reading stream X-Git-Tag: gnutls_3_6_0~1087 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=94fcf1645ea17223237aaf8d19132e004afddc1a;p=thirdparty%2Fgnutls.git opencdk: read_attribute: added more precise checks when reading stream That addresses heap read overflows found using oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=338 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=346 Signed-off-by: Nikos Mavrogiannopoulos --- diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c index cdb47007a6..b999e1c000 100644 --- a/lib/opencdk/read-packet.c +++ b/lib/opencdk/read-packet.c @@ -482,46 +482,64 @@ read_attribute(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t attr, return CDK_Out_Of_Core; rc = stream_read(inp, buf, pktlen, &nread); if (rc) { - cdk_free(buf); - return CDK_Inv_Packet; + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; } + p = buf; len = *p++; pktlen--; + if (len == 255) { + if (pktlen < 4) { + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; + } + len = _cdk_buftou32(p); p += 4; pktlen -= 4; } else if (len >= 192) { if (pktlen < 2) { - cdk_free(buf); - return CDK_Inv_Packet; + gnutls_assert(); + rc = CDK_Inv_Packet; + goto error; } + len = ((len - 192) << 8) + *p + 192; p++; pktlen--; } - if (*p != 1) { /* Currently only 1, meaning an image, is defined. */ - cdk_free(buf); - return CDK_Inv_Packet; + if (!len || *p != 1) { /* Currently only 1, meaning an image, is defined. */ + rc = CDK_Inv_Packet; + goto error; } + p++; len--; if (len >= pktlen) { - cdk_free(buf); - return CDK_Inv_Packet; + rc = CDK_Inv_Packet; + goto error; } + attr->attrib_img = cdk_calloc(1, len); if (!attr->attrib_img) { - cdk_free(buf); - return CDK_Out_Of_Core; + rc = CDK_Out_Of_Core; + goto error; } + attr->attrib_len = len; memcpy(attr->attrib_img, p, len); cdk_free(buf); return rc; + + error: + cdk_free(buf); + return rc; }