Skip to content
Permalink
Browse files

dird: Fix pthread issues

Fixes two double pthread_detach() calls and one pthread_getspecific()
without initialization, all leading to a SEGFAULT with musl libc and
undefined behaviour on other libc implementations.

This closes Bug #1073
  • Loading branch information...
bratkartoffel authored and arogge committed Apr 18, 2019
1 parent 619493d commit ad27319624adbaf89c1d39e11eed174f63187715
Showing with 23 additions and 4 deletions.
  1. +12 −0 core/src/dird/dird.cc
  2. +1 −0 core/src/dird/dird.h
  3. +1 −1 core/src/dird/job.cc
  4. +1 −1 core/src/dird/ua_server.cc
  5. +8 −2 core/src/lib/jcr.cc
@@ -657,6 +657,18 @@ bool DoReloadConfig()
is_reloading = false;
return reloaded;
}

void DetachIfNotDetached(pthread_t thr) {
/* only detach if not yet detached */
int _detachstate;
pthread_attr_t _gattr;
pthread_getattr_np(thr, &_gattr);
pthread_attr_getdetachstate(&_gattr, &_detachstate);
pthread_attr_destroy(&_gattr);
if(_detachstate != PTHREAD_CREATE_DETACHED) {
pthread_detach(thr);
}
}
} /* namespace directordaemon */

/*
@@ -246,6 +246,7 @@ struct runtime_job_status_t {
#define FD_VERSION_54 54

bool DoReloadConfig();
void DetachIfNotDetached(pthread_t thr);

} /* namespace directordaemon */

@@ -452,7 +452,7 @@ static void* job_thread(void* arg)
{
JobControlRecord* jcr = (JobControlRecord*)arg;

pthread_detach(pthread_self());
DetachIfNotDetached(pthread_self());

Dmsg0(200, "=====Start Job=========\n");
jcr->setJobStatus(JS_Running); /* this will be set only if no error */
@@ -79,7 +79,7 @@ JobControlRecord* new_control_jcr(const char* base_name, int job_type)
*/
void* HandleUserAgentClientRequest(BareosSocket* user_agent_socket)
{
pthread_detach(pthread_self());
DetachIfNotDetached(pthread_self());

JobControlRecord* jcr = new_control_jcr("-Console-", JT_CONSOLE);

@@ -83,6 +83,7 @@ static pthread_mutex_t jcr_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t job_start_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t last_jobs_mutex = PTHREAD_MUTEX_INITIALIZER;

static bool jcr_initialized = false;
#ifdef HAVE_WIN32
static bool tsd_initialized = false;
static pthread_key_t jcr_key; /* Pointer to jcr for each thread */
@@ -336,6 +337,8 @@ static void create_jcr_key()
BErrNo be;
Jmsg1(nullptr, M_ABORT, 0, _("pthread key create failed: ERR=%s\n"),
be.bstrerror(status));
} else {
jcr_initialized = true;
}
}

@@ -696,7 +699,10 @@ void SetJcrInTsd(JobControlRecord* jcr)
*/
JobControlRecord* get_jcr_from_tsd()
{
JobControlRecord* jcr = (JobControlRecord*)pthread_getspecific(jcr_key);
JobControlRecord* jcr = (JobControlRecord*)INVALID_JCR;
if (jcr_initialized){
jcr = (JobControlRecord*)pthread_getspecific(jcr_key);
}

/*
* Set any INVALID_JCR to nullptr which the rest of BAREOS understands
@@ -711,7 +717,7 @@ JobControlRecord* get_jcr_from_tsd()
*/
uint32_t GetJobidFromTsd()
{
JobControlRecord* jcr = (JobControlRecord*)pthread_getspecific(jcr_key);
JobControlRecord* jcr = get_jcr_from_tsd();
uint32_t JobId = 0;

if (jcr && jcr != INVALID_JCR) { JobId = (uint32_t)jcr->JobId; }

0 comments on commit ad27319

Please sign in to comment.
You can’t perform that action at this time.