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