Blob Blame History Raw
From f15dc13cab2814bdf40e909b8325e436ee1f3940 Mon Sep 17 00:00:00 2001
From: Tomas Heinrich <theinric@redhat.com>
Date: Thu, 14 Jul 2016 03:41:27 +0200
Subject: [PATCH] Prevent races in calls to json_object_get_string()

---
 runtime/msg.c | 10 ++++++++++
 runtime/msg.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/runtime/msg.c b/runtime/msg.c
index 10ecf48..4c82182 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -716,6 +716,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis)
 	pM->rcvFrom.pRcvFrom = NULL;
 	pM->pRuleset = NULL;
 	pM->json = NULL;
+	pthread_mutex_init(&pM->json_mut, NULL);
 	memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt));
 	memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP));
 	pM->TAG.pszTAG = NULL;
@@ -861,6 +862,7 @@ CODESTARTobjDestruct(msg)
 			rsCStrDestruct(&pThis->pCSMSGID);
 		if(pThis->json != NULL)
 			json_object_put(pThis->json);
+		pthread_mutex_destroy(&pThis->json_mut);
 		if(pThis->pszUUID != NULL)
 			free(pThis->pszUUID);
 #	ifndef HAVE_ATOMIC_BUILTINS
@@ -1065,7 +1067,9 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm)
 	psz = getRcvFromIP(pThis); 
 	CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRcvFromIP"), PROPTYPE_PSZ, (void*) psz));
 	if(pThis->json != NULL) {
+		pthread_mutex_lock(&pThis->json_mut);
 		psz = (uchar*) json_object_get_string(pThis->json);
+		pthread_mutex_unlock(&pThis->json_mut);
 		CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("json"), PROPTYPE_PSZ, (void*) psz));
 	}
 
@@ -2546,7 +2550,9 @@ getCEEPropVal(msg_t *pM, es_str_t *propName, uchar **pRes, rs_size_t *buflen, un
 		field = json_object_object_get(parent, (char*)leaf);
 	}
 	if(field != NULL) {
+		pthread_mutex_lock(&pM->json_mut);
 		*pRes = (uchar*) strdup(json_object_get_string(field));
+		pthread_mutex_unlock(&pM->json_mut);
 		*buflen = (int) ustrlen(*pRes);
 		*pbMustBeFreed = 1;
 	}
@@ -2985,7 +2991,9 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
 				bufLen = 2;
 				*pbMustBeFreed = 0;
 			} else {
+				pthread_mutex_lock(&pMsg->json_mut);
 				pRes = (uchar*)strdup(json_object_get_string(pMsg->json));
+				pthread_mutex_unlock(&pMsg->json_mut);
 				*pbMustBeFreed = 1;
 			}
 			break;
@@ -3686,7 +3694,9 @@ msgGetCEEVarNew(msg_t *pMsg, char *name)
 		goto done;
 	}
 	json = json_object_object_get(parent, (char*)leaf);
+	pthread_mutex_lock(&pMsg->json_mut);
 	val = (char*)json_object_get_string(json);
+	pthread_mutex_unlock(&pMsg->json_mut);
 	estr = es_newStrFromCStr(val, strlen(val));
 done:
 	return estr;
diff --git a/runtime/msg.h b/runtime/msg.h
index e7babdb..814468d 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -107,6 +107,7 @@ struct msg {
 	struct syslogTime tRcvdAt;/* time the message entered this program */
 	struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
 	struct json_object *json;
+	pthread_mutex_t json_mut; /* prevent concurent mutability of the json_object in the msg */
 	/* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */
 	uchar szRawMsg[CONF_RAWMSG_BUFSIZE];	/* most messages are small, and these are stored here (without malloc/free!) */
 	uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE];
-- 
2.5.5