Leonid Yuriev wrote:
04.01.2015 02:47, Howard Chu wrote:
The patch is wrong. syncprov_matchops can be called twice for the same operation; toggling the flag where you've placed it means the filter will be incorrect on the 2nd invocation as well as on all subsequent invocations.
Ok, but found another case. The ss->s_op->ors_filter may be updated immediately after the s_mutex released.
Seems like the simpler fix then is to keep the mutex held until after test_filter finishes.
This is a simple change for reproducing the bug.
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 5ef2eaa..f579faa 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -1295,6 +1295,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) }
if ( fc.fscope ) {
Filter *paranoia; ldap_pvt_thread_mutex_lock( &ss->s_mutex ); op2 = *ss->s_op; oh = *op->o_hdr;
@@ -1304,6 +1305,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) op2.o_hdr = &oh; op2.o_extra = op->o_extra; op2.o_callback = NULL;
paranoia = ss->s_op->ors_filter; if (ss->s_flags & PS_FIX_FILTER) { /* Skip the AND/GE clause that we stuck on in front. We would lose deletes/mods that happen during the refresh
@@ -1311,7 +1313,11 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) op2.ors_filter = ss->s_op->ors_filter->f_and->f_next; } ldap_pvt_thread_mutex_unlock( &ss->s_mutex );
assert (paranoia == ss->s_op->ors_filter || paranoia ==
ss->s_op->ors_filter->f_and->f_next);
usleep(1000);
assert (paranoia == ss->s_op->ors_filter || paranoia ==
ss->s_op->ors_filter->f_and->f_next); rc = test_filter( &op2, e, op2.ors_filter );
assert (paranoia == ss->s_op->ors_filter || paranoia ==
ss->s_op->ors_filter->f_and->f_next); }
Debug( LDAP_DEBUG_TRACE, "syncprov_matchops: sid %03x fscope
%d rc %d\n",
Updated patch attached. Please review and merge.
Leonid.
The attached files is derived from OpenLDAP Software. All of the modifications to OpenLDAP Software represented in the following patch(es) were developed by Peter-Service LLC, Moscow, Russia. Peter-Service LLC has not assigned rights and/or interest in this work to any party. I, Leonid Yuriev am authorized by Peter-Service LLC, my employer, to release this work under the following terms.
Peter-Service LLC hereby places the following modifications to OpenLDAP Software (and only these modifications) into the public domain. Hence, these modifications may be freely used and/or redistributed for any purpose with or without attribution and/or other notice.