From 8021cbd8f1aa0bd4158c954c451bd93a2bef4406 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Mon, 17 Jan 2011 12:20:56 +0000 Subject: [PATCH] ITS#6738 Catch ber errors in libldap/ldap_sync.c. Also remove variable tag in ldap_sync_search_intermediate() and reduce ber_scanf("tm", &tag, foo) to tag=ber_scanf("m", foo). --- libraries/libldap/ldap_sync.c | 106 +++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 40 deletions(-) diff --git a/libraries/libldap/ldap_sync.c b/libraries/libldap/ldap_sync.c index 17e52146ae..cc64e24a21 100644 --- a/libraries/libldap/ldap_sync.c +++ b/libraries/libldap/ldap_sync.c @@ -128,7 +128,7 @@ static int ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res ) { LDAPControl **ctrls = NULL; - int rc = LDAP_SUCCESS, + int rc = LDAP_OTHER, i; BerElement *ber = NULL; struct berval entryUUID = { 0 }, @@ -159,7 +159,6 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res ) /* extract controls */ ldap_get_entry_controls( ls->ls_ld, res, &ctrls ); if ( ctrls == NULL ) { - rc = LDAP_OTHER; goto done; } @@ -172,22 +171,26 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res ) /* control must be present; there might be other... */ if ( ctrls[ i ] == NULL ) { - rc = LDAP_OTHER; goto done; } /* extract data */ ber = ber_init( &ctrls[ i ]->ldctl_value ); + if ( ber == NULL ) { + goto done; + } /* scan entryUUID in-place ("m") */ - ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID ); - if ( entryUUID.bv_len == 0 ) { - rc = LDAP_OTHER; + if ( ber_scanf( ber, "{em" /*"}"*/, &state, &entryUUID ) == LBER_ERROR + || entryUUID.bv_len == 0 ) + { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { /* scan cookie in-place ("m") */ - ber_scanf( ber, /*"{"*/ "m}", &cookie ); + if ( ber_scanf( ber, /*"{"*/ "m}", &cookie ) == LBER_ERROR ) { + goto done; + } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } @@ -212,16 +215,15 @@ ldap_sync_search_entry( ldap_sync_t *ls, LDAPMessage *res ) break; default: - rc = LDAP_OTHER; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot unknown syncState=%d\n", state ); #endif /* LDAP_SYNC_TRACE */ goto done; } - if ( ls->ls_search_entry ) { - rc = ls->ls_search_entry( ls, res, &entryUUID, phase ); - } + rc = ls->ls_search_entry + ? ls->ls_search_entry( ls, res, &entryUUID, phase ) + : LDAP_SUCCESS; done:; if ( ber != NULL ) { @@ -302,9 +304,10 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) ber_len_t len; struct berval cookie = { 0 }; + rc = LDAP_OTHER; + /* deal with control; then fallthru to handler */ if ( ctrls == NULL ) { - rc = LDAP_OTHER; goto done; } @@ -319,16 +322,22 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) /* control must be present; there might be other... */ if ( ctrls[ i ] == NULL ) { - rc = LDAP_OTHER; goto done; } /* extract data */ ber = ber_init( &ctrls[ i ]->ldctl_value ); + if ( ber == NULL ) { + goto done; + } - ber_scanf( ber, "{" /*"}"*/); + if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) { + goto ber_done; + } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { - ber_scanf( ber, "m", &cookie ); + if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { + goto ber_done; + } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } @@ -340,17 +349,23 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) refreshDeletes = 0; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { - ber_scanf( ber, "b", &refreshDeletes ); + if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { + goto ber_done; + } if ( refreshDeletes ) { refreshDeletes = 1; } } - ber_scanf( ber, /*"{"*/ "}" ); + if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) { + rc = LDAP_SUCCESS; + } - /* NOTE: if any goto/return between ber_init() and here - * is introduced, don't forget to ber_free() */ + ber_done:; ber_free( ber, 1 ); + if ( rc != LDAP_SUCCESS ) { + break; + } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDeletes=%s\n", @@ -379,9 +394,6 @@ ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) err = ls->ls_search_result( ls, res, refreshDeletes ); } break; - - default: - break; } done:; @@ -413,8 +425,7 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo struct berval *retdata = NULL; BerElement *ber = NULL; ber_len_t len; - ber_tag_t tag, - syncinfo_tag; + ber_tag_t syncinfo_tag; struct berval cookie; int refreshDeletes = 0; BerVarray syncUUIDs = NULL; @@ -444,8 +455,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo goto done; } + rc = LDAP_OTHER; + if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) { - rc = LDAP_OTHER; goto done; } @@ -458,7 +470,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo syncinfo_tag = ber_peek_tag( ber, &len ); switch ( syncinfo_tag ) { case LDAP_TAG_SYNC_NEW_COOKIE: - ber_scanf( ber, "tm", &tag, &cookie ); + if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { + goto done; + } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } @@ -482,7 +496,6 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo default: /* TODO: impossible; handle */ - rc = LDAP_OTHER; goto done; } @@ -497,14 +510,17 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo default: /* TODO: impossible; handle */ - rc = LDAP_OTHER; goto done; } } - ber_scanf( ber, "t{" /*"}"*/, &tag ); + if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { + goto done; + } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { - ber_scanf( ber, "m", &cookie ); + if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { + goto done; + } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } @@ -516,7 +532,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo *refreshDone = 1; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) { - ber_scanf( ber, "b", refreshDone ); + if ( ber_scanf( ber, "b", refreshDone ) == LBER_ERROR ) { + goto done; + } } #ifdef LDAP_SYNC_TRACE @@ -524,7 +542,9 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo *refreshDone ? "TRUE" : "FALSE" ); #endif /* LDAP_SYNC_TRACE */ - ber_scanf( ber, /*"{"*/ "}" ); + if ( ber_scanf( ber, /*"{"*/ "}" ) == LBER_ERROR ) { + goto done; + } if ( *refreshDone ) { ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; @@ -540,9 +560,13 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot syncIdSet\n" ); #endif /* LDAP_SYNC_TRACE */ - ber_scanf( ber, "t{" /*"}"*/, &tag ); + if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { + goto done; + } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { - ber_scanf( ber, "m", &cookie ); + if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { + goto done; + } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } @@ -553,13 +577,14 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { - ber_scanf( ber, "b", &refreshDeletes ); + if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { + goto done; + } } - ber_scanf( ber, "[W]", &syncUUIDs ); - ber_scanf( ber, /*"{"*/ "}" ); - if ( syncUUIDs == NULL ) { - rc = LDAP_OTHER; + if ( ber_scanf( ber, /*"{"*/ "[W]}", &syncUUIDs ) == LBER_ERROR + || syncUUIDs == NULL ) + { goto done; } @@ -601,6 +626,8 @@ ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDo goto done; } + rc = LDAP_SUCCESS; + done:; if ( ber != NULL ) { ber_free( ber, 1 ); @@ -899,4 +926,3 @@ done_search:; done:; return rc; } - -- 2.39.5