From: Stef Walter Date: Wed, 7 Nov 2012 20:27:24 +0000 (+0100) Subject: egg-asn1x: Fix corner case where long DER length overflows X-Git-Tag: upstream/3.7.5~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0bf0aeb6688c7ff3795f42f5e1a5bee27e52bf6;p=platform%2Fupstream%2Fgcr.git egg-asn1x: Fix corner case where long DER length overflows * Better detection of the case where TLV length overflows the size of an int. --- diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c index 105540f..c35cf1e 100644 --- a/egg/egg-asn1x.c +++ b/egg/egg-asn1x.c @@ -669,6 +669,7 @@ atlv_parse_cls_tag (const guchar *at, { gint punt, ris, last; gint n_data; + guchar val; g_assert (end >= at); g_assert (cls != NULL); @@ -690,23 +691,27 @@ atlv_parse_cls_tag (const guchar *at, } else { punt = 1; ris = 0; - while (punt <= n_data && at[punt] & 128) { - int last = ris; - ris = ris * 128 + (at[punt++] & 0x7F); + while (punt <= n_data) { + val = at[punt++]; + last = ris; + ris = ris * 128; /* wrapper around, and no bignums... */ if (ris < last) return FALSE; - } - if (punt >= n_data) - return FALSE; + last = ris; + ris += (val & 0x7F); + + /* wrapper around, and no bignums... */ + if (ris < last) + return FALSE; - last = ris; - ris = ris * 128 + (at[punt++] & 0x7F); + if ((val & 0x7F) == val) + break; + } - /* wrapper around, and no bignums... */ - if (ris < last) + if (punt >= n_data) return FALSE; *off = punt; @@ -753,7 +758,14 @@ atlv_parse_length (const guchar *at, ans = 0; while (punt <= k && punt < n_data) { last = ans; - ans = ans * 256 + at[punt++]; + ans = ans * 256; + + /* we wrapped around, no bignum support... */ + if (ans < last) + return -2; + + last = ans; + ans += at[punt++]; /* we wrapped around, no bignum support... */ if (ans < last)