From c7fb671f4927d597afdd7d10adc44b35bfa88393 Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Aug 23 2016 08:26:53 +0000 Subject: Ticket 48960 Crash in import_wait_for_space_in_fifo(). Bug Description: At online total import on a consumer, the total import startup function allocates a fifo queue and monitor the overall import. This queue contain the entries later received during import. When monitoring ends (import complete or error) it frees the queue. Under error condition, there is a possibility that monitoring ends while entries are still received (bulk_import_queue). So there is a risk that the received entries will be added into the queue at the same time the monitoring thread frees the queue Fix Description: The thread storing the entries into the queue runs while holding the job->wire_lock. To prevent the monitoring thread to frees the queue under bulk_import_queue, make sure to acquire job->wire_lock before calling import_free_job https://fedorahosted.org/389/ticket/48960 Reviewed by: Mark Reynolds (thanks Mark !) Platforms tested: F23 Flag Day: no Doc impact: no --- diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c index bae76c9..18a366a 100644 --- a/ldap/servers/slapd/back-ldbm/import-threads.c +++ b/ldap/servers/slapd/back-ldbm/import-threads.c @@ -3199,6 +3199,11 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry) return -1; } + /* The import is aborted, just ignore that entry */ + if(job->flags & FLAG_ABORT) { + return -1; + } + PR_Lock(job->wire_lock); /* Let's do this inside the lock !*/ id = job->lead_ID + 1; diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c index 08e31da..a59f980 100644 --- a/ldap/servers/slapd/back-ldbm/import.c +++ b/ldap/servers/slapd/back-ldbm/import.c @@ -369,8 +369,21 @@ void import_free_job(ImportJob *job) ldbm_back_free_incl_excl(job->include_subtrees, job->exclude_subtrees); charray_free(job->input_filenames); - if (job->fifo.size) + if (job->fifo.size) { + /* bulk_import_queue is running, while holding the job lock. + * bulk_import_queue is using the fifo queue. + * To avoid freeing fifo queue under bulk_import_queue use + * job lock to synchronize + */ + if (job->wire_lock) + PR_Lock(job->wire_lock); + import_fifo_destroy(job); + + if (job->wire_lock) + PR_Unlock(job->wire_lock); + } + if (NULL != job->uuid_namespace) slapi_ch_free((void **)&job->uuid_namespace); if (job->wire_lock)