summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-01-04 15:22:13 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-01-04 15:24:57 +0100
commit49be4f7b82eba2363bb8d4090950dad976a77a3a (patch)
tree4b4dc9d143b89529cdf5aef2ac55f4f02617d59d
parent65ee81db857d3b44cec76aa94361abe5427430d8 (diff)
downloadgnutls-tmp-fix-openpgp-issues.tar.gz
opencdk: added error checking in the stream reading functionstmp-fix-openpgp-issues
This addresses an out of memory error. Issue found using oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=337 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/opencdk/read-packet.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c
index b999e1c000..fa4c604d81 100644
--- a/lib/opencdk/read-packet.c
+++ b/lib/opencdk/read-packet.c
@@ -42,6 +42,7 @@ static int
stream_read(cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread)
{
int res = cdk_stream_read(s, buf, buflen);
+
if (res > 0) {
*r_nread = res;
return 0;
@@ -55,13 +56,13 @@ stream_read(cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread)
static u32 read_32(cdk_stream_t s)
{
byte buf[4];
- size_t nread;
+ size_t nread = 0;
assert(s != NULL);
stream_read(s, buf, 4, &nread);
if (nread != 4)
- return (u32) - 1;
+ return (u32) -1;
return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
}
@@ -70,7 +71,7 @@ static u32 read_32(cdk_stream_t s)
static u16 read_16(cdk_stream_t s)
{
byte buf[2];
- size_t nread;
+ size_t nread = 0;
assert(s != NULL);
@@ -572,7 +573,7 @@ read_user_id(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t user_id)
static cdk_error_t
read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
{
- byte c, c1;
+ int c, c1;
size_t size, nread, n;
cdk_subpkt_t node;
cdk_error_t rc;
@@ -587,11 +588,18 @@ read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
*r_nbytes = 0;
c = cdk_stream_getc(inp);
n++;
+
if (c == 255) {
size = read_32(inp);
+ if (size == (u32)-1)
+ return CDK_Inv_Packet;
+
n += 4;
} else if (c >= 192 && c < 255) {
c1 = cdk_stream_getc(inp);
+ if (c1 == EOF)
+ return CDK_Inv_Packet;
+
n++;
if (c1 == 0)
return 0;
@@ -858,17 +866,29 @@ static void
read_old_length(cdk_stream_t inp, int ctb, size_t * r_len, size_t * r_size)
{
int llen = ctb & 0x03;
+ int c;
if (llen == 0) {
- *r_len = cdk_stream_getc(inp);
+ c = cdk_stream_getc(inp);
+ if (c == EOF)
+ goto fail;
+
+ *r_len = c;
(*r_size)++;
} else if (llen == 1) {
*r_len = read_16(inp);
+ if (*r_len == (u16)-1)
+ goto fail;
(*r_size) += 2;
} else if (llen == 2) {
*r_len = read_32(inp);
+ if (*r_len == (u32)-1) {
+ goto fail;
+ }
+
(*r_size) += 4;
} else {
+ fail:
*r_len = 0;
*r_size = 0;
}
@@ -883,15 +903,25 @@ read_new_length(cdk_stream_t inp,
int c, c1;
c = cdk_stream_getc(inp);
+ if (c == EOF)
+ return;
+
(*r_size)++;
if (c < 192)
*r_len = c;
else if (c >= 192 && c <= 223) {
c1 = cdk_stream_getc(inp);
+ if (c1 == EOF)
+ return;
+
(*r_size)++;
*r_len = ((c - 192) << 8) + c1 + 192;
} else if (c == 255) {
*r_len = read_32(inp);
+ if (*r_len == (u32)-1) {
+ return;
+ }
+
(*r_size) += 4;
} else {
*r_len = 1 << (c & 0x1f);