Blame SOURCES/rsyslog-8.24.0-rhbz1600462-wrktable-realloc-null.patch

fde8c1
From f2f67932a37539080b7ad3403dd073df3511a410 Mon Sep 17 00:00:00 2001
fde8c1
From: Rainer Gerhards <rgerhards@adiscon.com>
fde8c1
Date: Fri, 27 Oct 2017 08:36:19 +0200
fde8c1
Subject: [PATCH] core/action: fix NULL pointer access under OOM condition
fde8c1
fde8c1
If a new worker was started while the system ran out of memory
fde8c1
a NULL pointer access could happen. The patch handles this more
fde8c1
gracefully.
fde8c1
fde8c1
Detected by Coverty Scan, CID 185342.
fde8c1
---
fde8c1
 action.c | 17 +++++++++++++----
fde8c1
 1 file changed, 13 insertions(+), 4 deletions(-)
fde8c1
fde8c1
diff --git a/action.c b/action.c
fde8c1
index 986501074..4e467ee8b 100644
fde8c1
--- a/action.c
fde8c1
+++ b/action.c
fde8c1
@@ -822,8 +822,9 @@ actionDoRetry(action_t * const pThis, wti_t * const pWti)
fde8c1
 
fde8c1
 
fde8c1
 static rsRetVal
fde8c1
-actionCheckAndCreateWrkrInstance(action_t * const pThis, wti_t * const pWti)
fde8c1
+actionCheckAndCreateWrkrInstance(action_t * const pThis, const wti_t *const pWti)
fde8c1
 {
fde8c1
+	int locked = 0;
fde8c1
 	DEFiRet;
fde8c1
 	if(pWti->actWrkrInfo[pThis->iActionNbr].actWrkrData == NULL) {
fde8c1
 		DBGPRINTF("wti %p: we need to create a new action worker instance for "
fde8c1
@@ -836,23 +837,31 @@ actionCheckAndCreateWrkrInstance(action_t * const pThis, wti_t * const pWti)
fde8c1
 		/* maintain worker data table -- only needed if wrkrHUP is requested! */
fde8c1
 
fde8c1
 		pthread_mutex_lock(&pThis->mutWrkrDataTable);
fde8c1
+		locked = 1;
fde8c1
 		int freeSpot;
fde8c1
 		for(freeSpot = 0 ; freeSpot < pThis->wrkrDataTableSize ; ++freeSpot)
fde8c1
 			if(pThis->wrkrDataTable[freeSpot] == NULL)
fde8c1
 				break;
fde8c1
 		if(pThis->nWrkr == pThis->wrkrDataTableSize) {
fde8c1
-			// TODO: check realloc, fall back to old table if it fails. Better than nothing...
fde8c1
-			pThis->wrkrDataTable = realloc(pThis->wrkrDataTable,
fde8c1
+			void *const newTable = realloc(pThis->wrkrDataTable,
fde8c1
 				(pThis->wrkrDataTableSize + 1) * sizeof(void*));
fde8c1
+			if(newTable == NULL) {
fde8c1
+				DBGPRINTF("actionCheckAndCreateWrkrInstance: out of "
fde8c1
+					"memory realloc wrkrDataTable\n")
fde8c1
+				ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
fde8c1
+			}
fde8c1
+			pThis->wrkrDataTable = newTable;
fde8c1
 			pThis->wrkrDataTableSize++;
fde8c1
 		}
fde8c1
 		pThis->wrkrDataTable[freeSpot] = pWti->actWrkrInfo[pThis->iActionNbr].actWrkrData;
fde8c1
 		pThis->nWrkr++;
fde8c1
-		pthread_mutex_unlock(&pThis->mutWrkrDataTable);
fde8c1
 		DBGPRINTF("wti %p: created action worker instance %d for "
fde8c1
 			  "action %d\n", pWti, pThis->nWrkr, pThis->iActionNbr);
fde8c1
 	}
fde8c1
 finalize_it:
fde8c1
+	if(locked) {
fde8c1
+		pthread_mutex_unlock(&pThis->mutWrkrDataTable);
fde8c1
+	}
fde8c1
 	RETiRet;
fde8c1
 }
fde8c1