For ITS#6353: Catch embedded NULs in BerValues converted to char* strings

This commit is contained in:
Hallvard Furuseth 2009-10-28 23:00:27 +00:00
parent d3addb8247
commit 989bd54914
2 changed files with 23 additions and 11 deletions

View File

@ -278,6 +278,7 @@ ber_get_stringb LDAP_P((
#define LBER_BV_ALLOC 0x01 /* allocate/copy result, otherwise in-place */ #define LBER_BV_ALLOC 0x01 /* allocate/copy result, otherwise in-place */
#define LBER_BV_NOTERM 0x02 /* omit NUL-terminator if parsing in-place */ #define LBER_BV_NOTERM 0x02 /* omit NUL-terminator if parsing in-place */
#define LBER_BV_STRING 0x04 /* fail if berval contains embedded \0 */
LBER_F( ber_tag_t ) LBER_F( ber_tag_t )
ber_get_stringbv LDAP_P(( ber_get_stringbv LDAP_P((

View File

@ -345,7 +345,7 @@ enum bgbvc { ChArray, BvArray, BvVec, BvOff };
*/ */
typedef struct bgbvr { typedef struct bgbvr {
const enum bgbvc choice; const enum bgbvc choice;
const int alloc; /* choice == BvOff ? 0 : LBER_ALLOC */ const int option; /* (ALLOC unless BvOff) | (STRING if ChArray) */
ber_len_t siz; /* input array element size, output count */ ber_len_t siz; /* input array element size, output count */
ber_len_t off; /* BvOff offset to the struct berval */ ber_len_t off; /* BvOff offset to the struct berval */
void *result; void *result;
@ -418,9 +418,9 @@ ber_get_stringbvl( BerElement *ber, bgbvr *b )
n = 0; n = 0;
do { do {
tag = ber_get_stringbv( ber, &bv, b->alloc ); tag = ber_get_stringbv( ber, &bv, b->option );
if ( tag == LBER_DEFAULT ) { if ( tag == LBER_DEFAULT ) {
goto nomem; goto failed;
} }
/* store my result */ /* store my result */
@ -436,7 +436,7 @@ ber_get_stringbvl( BerElement *ber, bgbvr *b )
ber->ber_memctx ); ber->ber_memctx );
if ( !bvp ) { if ( !bvp ) {
ber_memfree_x( bv.bv_val, ber->ber_memctx ); ber_memfree_x( bv.bv_val, ber->ber_memctx );
goto nomem; goto failed;
} }
res.bv[n] = bvp; res.bv[n] = bvp;
*bvp = bv; *bvp = bv;
@ -449,8 +449,8 @@ ber_get_stringbvl( BerElement *ber, bgbvr *b )
} while (++n < i); } while (++n < i);
return tag; return tag;
nomem: failed:
if (b->choice != BvOff) { /* BvOff does not have b->alloc set */ if (b->choice != BvOff) { /* BvOff does not have LBER_BV_ALLOC set */
while (--n >= 0) { while (--n >= 0) {
switch(b->choice) { switch(b->choice) {
case ChArray: case ChArray:
@ -480,9 +480,11 @@ ber_get_stringbv( BerElement *ber, struct berval *bv, int option )
char *data; char *data;
tag = ber_skip_element( ber, bv ); tag = ber_skip_element( ber, bv );
if ( tag == LBER_DEFAULT ) { if ( tag == LBER_DEFAULT ||
(( option & LBER_BV_STRING ) && memchr( bv->bv_val, 0, bv->bv_len )))
{
bv->bv_val = NULL; bv->bv_val = NULL;
return tag; return LBER_DEFAULT;
} }
data = bv->bv_val; data = bv->bv_val;
@ -516,6 +518,11 @@ ber_get_stringbv_null( BerElement *ber, struct berval *bv, int option )
return tag; return tag;
} }
if (( option & LBER_BV_STRING ) && memchr( bv->bv_val, 0, bv->bv_len )) {
bv->bv_val = NULL;
return LBER_DEFAULT;
}
data = bv->bv_val; data = bv->bv_val;
if ( option & LBER_BV_ALLOC ) { if ( option & LBER_BV_ALLOC ) {
bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1, bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
@ -541,7 +548,7 @@ ber_get_stringa( BerElement *ber, char **buf )
assert( buf != NULL ); assert( buf != NULL );
tag = ber_get_stringbv( ber, &bv, LBER_BV_ALLOC ); tag = ber_get_stringbv( ber, &bv, LBER_BV_ALLOC | LBER_BV_STRING );
*buf = bv.bv_val; *buf = bv.bv_val;
return tag; return tag;
@ -555,7 +562,7 @@ ber_get_stringa_null( BerElement *ber, char **buf )
assert( buf != NULL ); assert( buf != NULL );
tag = ber_get_stringbv_null( ber, &bv, LBER_BV_ALLOC ); tag = ber_get_stringbv_null( ber, &bv, LBER_BV_ALLOC | LBER_BV_STRING );
*buf = bv.bv_val; *buf = bv.bv_val;
return tag; return tag;
@ -608,6 +615,10 @@ ber_get_bitstringa(
goto fail; goto fail;
} }
if ( memchr( data.bv_val, 0, data.bv_len )) {
goto fail;
}
*buf = (char *) ber_memalloc_x( data.bv_len, ber->ber_memctx ); *buf = (char *) ber_memalloc_x( data.bv_len, ber->ber_memctx );
if ( *buf == NULL ) { if ( *buf == NULL ) {
return LBER_DEFAULT; return LBER_DEFAULT;
@ -811,7 +822,7 @@ ber_scanf ( BerElement *ber,
case 'v': /* sequence of strings */ case 'v': /* sequence of strings */
{ {
bgbvr cookie = { bgbvr cookie = {
ChArray, LBER_BV_ALLOC, sizeof( char * ) ChArray, LBER_BV_ALLOC | LBER_BV_STRING, sizeof( char * )
}; };
rc = ber_get_stringbvl( ber, &cookie ); rc = ber_get_stringbvl( ber, &cookie );
*(va_arg( ap, char *** )) = cookie.result; *(va_arg( ap, char *** )) = cookie.result;