Module Name: src
Committed By: riz
Date: Sat Apr 21 15:54:46 UTC 2012
Modified Files:
src/crypto/dist/openssl/crypto [netbsd-5-1]: mem.c
src/crypto/dist/openssl/crypto/asn1 [netbsd-5-1]: a_d2i_fp.c
src/crypto/dist/openssl/crypto/buffer [netbsd-5-1]: buffer.c
src/sys/miscfs/genfs [netbsd-5-1]: genfs_io.c
Log Message:
Pull up following revision(s) (requested by spz in ticket #1750):
crypto/dist/openssl/crypto/mem.c patch
crypto/dist/openssl/crypto/asn1/a_d2i_fp.c patch
crypto/dist/openssl/crypto/buffer/buffer.c patch
sys/miscfs/genfs/genfs_io.c patch
Address CVE-2012-2110.
[spz, ticket #1750]
To generate a diff of this commit:
cvs rdiff -u -r1.1.1.8 -r1.1.1.8.12.1 src/crypto/dist/openssl/crypto/mem.c
cvs rdiff -u -r1.1.1.3 -r1.1.1.3.34.1 \
src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c
cvs rdiff -u -r1.1.1.5 -r1.1.1.5.12.1 \
src/crypto/dist/openssl/crypto/buffer/buffer.c
cvs rdiff -u -r1.13.4.3 -r1.13.4.3.2.1 src/sys/miscfs/genfs/genfs_io.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/crypto/dist/openssl/crypto/mem.c
diff -u src/crypto/dist/openssl/crypto/mem.c:1.1.1.8 src/crypto/dist/openssl/crypto/mem.c:1.1.1.8.12.1
--- src/crypto/dist/openssl/crypto/mem.c:1.1.1.8 Fri May 9 21:34:14 2008
+++ src/crypto/dist/openssl/crypto/mem.c Sat Apr 21 15:54:46 2012
@@ -354,6 +354,10 @@ void *CRYPTO_realloc_clean(void *str, in
if (num <= 0) return NULL;
+ /* We don't support shrinking the buffer. Note the memcpy that copies
+ * |old_len| bytes to the new buffer, below. */
+ if (num < old_len) return NULL;
+
if (realloc_debug_func != NULL)
realloc_debug_func(str, NULL, num, file, line, 0);
ret=malloc_ex_func(num,file,line);
Index: src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c
diff -u src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c:1.1.1.3 src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c:1.1.1.3.34.1
--- src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c:1.1.1.3 Fri Nov 25 03:04:06 2005
+++ src/crypto/dist/openssl/crypto/asn1/a_d2i_fp.c Sat Apr 21 15:54:46 2012
@@ -57,6 +57,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1_mac.h>
@@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BU
BUF_MEM *b;
unsigned char *p;
int i;
- int ret=-1;
ASN1_const_CTX c;
- int want=HEADER_SIZE;
+ size_t want=HEADER_SIZE;
int eos=0;
-#if defined(__GNUC__) && defined(__ia64)
- /* pathetic compiler bug in all known versions as of Nov. 2002 */
- long off=0;
-#else
- int off=0;
-#endif
- int len=0;
+ size_t off=0;
+ size_t len=0;
b=BUF_MEM_new();
if (b == NULL)
@@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BU
{
want-=(len-off);
- if (!BUF_MEM_grow_clean(b,len+want))
+ if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err;
@@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BU
goto err;
}
if (i > 0)
+ {
+ if (len+i < len)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
+ goto err;
+ }
len+=i;
+ }
}
/* else data already loaded */
@@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BU
{
/* no data body so go round again */
eos++;
+ if (eos < 0)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
+ goto err;
+ }
want=HEADER_SIZE;
}
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
@@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BU
else
{
/* suck in c.slen bytes of data */
- want=(int)c.slen;
+ want=c.slen;
if (want > (len-off))
{
want-=(len-off);
+ if (want > INT_MAX /* BIO_read takes an int length */ ||
+ len+want < len)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
+ goto err;
+ }
if (!BUF_MEM_grow_clean(b,len+want))
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
@@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BU
ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
+ /* This can't overflow because
+ * |len+want| didn't overflow. */
len+=i;
- want -= i;
+ want-=i;
}
}
- off+=(int)c.slen;
+ if (off + c.slen < off)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
+ goto err;
+ }
+ off+=c.slen;
if (eos <= 0)
{
break;
@@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BU
}
}
+ if (off > INT_MAX)
+ {
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
+ goto err;
+ }
+
*pb = b;
return off;
err:
if (b != NULL) BUF_MEM_free(b);
- return(ret);
+ return -1;
}
Index: src/crypto/dist/openssl/crypto/buffer/buffer.c
diff -u src/crypto/dist/openssl/crypto/buffer/buffer.c:1.1.1.5 src/crypto/dist/openssl/crypto/buffer/buffer.c:1.1.1.5.12.1
--- src/crypto/dist/openssl/crypto/buffer/buffer.c:1.1.1.5 Fri May 9 21:34:22 2008
+++ src/crypto/dist/openssl/crypto/buffer/buffer.c Sat Apr 21 15:54:46 2012
@@ -60,6 +60,11 @@
#include "cryptlib.h"
#include <openssl/buffer.h>
+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
+ * function is applied in several functions in this file and this limit ensures
+ * that the result fits in an int. */
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+
BUF_MEM *BUF_MEM_new(void)
{
BUF_MEM *ret;
@@ -105,6 +110,12 @@ int BUF_MEM_grow(BUF_MEM *str, size_t le
str->length=len;
return(len);
}
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+ if (len > LIMIT_BEFORE_EXPANSION)
+ {
+ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
n=(len+3)/3*4;
if (str->data == NULL)
ret=OPENSSL_malloc(n);
@@ -142,6 +153,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, siz
str->length=len;
return(len);
}
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+ if (len > LIMIT_BEFORE_EXPANSION)
+ {
+ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
n=(len+3)/3*4;
if (str->data == NULL)
ret=OPENSSL_malloc(n);
Index: src/sys/miscfs/genfs/genfs_io.c
diff -u src/sys/miscfs/genfs/genfs_io.c:1.13.4.3 src/sys/miscfs/genfs/genfs_io.c:1.13.4.3.2.1
--- src/sys/miscfs/genfs/genfs_io.c:1.13.4.3 Tue Sep 7 19:33:35 2010
+++ src/sys/miscfs/genfs/genfs_io.c Sat Apr 21 15:54:46 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_io.c,v 1.13.4.3 2010/09/07 19:33:35 bouyer Exp $ */
+/* $NetBSD: genfs_io.c,v 1.13.4.3.2.1 2012/04/21 15:54:46 riz Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.13.4.3 2010/09/07 19:33:35 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.13.4.3.2.1 2012/04/21 15:54:46 riz Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -802,7 +802,19 @@ genfs_do_putpages(struct vnode *vp, off_
KASSERT(origflags & (PGO_CLEANIT|PGO_FREE|PGO_DEACTIVATE));
KASSERT((startoff & PAGE_MASK) == 0 && (endoff & PAGE_MASK) == 0);
- KASSERT(startoff < endoff || endoff == 0);
+// KASSERT(startoff < endoff || endoff == 0);
+
+// replacement for the previous KASSERT to get debug output, by rmind
+ if (!(startoff < endoff || endoff == 0)) {
+ proc_t *p = curproc;
+ mutex_exit(slock);
+ printf("genfs_do_putpages: startoff 0x%lx, endoff 0x%lx vm_map %p\n", (uint64_t) startoff, (uint64_t) endoff, &p->p_vmspace->vm_map);
+ void uvm_map_printit(struct vm_map *, bool, void (*)(const char *, ...));
+ uvm_map_printit(&p->p_vmspace->vm_map, true, printf);
+ KASSERT(p == l->l_proc);
+ Debugger(); /* Bang ! */
+ return EIO;
+ }
UVMHIST_LOG(ubchist, "vp %p pages %d off 0x%x len 0x%x",
vp, uobj->uo_npages, startoff, endoff - startoff);