[Freeipa-devel] [PATCH][bind-dyndb-ldap] Fix potential dereference of NULL pointer in sync_ctx_init

Lukas Slebodnik lslebodn at redhat.com
Fri Feb 21 18:35:22 UTC 2014


On (13/12/13 17:44), Petr Spacek wrote:
>On 12.11.2013 16:13, Petr Spacek wrote:
>>On 5.11.2013 12:29, Tomas Hozza wrote:
>>>----- Original Message -----
>>>>Hello,
>>>>
>>>>Improve performance of initial LDAP synchronization.
>>>>
>>>>Changes are not journaled and SOA serial is not incremented during initial
>>>>LDAP synchronization.
>>>>
>>>>This eliminates unnecessary synchronous writes to journal and also
>>>>unnecessary SOA serial writes to LDAP.
>>>>
>>>>See commit messages and comments in syncrepl.c for all the gory details.
>>>
>>>
>>>ACK.
>>>
>>>Patches look good. AXFR and IXFR works as expected. Also BIND starts up much
>>>faster with these patches. Good job... :)
>>>
>>>Regards,
>>>
>>>Tomas
>>
>>Hmm, further testing revealed that patch 203 changed behavior little bit:
>>Zones were loaded from LDAP correctly, but the SOA serial wasn't changed at
>>all. As a result, zone transfers return inconsistent results if the data in
>>LDAP are changed when BIND was not running.
>>
>>Patch 203-v2 imitates the old behavior from bind-dyndb-ldap 3.x: Zone serial
>>is bumped *once* for each zone, so any changed in LDAP will be transferred
>>correctly (with new serial).
>
>Patch 202 v2 was rebased and fixes reconnection to LDAP and solves
>deadlock caused by too eager locking.
>
>Patch 203 v3 was rebased and fixes reconnection to LDAP.
>
>These patches should go to master branch.
>
>-- 
>Petr^2 Spacek
>

When I was testing upcoming bind-dyndb-ldap 4.0 release,
There was an interesting warning from clang static analyser.
I thought it was a false passitive, but it isn't.

Patch is attached


>From b73e345393d55fe411875d52e6fe4c98e1de8c04 Mon Sep 17 00:00:00 2001
>From: Petr Spacek <pspacek at redhat.com>
>Date: Mon, 9 Dec 2013 11:11:10 +0100
>Subject: [PATCH] Detect end of initial LDAP synchronization phase.
>
>LDAP intermediate message with refreshDone = TRUE is translated to
>sync_barrier_wait() call. This call sends 'barrier event' to all tasks
>involved in syncrepl event processing. The call will return when all tasks
>have processed all events enqueued before the call.
>
>Effectively, all events produced by initial LDAP synchronization
>are processed first. Current state of synchronization is available via
>sync_state_get() call.
>
>See comments in syncrepl.c for all the gory details.
>
>Signed-off-by: Petr Spacek <pspacek at redhat.com>
>---
> src/Makefile.am   |   2 +
> src/ldap_helper.c |  67 +++++++++--
> src/ldap_helper.h |   2 +
> src/syncrepl.c    | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> src/syncrepl.h    |  63 ++++++++++
> 5 files changed, 473 insertions(+), 12 deletions(-)
> create mode 100644 src/syncrepl.c
> create mode 100644 src/syncrepl.h
>

<snip>

>+/**
>+ * Initialize synchronization context.
>+ *
>+ * @param[in]	task	Task used for first synchronization events.
>+ * 			Typically the ldap_inst->task.
>+ * @param[out]	sctxp	The new synchronization context.
>+ *
>+ * @post state == sync_init
>+ * @post task_cnt == 1
>+ * @post tasks list contains the task
>+ */
>+isc_result_t
>+sync_ctx_init(isc_mem_t *mctx, isc_task_t *task, sync_ctx_t **sctxp) {
>+	isc_result_t result;
>+	sync_ctx_t *sctx = NULL;
>+	isc_boolean_t lock_ready = ISC_FALSE;
>+	isc_boolean_t cond_ready = ISC_FALSE;
>+	isc_boolean_t refcount_ready = ISC_FALSE;
>+
>+	REQUIRE(sctxp != NULL && *sctxp == NULL);
                             ^^^^^^^^^^^^^^
                  *sctxp is NULL


>+	REQUIRE(ISCAPI_TASK_VALID(task));
>+
>+	CHECKED_MEM_GET_PTR(mctx, sctx);
>+	ZERO_PTR(sctx);
>+	isc_mem_attach(mctx, &sctx->mctx);
>+
>+	CHECK(isc_mutex_init(&sctx->mutex));
>+	lock_ready = ISC_TRUE;
>+	CHECK(isc_condition_init(&sctx->cond));
>+	cond_ready = ISC_TRUE;
>+
>+	/* refcount includes ldap_inst->task implicitly */
>+	CHECK(isc_refcount_init(&sctx->task_cnt, 0));
>+	refcount_ready = ISC_TRUE;
>+
>+	ISC_LIST_INIT(sctx->tasks);
>+
>+	sctx->state = sync_init;
>+	CHECK(sync_task_add(sctx, task));
>+
>+	*sctxp = sctx;
    ^^^^^^
value to *sctxp is asigned only on this line.

>+	return ISC_R_SUCCESS;
>+
>+cleanup:
*sctxp will be NULL in cleanup section

>+	if (lock_ready == ISC_TRUE)
>+		isc_mutex_destroy(&(*sctxp)->mutex);
                          &(NULL)->mutex
                     It does not look like a good idea :-)
>+	if (cond_ready == ISC_TRUE)
>+		isc_condition_init(&(*sctxp)->cond);
>+	if (refcount_ready == ISC_TRUE)
>+		isc_refcount_destroy(&(*sctxp)->task_cnt);
>+	MEM_PUT_AND_DETACH(*sctxp);
>+	return result;
>+}
>+

LS
-------------- next part --------------
>From dcf99122eb33b63799be91d3c13a9967420880c3 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Fri, 21 Feb 2014 19:18:28 +0100
Subject: [PATCH] Fix potential dereference of NULL pointer in sync_ctx_init

Value is asigned to the output argument sync_ctx_t **sctxp
before returning ISC_R_SUCCESS. Thus we should use local variable sctx
in cleanup section.
---
 src/syncrepl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/syncrepl.c b/src/syncrepl.c
index 2a6d159fe16fffbf928198f9240cd8b1fcd41005..c6b326bab9733f7cb5065381d26e999ddbb570db 100644
--- a/src/syncrepl.c
+++ b/src/syncrepl.c
@@ -215,12 +215,12 @@ sync_ctx_init(isc_mem_t *mctx, isc_task_t *task, sync_ctx_t **sctxp) {
 
 cleanup:
 	if (lock_ready == ISC_TRUE)
-		isc_mutex_destroy(&(*sctxp)->mutex);
+		isc_mutex_destroy(&sctx->mutex);
 	if (cond_ready == ISC_TRUE)
-		isc_condition_init(&(*sctxp)->cond);
+		isc_condition_init(&sctx->cond);
 	if (refcount_ready == ISC_TRUE)
-		isc_refcount_destroy(&(*sctxp)->task_cnt);
-	MEM_PUT_AND_DETACH(*sctxp);
+		isc_refcount_destroy(&sctx->task_cnt);
+	MEM_PUT_AND_DETACH(sctx);
 	return result;
 }
 
-- 
1.8.5.3



More information about the Freeipa-devel mailing list