373 lines
12 KiB
Diff
373 lines
12 KiB
Diff
From ce896d538052d20f56f440d1a23fd99da950ed07 Mon Sep 17 00:00:00 2001
|
|
From: Noel Power <noel.power@suse.com>
|
|
Date: Wed, 19 Dec 2018 12:34:13 +0000
|
|
Subject: [PATCH 1/2] Fix segfault in nops when used with membersof overlay
|
|
|
|
Allow problematic variables to be defined on heap so modifications
|
|
to modlist can happen in other overlay modules
|
|
|
|
Signed-off-by: Noel Power <noel.power@suse.com>
|
|
---
|
|
servers/slapd/overlays/memberof.c | 64 +++++++++++++++++++++++++--------------
|
|
1 file changed, 41 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/servers/slapd/overlays/memberof.c b/servers/slapd/overlays/memberof.c
|
|
index 40ad6e2..358d5f9 100644
|
|
--- a/servers/slapd/overlays/memberof.c
|
|
+++ b/servers/slapd/overlays/memberof.c
|
|
@@ -355,10 +355,13 @@ memberof_value_modify(
|
|
unsigned long opid = op->o_opid;
|
|
SlapReply rs2 = { REP_RESULT };
|
|
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
|
|
- Modifications mod[ 2 ] = { { { 0 } } }, *ml;
|
|
- struct berval values[ 4 ], nvalues[ 4 ];
|
|
+ Modifications *mod[2] = {NULL, NULL};
|
|
+ Modifications *ml = NULL;
|
|
int mcnt = 0;
|
|
|
|
+ mod[0] = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
+ mod[1] = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
+
|
|
op2.o_tag = LDAP_REQ_MODIFY;
|
|
|
|
op2.o_req_dn = *ndn;
|
|
@@ -375,13 +378,17 @@ memberof_value_modify(
|
|
op2.o_dont_replicate = 1;
|
|
|
|
if ( !BER_BVISNULL( &mo->mo_ndn ) ) {
|
|
- ml = &mod[ mcnt ];
|
|
+ ml = mod[ mcnt ];
|
|
ml->sml_numvals = 1;
|
|
- ml->sml_values = &values[ 0 ];
|
|
- ml->sml_values[ 0 ] = mo->mo_dn;
|
|
+ ml->sml_values =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ ber_dupbv(&ml->sml_values[ 0 ], &mo->mo_ndn);
|
|
BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
- ml->sml_nvalues = &nvalues[ 0 ];
|
|
- ml->sml_nvalues[ 0 ] = mo->mo_ndn;
|
|
+ ml->sml_nvalues =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ ber_dupbv(&ml->sml_nvalues[ 0 ], &mo->mo_ndn);
|
|
BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
ml->sml_desc = slap_schema.si_ad_modifiersName;
|
|
ml->sml_type = ml->sml_desc->ad_cname;
|
|
@@ -393,11 +400,17 @@ memberof_value_modify(
|
|
mcnt++;
|
|
}
|
|
|
|
- ml = &mod[ mcnt ];
|
|
+ ml = mod[ mcnt ];
|
|
ml->sml_numvals = 1;
|
|
- ml->sml_values = &values[ 2 ];
|
|
+ ml->sml_values =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ BER_BVZERO( &ml->sml_values[ 0 ] );
|
|
BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
- ml->sml_nvalues = &nvalues[ 2 ];
|
|
+ ml->sml_nvalues =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ BER_BVZERO( &ml->sml_nvalues[ 0 ] );
|
|
BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
ml->sml_desc = ad;
|
|
ml->sml_type = ml->sml_desc->ad_cname;
|
|
@@ -412,11 +425,13 @@ memberof_value_modify(
|
|
assert( !BER_BVISNULL( new_dn ) );
|
|
assert( !BER_BVISNULL( new_ndn ) );
|
|
|
|
- ml = &mod[ mcnt ];
|
|
+ ml = mod[ mcnt ];
|
|
ml->sml_op = LDAP_MOD_ADD;
|
|
|
|
- ml->sml_values[ 0 ] = *new_dn;
|
|
- ml->sml_nvalues[ 0 ] = *new_ndn;
|
|
+ ber_memfree(ml->sml_values[ 0 ].bv_val);
|
|
+ ber_memfree(ml->sml_nvalues[ 0 ].bv_val);
|
|
+ ber_dupbv(&ml->sml_values[ 0 ], new_dn);
|
|
+ ber_dupbv(&ml->sml_nvalues[ 0 ], new_dn);
|
|
|
|
oex.oe_key = (void *)&memberof;
|
|
LDAP_SLIST_INSERT_HEAD(&op2.o_extra, &oex, oe_next);
|
|
@@ -433,18 +448,18 @@ memberof_value_modify(
|
|
op->o_log_prefix, buf, 0 );
|
|
}
|
|
|
|
- assert( op2.orm_modlist == &mod[ mcnt ] );
|
|
- assert( mcnt == 0 || op2.orm_modlist->sml_next == &mod[ 0 ] );
|
|
+ assert( op2.orm_modlist == mod[ mcnt ] );
|
|
+ assert( mcnt == 0 || op2.orm_modlist->sml_next == mod[ 0 ] );
|
|
ml = op2.orm_modlist->sml_next;
|
|
if ( mcnt == 1 ) {
|
|
- assert( ml == &mod[ 0 ] );
|
|
+ assert( ml == mod[ 0 ] );
|
|
ml = ml->sml_next;
|
|
}
|
|
if ( ml != NULL ) {
|
|
slap_mods_free( ml, 1 );
|
|
}
|
|
|
|
- mod[ 0 ].sml_next = NULL;
|
|
+ mod[ 0 ]->sml_next = NULL;
|
|
}
|
|
|
|
if ( old_ndn != NULL ) {
|
|
@@ -454,11 +469,13 @@ memberof_value_modify(
|
|
assert( !BER_BVISNULL( old_dn ) );
|
|
assert( !BER_BVISNULL( old_ndn ) );
|
|
|
|
- ml = &mod[ mcnt ];
|
|
+ ml = mod[ mcnt ];
|
|
ml->sml_op = LDAP_MOD_DELETE;
|
|
-
|
|
- ml->sml_values[ 0 ] = *old_dn;
|
|
- ml->sml_nvalues[ 0 ] = *old_ndn;
|
|
+
|
|
+ ber_memfree(ml->sml_values[ 0 ].bv_val);
|
|
+ ber_memfree(ml->sml_nvalues[ 0 ].bv_val);
|
|
+ ber_dupbv(&ml->sml_values[ 0 ], old_dn);
|
|
+ ber_dupbv(&ml->sml_nvalues[ 0 ], old_dn);
|
|
|
|
oex.oe_key = (void *)&memberof;
|
|
LDAP_SLIST_INSERT_HEAD(&op2.o_extra, &oex, oe_next);
|
|
@@ -475,10 +492,10 @@ memberof_value_modify(
|
|
op->o_log_prefix, buf, 0 );
|
|
}
|
|
|
|
- assert( op2.orm_modlist == &mod[ mcnt ] );
|
|
+ assert( op2.orm_modlist == mod[ mcnt ] );
|
|
ml = op2.orm_modlist->sml_next;
|
|
if ( mcnt == 1 ) {
|
|
- assert( ml == &mod[ 0 ] );
|
|
+ assert( ml == mod[ 0 ] );
|
|
ml = ml->sml_next;
|
|
}
|
|
if ( ml != NULL ) {
|
|
@@ -488,6 +505,7 @@ memberof_value_modify(
|
|
/* restore original opid */
|
|
op->o_opid = opid;
|
|
|
|
+ slap_mods_free( op2.orm_modlist, 1 );
|
|
/* FIXME: if old_group_ndn doesn't exist, both delete __and__
|
|
* add will fail; better split in two operations, although
|
|
* not optimal in terms of performance. At least it would
|
|
--
|
|
2.16.4
|
|
|
|
|
|
From 6bd3ce920e750c21cedf4a118027043d37056950 Mon Sep 17 00:00:00 2001
|
|
From: Noel Power <noel.power@suse.com>
|
|
Date: Wed, 19 Dec 2018 15:51:37 +0000
|
|
Subject: [PATCH 2/2] Remove asserts to allow nops to process.
|
|
|
|
The asserts present seem to:
|
|
a) ensure that only additions can happen to the modlist
|
|
b) that we only delete Modifications that have been added
|
|
|
|
These asserts are bound to the assumption that no other overlay
|
|
will delete Modifications from the modlist and additionally are
|
|
there to protect illegal deletion of Modifications allocated on
|
|
the stack. These changes allow Modifications to be deleted via
|
|
other overlay modules that could be called. Additionally since
|
|
now the modlist elements are allocated on the heap we can delete
|
|
them freely now.
|
|
|
|
Signed-off-by: Noel Power <noel.power@suse.com>
|
|
---
|
|
servers/slapd/overlays/memberof.c | 129 +++++++++++++++++---------------------
|
|
1 file changed, 57 insertions(+), 72 deletions(-)
|
|
|
|
diff --git a/servers/slapd/overlays/memberof.c b/servers/slapd/overlays/memberof.c
|
|
index 358d5f9..d49f2d3 100644
|
|
--- a/servers/slapd/overlays/memberof.c
|
|
+++ b/servers/slapd/overlays/memberof.c
|
|
@@ -334,6 +334,55 @@ memberof_isGroupOrMember( Operation *op, memberof_cbinfo_t *mci )
|
|
return LDAP_SUCCESS;
|
|
}
|
|
|
|
+static Modifications*
|
|
+memberof_value_modlist(
|
|
+ Operation *op2,
|
|
+ memberof_t *mo,
|
|
+ AttributeDescription *ad)
|
|
+{
|
|
+ Modifications *ml = NULL;
|
|
+ Modifications *result = NULL;
|
|
+ if ( !BER_BVISNULL( &mo->mo_ndn ) ) {
|
|
+ ml = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
+ ml->sml_numvals = 1;
|
|
+ ml->sml_values =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ ber_dupbv(&ml->sml_values[ 0 ], &mo->mo_ndn);
|
|
+ BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
+ ml->sml_nvalues =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ ber_dupbv(&ml->sml_nvalues[ 0 ], &mo->mo_ndn);
|
|
+ BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
+ ml->sml_desc = slap_schema.si_ad_modifiersName;
|
|
+ ml->sml_type = ml->sml_desc->ad_cname;
|
|
+ ml->sml_op = LDAP_MOD_REPLACE;
|
|
+ ml->sml_flags = SLAP_MOD_INTERNAL;
|
|
+ ml->sml_next = result;
|
|
+ result = ml;
|
|
+ }
|
|
+
|
|
+ ml = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
+ ml->sml_numvals = 1;
|
|
+ ml->sml_values =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ BER_BVZERO( &ml->sml_values[ 0 ] );
|
|
+ BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
+ ml->sml_nvalues =
|
|
+ (BerVarray)ch_malloc(
|
|
+ (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
+ BER_BVZERO( &ml->sml_nvalues[ 0 ] );
|
|
+ BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
+ ml->sml_desc = ad;
|
|
+ ml->sml_type = ml->sml_desc->ad_cname;
|
|
+ ml->sml_flags = SLAP_MOD_INTERNAL;
|
|
+ ml->sml_next = result;
|
|
+ result = ml;
|
|
+ return result;
|
|
+}
|
|
+
|
|
/*
|
|
* response callback that adds memberof values when a group is modified.
|
|
*/
|
|
@@ -355,12 +404,7 @@ memberof_value_modify(
|
|
unsigned long opid = op->o_opid;
|
|
SlapReply rs2 = { REP_RESULT };
|
|
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
|
|
- Modifications *mod[2] = {NULL, NULL};
|
|
Modifications *ml = NULL;
|
|
- int mcnt = 0;
|
|
-
|
|
- mod[0] = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
- mod[1] = (Modifications*)ch_calloc( sizeof(Modifications), 1 );
|
|
|
|
op2.o_tag = LDAP_REQ_MODIFY;
|
|
|
|
@@ -377,47 +421,6 @@ memberof_value_modify(
|
|
op2.orm_no_opattrs = 1;
|
|
op2.o_dont_replicate = 1;
|
|
|
|
- if ( !BER_BVISNULL( &mo->mo_ndn ) ) {
|
|
- ml = mod[ mcnt ];
|
|
- ml->sml_numvals = 1;
|
|
- ml->sml_values =
|
|
- (BerVarray)ch_malloc(
|
|
- (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
- ber_dupbv(&ml->sml_values[ 0 ], &mo->mo_ndn);
|
|
- BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
- ml->sml_nvalues =
|
|
- (BerVarray)ch_malloc(
|
|
- (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
- ber_dupbv(&ml->sml_nvalues[ 0 ], &mo->mo_ndn);
|
|
- BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
- ml->sml_desc = slap_schema.si_ad_modifiersName;
|
|
- ml->sml_type = ml->sml_desc->ad_cname;
|
|
- ml->sml_op = LDAP_MOD_REPLACE;
|
|
- ml->sml_flags = SLAP_MOD_INTERNAL;
|
|
- ml->sml_next = op2.orm_modlist;
|
|
- op2.orm_modlist = ml;
|
|
-
|
|
- mcnt++;
|
|
- }
|
|
-
|
|
- ml = mod[ mcnt ];
|
|
- ml->sml_numvals = 1;
|
|
- ml->sml_values =
|
|
- (BerVarray)ch_malloc(
|
|
- (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
- BER_BVZERO( &ml->sml_values[ 0 ] );
|
|
- BER_BVZERO( &ml->sml_values[ 1 ] );
|
|
- ml->sml_nvalues =
|
|
- (BerVarray)ch_malloc(
|
|
- (ml->sml_numvals + 1) * sizeof( struct berval ));
|
|
- BER_BVZERO( &ml->sml_nvalues[ 0 ] );
|
|
- BER_BVZERO( &ml->sml_nvalues[ 1 ] );
|
|
- ml->sml_desc = ad;
|
|
- ml->sml_type = ml->sml_desc->ad_cname;
|
|
- ml->sml_flags = SLAP_MOD_INTERNAL;
|
|
- ml->sml_next = op2.orm_modlist;
|
|
- op2.orm_modlist = ml;
|
|
-
|
|
if ( new_ndn != NULL ) {
|
|
BackendInfo *bi = op2.o_bd->bd_info;
|
|
OpExtra oex;
|
|
@@ -425,7 +428,9 @@ memberof_value_modify(
|
|
assert( !BER_BVISNULL( new_dn ) );
|
|
assert( !BER_BVISNULL( new_ndn ) );
|
|
|
|
- ml = mod[ mcnt ];
|
|
+ ml = memberof_value_modlist(&op2, mo, ad);
|
|
+ op2.orm_modlist = ml;
|
|
+
|
|
ml->sml_op = LDAP_MOD_ADD;
|
|
|
|
ber_memfree(ml->sml_values[ 0 ].bv_val);
|
|
@@ -447,19 +452,7 @@ memberof_value_modify(
|
|
Debug( LDAP_DEBUG_ANY, "%s: %s\n",
|
|
op->o_log_prefix, buf, 0 );
|
|
}
|
|
-
|
|
- assert( op2.orm_modlist == mod[ mcnt ] );
|
|
- assert( mcnt == 0 || op2.orm_modlist->sml_next == mod[ 0 ] );
|
|
- ml = op2.orm_modlist->sml_next;
|
|
- if ( mcnt == 1 ) {
|
|
- assert( ml == mod[ 0 ] );
|
|
- ml = ml->sml_next;
|
|
- }
|
|
- if ( ml != NULL ) {
|
|
- slap_mods_free( ml, 1 );
|
|
- }
|
|
-
|
|
- mod[ 0 ]->sml_next = NULL;
|
|
+ slap_mods_free( op2.orm_modlist, 1 );
|
|
}
|
|
|
|
if ( old_ndn != NULL ) {
|
|
@@ -469,7 +462,9 @@ memberof_value_modify(
|
|
assert( !BER_BVISNULL( old_dn ) );
|
|
assert( !BER_BVISNULL( old_ndn ) );
|
|
|
|
- ml = mod[ mcnt ];
|
|
+ ml = memberof_value_modlist(&op2, mo, ad);
|
|
+ op2.orm_modlist = ml;
|
|
+
|
|
ml->sml_op = LDAP_MOD_DELETE;
|
|
|
|
ber_memfree(ml->sml_values[ 0 ].bv_val);
|
|
@@ -491,21 +486,11 @@ memberof_value_modify(
|
|
Debug( LDAP_DEBUG_ANY, "%s: %s\n",
|
|
op->o_log_prefix, buf, 0 );
|
|
}
|
|
-
|
|
- assert( op2.orm_modlist == mod[ mcnt ] );
|
|
- ml = op2.orm_modlist->sml_next;
|
|
- if ( mcnt == 1 ) {
|
|
- assert( ml == mod[ 0 ] );
|
|
- ml = ml->sml_next;
|
|
- }
|
|
- if ( ml != NULL ) {
|
|
- slap_mods_free( ml, 1 );
|
|
- }
|
|
+ slap_mods_free( op2.orm_modlist, 1 );
|
|
}
|
|
/* restore original opid */
|
|
op->o_opid = opid;
|
|
|
|
- slap_mods_free( op2.orm_modlist, 1 );
|
|
/* FIXME: if old_group_ndn doesn't exist, both delete __and__
|
|
* add will fail; better split in two operations, although
|
|
* not optimal in terms of performance. At least it would
|
|
--
|
|
2.16.4
|
|
|