]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9420 - Fix memory leak in modrdn
authorQuanah Gibson-Mount <quanah@openldap.org>
Tue, 8 Dec 2020 16:05:35 +0000 (16:05 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 8 Dec 2020 17:09:59 +0000 (17:09 +0000)
Fix provided by grapvar@gmail.com

servers/slapd/modrdn.c

index a22975540c1eea68a0e3fae248a60127f61216c9..26550722d5ad8801c229ecbaf51695d96f03b44e 100644 (file)
@@ -382,6 +382,50 @@ cleanup:;
        return rs->sr_err;
 }
 
+/* extracted from slap_modrdn2mods() */
+static int
+mod_op_add_val(
+       Operation *op,
+       AttributeDescription * const desc,
+       struct berval * const val,
+       short const sm_op )
+{
+       int rv = LDAP_SUCCESS;
+       Modifications *mod_tmp;
+       mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
+       mod_tmp->sml_desc = desc;
+       BER_BVZERO( &mod_tmp->sml_type );
+       mod_tmp->sml_numvals = 1;
+       mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
+       ber_dupbv( &mod_tmp->sml_values[0], val );
+       mod_tmp->sml_values[1].bv_val = NULL;
+       if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
+               mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
+               rv = desc->ad_type->sat_equality->smr_normalize(
+                       SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
+                       desc->ad_type->sat_syntax,
+                       desc->ad_type->sat_equality,
+                       &mod_tmp->sml_values[0],
+                       &mod_tmp->sml_nvalues[0], NULL );
+               if (rv != LDAP_SUCCESS) {
+                       ch_free(mod_tmp->sml_nvalues);
+                       ch_free(mod_tmp->sml_values[0].bv_val);
+                       ch_free(mod_tmp->sml_values);
+                       ch_free(mod_tmp);
+                       goto done;
+               }
+               mod_tmp->sml_nvalues[1].bv_val = NULL;
+       } else {
+               mod_tmp->sml_nvalues = NULL;
+       }
+       mod_tmp->sml_op = sm_op;
+       mod_tmp->sml_flags = 0;
+       mod_tmp->sml_next = op->orr_modlist;
+       op->orr_modlist = mod_tmp;
+done:
+       return rv;
+}
+
 int
 slap_modrdn2mods(
        Operation       *op,
@@ -424,7 +468,6 @@ slap_modrdn2mods(
        /* Add new attribute values to the entry */
        for ( a_cnt = 0; new_rdn[a_cnt]; a_cnt++ ) {
                AttributeDescription    *desc = NULL;
-               Modifications           *mod_tmp;
 
                rs->sr_err = slap_bv2ad( &new_rdn[a_cnt]->la_attr, &desc, &rs->sr_text );
 
@@ -449,43 +492,15 @@ slap_modrdn2mods(
                }
 
                /* Apply modification */
-               mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
-               mod_tmp->sml_desc = desc;
-               BER_BVZERO( &mod_tmp->sml_type );
-               mod_tmp->sml_numvals = 1;
-               mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-               ber_dupbv( &mod_tmp->sml_values[0], &new_rdn[a_cnt]->la_value );
-               mod_tmp->sml_values[1].bv_val = NULL;
-               if( desc->ad_type->sat_equality->smr_normalize) {
-                       mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-                       rs->sr_err = desc->ad_type->sat_equality->smr_normalize(
-                               SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-                               desc->ad_type->sat_syntax,
-                               desc->ad_type->sat_equality,
-                               &mod_tmp->sml_values[0],
-                               &mod_tmp->sml_nvalues[0], NULL );
-                       if (rs->sr_err != LDAP_SUCCESS) {
-                               ch_free(mod_tmp->sml_nvalues);
-                               ch_free(mod_tmp->sml_values[0].bv_val);
-                               ch_free(mod_tmp->sml_values);
-                               ch_free(mod_tmp);
-                               goto done;
-                       }
-                       mod_tmp->sml_nvalues[1].bv_val = NULL;
-               } else {
-                       mod_tmp->sml_nvalues = NULL;
-               }
-               mod_tmp->sml_op = SLAP_MOD_SOFTADD;
-               mod_tmp->sml_flags = 0;
-               mod_tmp->sml_next = op->orr_modlist;
-               op->orr_modlist = mod_tmp;
+               rs->sr_err = mod_op_add_val( op, desc, &new_rdn[a_cnt]->la_value, SLAP_MOD_SOFTADD );
+               if (rs->sr_err != LDAP_SUCCESS)
+                       goto done;
        }
 
        /* Remove old rdn value if required */
        if ( op->orr_deleteoldrdn ) {
                for ( d_cnt = 0; old_rdn[d_cnt]; d_cnt++ ) {
                        AttributeDescription    *desc = NULL;
-                       Modifications           *mod_tmp;
 
                        rs->sr_err = slap_bv2ad( &old_rdn[d_cnt]->la_attr, &desc, &rs->sr_text );
                        if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -498,29 +513,9 @@ slap_modrdn2mods(
                        }
 
                        /* Apply modification */
-                       mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) );
-                       mod_tmp->sml_desc = desc;
-                       BER_BVZERO( &mod_tmp->sml_type );
-                       mod_tmp->sml_numvals = 1;
-                       mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod_tmp->sml_values[0], &old_rdn[d_cnt]->la_value );
-                       mod_tmp->sml_values[1].bv_val = NULL;
-                       if( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize) {
-                               mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) );
-                               (void) (*desc->ad_type->sat_equality->smr_normalize)(
-                                       SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
-                                       desc->ad_type->sat_syntax,
-                                       desc->ad_type->sat_equality,
-                                       &mod_tmp->sml_values[0],
-                                       &mod_tmp->sml_nvalues[0], NULL );
-                               mod_tmp->sml_nvalues[1].bv_val = NULL;
-                       } else {
-                               mod_tmp->sml_nvalues = NULL;
-                       }
-                       mod_tmp->sml_op = LDAP_MOD_DELETE;
-                       mod_tmp->sml_flags = 0;
-                       mod_tmp->sml_next = op->orr_modlist;
-                       op->orr_modlist = mod_tmp;
+                       rs->sr_err = mod_op_add_val( op, desc, &old_rdn[d_cnt]->la_value, LDAP_MOD_DELETE );
+                       if (rs->sr_err != LDAP_SUCCESS)
+                               goto done;
                }
        }
        
@@ -528,12 +523,8 @@ done:
 
        /* LDAP v2 supporting correct attribute handling. */
        if ( rs->sr_err != LDAP_SUCCESS && op->orr_modlist != NULL ) {
-               Modifications *tmp;
-
-               for ( ; op->orr_modlist != NULL; op->orr_modlist = tmp ) {
-                       tmp = op->orr_modlist->sml_next;
-                       ch_free( op->orr_modlist );
-               }
+               slap_mods_free( op->orr_modlist, 1 );
+               op->orr_modlist = NULL;
        }
 
        if ( new_rdn != NULL ) {