453637, 453638, 453639, 453640,453444: CVE-2008-2952 OpenLDAP denial-of-service flaw in ASN.1 decoder Source: upstream, cvs diff -r 1.120 -r 1.122 libraries/liblber/io.c Index: libraries/liblber/io.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/libraries/liblber/io.c,v retrieving revision 1.120 retrieving revision 1.122 diff -u -r1.120 -r1.122 --- libraries/liblber/io.c 7 Jan 2008 23:20:03 -0000 1.120 +++ libraries/liblber/io.c 1 Jul 2008 23:33:15 -0000 1.122 @@ -522,14 +522,18 @@ } while (ber->ber_rwptr > (char *)&ber->ber_tag && ber->ber_rwptr < - (char *)&ber->ber_len + LENSIZE*2 -1) { + (char *)&ber->ber_len + LENSIZE*2) { ber_slen_t sblen; char buf[sizeof(ber->ber_len)-1]; ber_len_t tlen = 0; + /* The tag & len can be at most 9 bytes; we try to read up to 8 here */ sock_errset(0); - sblen=ber_int_sb_read( sb, ber->ber_rwptr, - ((char *)&ber->ber_len + LENSIZE*2 - 1)-ber->ber_rwptr); + sblen=((char *)&ber->ber_len + LENSIZE*2 - 1)-ber->ber_rwptr; + /* Trying to read the last len byte of a 9 byte tag+len */ + if (sblen<1) + sblen = 1; + sblen=ber_int_sb_read( sb, ber->ber_rwptr, sblen ); if (sblen<=0) return LBER_DEFAULT; ber->ber_rwptr += sblen; @@ -579,7 +583,7 @@ int i; unsigned char *p = (unsigned char *)ber->ber_ptr; int llen = *p++ & 0x7f; - if (llen > (int)sizeof(ber_len_t)) { + if (llen > LENSIZE) { sock_errset(ERANGE); return LBER_DEFAULT; }