1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
From 6231a4a087f9fdbd5f5f274e80c7a71e3e45b9c8 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date: Wed, 4 Jan 2017 14:42:03 +0100
Subject: [PATCH 5/8] 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>
---
lib/opencdk/read-packet.c | 40 +++++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c
index 8cba25c47..e8ff24ffe 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;
}
--
2.11.0
|