pull up r22175 from trunk
authorTom Yu <tlyu@mit.edu>
Wed, 15 Apr 2009 20:07:32 +0000 (20:07 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 15 Apr 2009 20:07:32 +0000 (20:07 +0000)
 ------------------------------------------------------------------------
 r22175 | tlyu | 2009-04-07 17:22:20 -0400 (Tue, 07 Apr 2009) | 14 lines
 Changed paths:
    M /trunk/src/lib/krb5/asn.1/asn1buf.c

 ticket: 6444
 subject: CVE-2009-0847 asn1buf_imbed incorrect length validation
 tags: pullup
 target_version: 1.7

 asn1buf_imbed() can perform pointer arithmetic that causes the "bound"
 pointer of the subbuffer to be less than the "next" pointer.  This can
 lead to malloc() failure or crash.

 In asn1buf_imbed(), check the length before doing arithmetic to set
 subbuf->bound.  In asn1buf_remove_octetstring() and
 asn1buf_remove_charstring(), check for invalid buffer pointers before
 executing an unsigned length check against a (casted to size_t)
 negative number.

ticket: 6444
version_fixed: 1.7

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-7@22249 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/asn.1/asn1buf.c

index 5793a0303ab3b21c33120a96b4c1a16416f2064c..8985140d46db84f16e8d4300939fa1b0a7e30eeb 100644 (file)
@@ -92,11 +92,11 @@ asn1_error_code asn1buf_wrap_data(asn1buf *buf, const krb5_data *code)
 
 asn1_error_code asn1buf_imbed(asn1buf *subbuf, const asn1buf *buf, const unsigned int length, const int indef)
 {
+    if (buf->next > buf->bound + 1) return ASN1_OVERRUN;
     subbuf->base = subbuf->next = buf->next;
     if (!indef) {
+        if (length > (size_t)(buf->bound + 1 - buf->next)) return ASN1_OVERRUN;
         subbuf->bound = subbuf->base + length - 1;
-        if (subbuf->bound > buf->bound)
-            return ASN1_OVERRUN;
     } else /* constructed indefinite */
         subbuf->bound = buf->bound;
     return 0;
@@ -205,6 +205,7 @@ asn1_error_code asn1buf_remove_octetstring(asn1buf *buf, const unsigned int len,
 {
     unsigned int i;
 
+    if (buf->next > buf->bound + 1) return ASN1_OVERRUN;
     if (len > (size_t)(buf->bound + 1 - buf->next)) return ASN1_OVERRUN;
     if (len == 0) {
         *s = 0;
@@ -223,6 +224,7 @@ asn1_error_code asn1buf_remove_charstring(asn1buf *buf, const unsigned int len,
 {
     unsigned int i;
 
+    if (buf->next > buf->bound + 1) return ASN1_OVERRUN;
     if (len > (size_t)(buf->bound + 1 - buf->next)) return ASN1_OVERRUN;
     if (len == 0) {
         *s = 0;