From 35462e713d90b1d455a2f09b32a2d76d34c813b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Thu, 12 Oct 2017 10:57:52 +0200
Subject: [PATCH] HTTPLoop: Get the log_lock before messing with log_head.

Fixes unlikely race in cleanup code on accept(2) failing with EBADF.

Fixes [CID 742665].
---
 src/modules/HTTPLoop/accept_and_parse.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/modules/HTTPLoop/accept_and_parse.c b/src/modules/HTTPLoop/accept_and_parse.c
index 47175d3956..aab4d65687 100644
--- a/src/modules/HTTPLoop/accept_and_parse.c
+++ b/src/modules/HTTPLoop/accept_and_parse.c
@@ -461,6 +461,20 @@ static void low_accept_loop(struct args *arg)
 	struct cache *c, *p = NULL;
 	struct log *l, *n = NULL;
 	/* oups. */
+
+	/* NB: log_head is protected by the log_lock mutex. */
+	mt_lock(&arg->log->log_lock);
+	while(arg->log->log_head)
+	{
+	  struct log_entry *l = arg->log->log_head->next;
+	  free(arg->log->log_head);
+	  arg->log->log_head = l;
+	}
+	mt_unlock(&arg->log->log_lock);
+
+	/* NB: The cache, and the variables first_cache and aap_first_log
+	 *     are protected by the interpreter lock.
+	 */
 	low_mt_lock_interpreter(); /* Can run even if threads_disabled. */
 	for(i=0; i<CACHE_HTABLE_SIZE; i++)
 	{
@@ -475,12 +489,6 @@ static void low_accept_loop(struct args *arg)
 	    free(t);
 	  }
 	}
-	while(arg->log->log_head)
-	{
-	  struct log_entry *l = arg->log->log_head->next;
-	  free(arg->log->log_head);
-	  arg->log->log_head = l;
-	}
 
 	c = first_cache;
 	while(c && c != arg->cache) {p=c;c = c->next;}
-- 
GitLab