From 0a25cddcf39d8acdb22acd3fa2ce1c5bb8b554a5 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 27 Nov 2001 09:34:53 +0000 Subject: [PATCH] Fix segv in slapcat. Tool must use be_entry_return to free entries returned from the backend. --- servers/slapd/back-bdb/id2entry.c | 21 ++++++++++++++++++--- servers/slapd/back-bdb/init.c | 3 +-- servers/slapd/back-bdb/proto-bdb.h | 1 + servers/slapd/entry.c | 6 +++--- servers/slapd/tools/slapcat.c | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c index 4686dadf2d..2edc0dbe0e 100644 --- a/servers/slapd/back-bdb/id2entry.c +++ b/servers/slapd/back-bdb/id2entry.c @@ -139,10 +139,10 @@ int bdb_entry_return( /* Our entries are almost always contiguous blocks, so a single * free() on the Entry pointer suffices. The exception is when * an entry has been modified, in which case the attr list will - * have been alloc'd separately. + * have been alloc'd separately and its address will no longer + * be a constant offset from (e). */ - if( (void *) e->e_attrs < (void *) e - || (void *) e->e_attrs > e->e_private ) + if( (void *) e->e_attrs != (void *) (e+1)) { attrs_free(e->e_attrs); } @@ -151,3 +151,18 @@ int bdb_entry_return( return 0; } +int bdb_entry_release( + BackendDB *be, + Connection *c, + Operation *o, + Entry *e, + int rw ) +{ + /* A tool will call this with NULL Connection and Operation + * pointers. We don't need to do anything in that case, + * because the tool is getting entries into a realloc'd + * buffer. + */ + if (c && o) + return bdb_entry_return(be, e); +} diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 6511221c19..73dbb384ef 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -128,7 +128,6 @@ bdb_db_open( BackendDB *be ) } else { flags |= DB_INIT_CDB; bdb->bi_txn_cp = 0; - bdb->bi_dbenv->set_lk_detect(bdb->bi_dbenv, DB_LOCK_DEFAULT); } bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0] ); @@ -385,7 +384,7 @@ bdb_initialize( bi->bi_acl_attribute = bdb_attribute; bi->bi_chk_referrals = bdb_referrals; - bi->bi_entry_release_rw = 0; + bi->bi_entry_release_rw = bdb_entry_release; /* * hooks for slap tools diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 3b7ccbbd7f..fbeb1d1826 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -107,6 +107,7 @@ bdb_dn2idl( * entry.c */ int bdb_entry_return( BackendDB *be, Entry *e ); +int bdb_entry_release( BackendDB *, Connection *, Operation *, Entry *, int ); /* * error.c diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 9dd396ffb9..0e0943513e 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -488,8 +488,8 @@ int entry_encode(Entry *e, struct berval **bv) * All we have to do is add the buffer address to all of the * stored offsets. We also must lookup the stored attribute names * to get AttributeDescriptions. To detect if the attributes of - * an Entry are later modified, we also store the address of the - * end of this block in e_private. + * an Entry are later modified, we note that e->e_attr is always + * a constant offset from (e). * * Note: everything is stored in a single contiguous block, so * you can not free individual attributes or names from this @@ -516,7 +516,7 @@ int entry_decode(struct berval *bv, Entry **e) "entry_decode: \"%s\"\n", x->e_dn, 0, 0 ); #endif - x->e_private = bv->bv_val + bv->bv_len; + x->e_private = NULL; if (x->e_attrs) x->e_attrs = (Attribute *)((long)x->e_attrs+base); for (a=x->e_attrs; a; a=a->a_next) { diff --git a/servers/slapd/tools/slapcat.c b/servers/slapd/tools/slapcat.c index a8b69a89e7..16224cff4f 100644 --- a/servers/slapd/tools/slapcat.c +++ b/servers/slapd/tools/slapcat.c @@ -59,7 +59,7 @@ main( int argc, char **argv ) } data = entry2str( e, &len ); - entry_free( e ); + be_entry_release_r( be, 0L, 0L, e ); if ( data == NULL ) { printf("# bad data for entry id=%08lx\n\n", (long) id ); -- 2.39.5