Skip to content

Commit e726ae9

Browse files
committed
Add predicate checks in the pthread_cond wait loop in seap-command.c
SEAP_cmd_exec function waiting branch was prone to spurious wakeups. Use pthread_cond_broadcast __SEAP_cmd_sync_handler to make sure all possible listeners are notified.
1 parent 486b051 commit e726ae9

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

src/OVAL/probes/SEAP/seap-command.c

+11-15
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ static SEXP_t *__SEAP_cmd_sync_handler (SEXP_t *res, void *arg)
205205
h->args = res;
206206
(void) pthread_mutex_lock (&h->mtx);
207207
h->signaled = 1;
208-
(void) pthread_cond_signal (&h->cond);
208+
(void) pthread_cond_broadcast (&h->cond);
209209
(void) pthread_mutex_unlock (&h->mtx);
210210

211211
return (NULL);
@@ -322,9 +322,6 @@ SEXP_t *SEAP_cmd_exec (SEAP_CTX_t *ctx,
322322
h.args = NULL;
323323
h.signaled = 0;
324324

325-
if (pthread_mutex_lock (&(h.mtx)) != 0)
326-
abort ();
327-
328325
rec = SEAP_cmdrec_new ();
329326
rec->code = cmdptr->id;
330327
rec->func = &__SEAP_cmd_sync_handler;
@@ -377,8 +374,6 @@ SEXP_t *SEAP_cmd_exec (SEAP_CTX_t *ctx,
377374
timeout.tv_nsec = 0;
378375
*/
379376
for (;;) {
380-
pthread_mutex_unlock(&h.mtx);
381-
382377
if (SEAP_packet_recv(ctx, sd, &packet_rcv) != 0) {
383378
dD("FAIL: ctx=%p, sd=%d, errno=%u, %s.", ctx, sd, errno, strerror(errno));
384379
SEAP_packet_free(packet);
@@ -407,21 +402,23 @@ SEXP_t *SEAP_cmd_exec (SEAP_CTX_t *ctx,
407402
}
408403

409404
/* Morbo: THIS IS NOT HOW SYCHNRONIZATION WORKS! */
410-
if (h.signaled)
405+
if (h.signaled) {
406+
h.signaled = 0;
411407
break;
408+
}
412409
}
413410
} else {
414411
/*
415412
* Someone else does receiving of events for us.
416413
* Just wait for the condition to be signaled.
417414
*/
418-
if (pthread_cond_wait(&h.cond, &h.mtx) != 0) {
419-
/*
420-
* Fatal error - don't know how to handle
421-
* this so let's just call abort()...
422-
*/
423-
abort();
424-
}
415+
pthread_mutex_lock(&h.mtx);
416+
while (!h.signaled) {
417+
pthread_cond_wait(&h.cond, &h.mtx);
418+
}
419+
// This might not be needed, but still
420+
h.signaled = 0;
421+
pthread_mutex_unlock(&h.mtx);
425422
}
426423

427424
dD("cond return: h.args=%p", h.args);
@@ -436,7 +433,6 @@ SEXP_t *SEAP_cmd_exec (SEAP_CTX_t *ctx,
436433
/*
437434
* SEAP_cmdtbl_del(dsc->cmd_w_table, rec);
438435
*/
439-
pthread_mutex_unlock (&(h.mtx));
440436
pthread_cond_destroy (&(h.cond));
441437
pthread_mutex_destroy (&(h.mtx));
442438
SEAP_packet_free(packet);

0 commit comments

Comments
 (0)