From d68398e122cfd6c3fc35ab54b3cbeed38ae1e6a9 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Wed, 8 Apr 2009 01:22:57 +0000 Subject: [PATCH] CVE-2009-0847 (1.6.x) asn1buf_imbed incorrect length validatin pull up rxxxx from trunk 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: 6447 tags: pullup target_version: 1.6.4 version_fixed: 1.6.4 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@22180 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/asn.1/asn1buf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index 8baac2424..587cccc21 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -78,11 +78,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; @@ -200,6 +200,7 @@ asn1_error_code asn1buf_remove_octetstring(asn1buf *buf, const unsigned int len, { int i; + if (buf->next > buf->bound + 1) return ASN1_OVERRUN; if (len > buf->bound + 1 - buf->next) return ASN1_OVERRUN; if (len == 0) { *s = 0; @@ -218,6 +219,7 @@ asn1_error_code asn1buf_remove_charstring(asn1buf *buf, const unsigned int len, { int i; + if (buf->next > buf->bound + 1) return ASN1_OVERRUN; if (len > buf->bound + 1 - buf->next) return ASN1_OVERRUN; if (len == 0) { *s = 0; -- 2.26.2