mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
bug 324529
When the malloc fails in the 'v' or 'V' ber_scanf case, we need to break out of the loop and return with an LBER_DEFAULT code. Also, in the realloc case, we need to save a copy of the old pointer and use either ber_svecfree ('v' case) or ber_bvecfree ('V' case) to clean up the memory. bug 324525 If the malloc is done to allocate the *bv, but then an lber error is encountered while doing the ber_skip_tag (due to a bad or malicious client), the bv->bv_val is set to a random value. If you then try to use ber_bvfree to free the bv, it may call free on this uninitialized value, and badness ensues. I think the proper fix is for ber_get_stringal to set (*bv)->bv_val to NULL and (*bv)->bv_len to 0 just after the malloc.
This commit is contained in:
parent
efd15b81c3
commit
1813b5349f
@ -313,6 +313,9 @@ ber_get_stringal( BerElement *ber, struct berval **bv )
|
||||
return( LBER_DEFAULT );
|
||||
}
|
||||
|
||||
(*bv)->bv_val = NULL;
|
||||
(*bv)->bv_len = 0;
|
||||
|
||||
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
|
||||
return( LBER_DEFAULT );
|
||||
}
|
||||
@ -528,14 +531,25 @@ ber_scanf( BerElement *ber, const char *fmt, ... )
|
||||
if ( *sss == NULL ) {
|
||||
/* Make room for at least 15 strings */
|
||||
*sss = (char **)NSLBERI_MALLOC(16 * sizeof(char *) );
|
||||
if (!*sss) {
|
||||
rc = LBER_DEFAULT;
|
||||
break; /* out of memory - cannot continue */
|
||||
}
|
||||
array_size = 16;
|
||||
} else {
|
||||
char **save_sss = *sss;
|
||||
if ( (size_t)(j+2) > array_size) {
|
||||
/* We'v overflowed our buffer */
|
||||
*sss = (char **)NSLBERI_REALLOC( *sss, (array_size * 2) * sizeof(char *) );
|
||||
array_size = array_size * 2;
|
||||
}
|
||||
if (!*sss) {
|
||||
rc = LBER_DEFAULT;
|
||||
ber_svecfree(save_sss);
|
||||
break; /* out of memory - cannot continue */
|
||||
}
|
||||
}
|
||||
(*sss)[j] = NULL;
|
||||
rc = ber_get_stringa( ber, &((*sss)[j]) );
|
||||
j++;
|
||||
}
|
||||
@ -543,8 +557,9 @@ ber_scanf( BerElement *ber, const char *fmt, ... )
|
||||
tag != LBER_END_OF_SEQORSET ) {
|
||||
rc = LBER_DEFAULT;
|
||||
}
|
||||
if ( j > 0 )
|
||||
if ( *sss && (j > 0) ) {
|
||||
(*sss)[j] = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V': /* sequence of strings + lengths */
|
||||
@ -558,10 +573,20 @@ ber_scanf( BerElement *ber, const char *fmt, ... )
|
||||
if ( *bv == NULL ) {
|
||||
*bv = (struct berval **)NSLBERI_MALLOC(
|
||||
2 * sizeof(struct berval *) );
|
||||
if (!*bv) {
|
||||
rc = LBER_DEFAULT;
|
||||
break; /* out of memory - cannot continue */
|
||||
}
|
||||
} else {
|
||||
struct berval **save_bv = *bv;
|
||||
*bv = (struct berval **)NSLBERI_REALLOC(
|
||||
*bv,
|
||||
(j + 2) * sizeof(struct berval *) );
|
||||
if (!*bv) {
|
||||
rc = LBER_DEFAULT;
|
||||
ber_bvecfree(save_bv);
|
||||
break; /* out of memory - cannot continue */
|
||||
}
|
||||
}
|
||||
rc = ber_get_stringal( ber, &((*bv)[j]) );
|
||||
j++;
|
||||
@ -570,8 +595,9 @@ ber_scanf( BerElement *ber, const char *fmt, ... )
|
||||
tag != LBER_END_OF_SEQORSET ) {
|
||||
rc = LBER_DEFAULT;
|
||||
}
|
||||
if ( j > 0 )
|
||||
if ( *bv && (j > 0) ) {
|
||||
(*bv)[j] = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'x': /* skip the next element - whatever it is */
|
||||
|
Loading…
Reference in New Issue
Block a user