diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-01-04 14:42:03 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-01-06 08:04:15 +0100 |
commit | f55213117932fc96e2de22adc367110c6fd8fcff (patch) | |
tree | 0c853acf436928f4a87185dc19702663bc5677e5 | |
parent | 21070c34368744d660467c6a9e2248cf3914ac1c (diff) | |
download | gnutls-f55213117932fc96e2de22adc367110c6fd8fcff.tar.gz |
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 <nmav@redhat.com>
-rw-r--r-- | lib/opencdk/read-packet.c | 40 |
1 files changed, 29 insertions, 11 deletions
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; } |