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

Petr Spacek pspacek at redhat.com
Mon Feb 24 13:04:47 UTC 2014


On 21.2.2014 19:35, Lukas Slebodnik wrote:
> 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

ACK. Thank you for discovering this!

Pushed to master: e346fbce099eacb1cd860e0624dcaaea36161169

-- 
Petr^2 Spacek




More information about the Freeipa-devel mailing list