diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-01-04 14:42:03 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-01-09 07:36:28 +0100 |
commit | 6231a4a087f9fdbd5f5f274e80c7a71e3e45b9c8 (patch) | |
tree | bbadc95ba6989f21bc7aef04dc6482cfe493a3cb | |
parent | affb3d659681af1dca04448e25f27c7e22eda0c7 (diff) | |
download | gnutls-6231a4a087f9fdbd5f5f274e80c7a71e3e45b9c8.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 8cba25c471..e8ff24ffe6 100644 --- a/lib/opencdk/read-packet.c +++ b/lib/opencdk/read-packet.c @@ -483,46 +483,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; } |