From b98517da32aa338554282b9eac57f5c78fbddf4f Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 7 Nov 2013 16:09:21 -0500 Subject: [PATCH] Ticket 47582 - agmt_count in Replica could become (PRUint64)-1 Bug Description: agmt_count can go negative, and lead to a crash. This can happen when creating an agreement fails, and we lower the count before it was actually incremented. Fix Description: Move the agmt incrementing to agmt_new_from_entry(), as this same function can also cause the count to be decremented if something fails. https://fedorahosted.org/389/ticket/47582 Reviewed by: ? --- ldap/servers/plugins/replication/repl5_agmt.c | 10 ++++++++++ ldap/servers/plugins/replication/repl5_agmtlist.c | 1 - ldap/servers/plugins/replication/repl5_replica.c | 4 +++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c index c78ee94..6a9f8ad 100644 --- a/ldap/servers/plugins/replication/repl5_agmt.c +++ b/ldap/servers/plugins/replication/repl5_agmt.c @@ -347,8 +347,18 @@ agmt_new_from_entry(Slapi_Entry *e) tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot); if (NULL != tmpstr) { + Object *repl_obj; + Replica *replica; + ra->replarea = slapi_sdn_new_dn_passin(tmpstr); + /* now that we set the repl area, when can bump our agmt count */ + if((repl_obj = replica_get_replica_from_dn(ra->replarea))){ + if((replica = (Replica*)object_get_data (repl_obj))){ + replica_incr_agmt_count(replica); + } + } + /* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */ ra->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout); if(ra->protocol_timeout == 0){ diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c index 01814b0..bb2d628 100644 --- a/ldap/servers/plugins/replication/repl5_agmtlist.c +++ b/ldap/servers/plugins/replication/repl5_agmtlist.c @@ -171,7 +171,6 @@ add_new_agreement(Slapi_Entry *e) } rc = replica_start_agreement(replica, ra); - replica_incr_agmt_count(replica); if (repl_obj) object_release(repl_obj); diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c index ec5bf4d..26935ca 100644 --- a/ldap/servers/plugins/replication/repl5_replica.c +++ b/ldap/servers/plugins/replication/repl5_replica.c @@ -3956,6 +3956,8 @@ void replica_decr_agmt_count(Replica *r) { if(r){ - r->agmt_count--; + if(r->agmt_count > 0){ + r->agmt_count--; + } } } -- 1.7.1