diff --git a/SOURCES/rsyslog-8.24.0-doc-rhbz1309698-imudp-case-sensitive-option.patch b/SOURCES/rsyslog-8.24.0-doc-rhbz1309698-imudp-case-sensitive-option.patch
new file mode 100644
index 0000000..58f4b57
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-doc-rhbz1309698-imudp-case-sensitive-option.patch
@@ -0,0 +1,64 @@
+From 27eda7938d678bc69b46cfcb8351e871161ba526 Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@momo7.localdomain>
+Date: Fri, 13 Jul 2018 10:44:13 -0700
+Subject: [PATCH] Introducing an option preservecase to imudp and imtcp module
+ for managing the case of FROMHOST value.
+
+Usage:
+  module(load="imudp" [preservecase="on"|"off"])
+  module(load="imtdp" [preservecase="on"|"off"])
+
+If preservecase="on", FROMHOST value is handled in the case sensitive manner.
+If preservecase="off", FROMHOST value is handled in the case insensitive manner.
+
+To maintain the current behaviour, the default value of preservecase is
+"on" for imtcp and "off" for imudp.
+
+References:
+  https://github.com/rsyslog/rsyslog/pull/2774
+  https://bugzilla.redhat.com/show_bug.cgi?id=1309698
+---
+ source/configuration/modules/imtcp.rst | 9 +++++++++
+ source/configuration/modules/imudp.rst | 9 +++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/source/configuration/modules/imtcp.rst b/source/configuration/modules/imtcp.rst
+index 2ddb7e9a..b9fe0adb 100644
+--- a/source/configuration/modules/imtcp.rst
++++ b/source/configuration/modules/imtcp.rst
+@@ -138,6 +138,15 @@
+    Array of peers:
+    PermittedPeer=["test1.example.net","10.1.2.3","test2.example.net","..."]
+ 
++.. function::  PreserveCase <on/off>
++
++   *Default: off*
++
++   This parameter is for controlling the case in fromhost.  If set to "on", 
++   the case in fromhost is preserved.  E.g., 'Host1.Example.Org' when the 
++   message was received from 'Host1.Example.Org'.  Defaults to "off" for 
++   backwards compatibility.
++
+ Input Parameters
+ ^^^^^^^^^^^^^^^^
+ 
+diff --git a/source/configuration/modules/imudp.rst b/source/configuration/modules/imudp.rst
+index 487853f6..b92f0810 100644
+--- a/source/configuration/modules/imudp.rst
++++ b/source/configuration/modules/imudp.rst
+@@ -97,6 +97,15 @@
+    set to 32. It may increase in the future when massive multicore
+    processors become available.
+ 
++.. function::  PreserveCase <on/off>
++
++   *Default: off*
++
++   This parameter is for controlling the case in fromhost.  If set to "on", 
++   the case in fromhost is preserved.  E.g., 'Host1.Example.Org' when the 
++   message was received from 'Host1.Example.Org'.  Defaults to "off" for 
++   backwards compatibility.
++
+ .. index:: imudp; input parameters
+ 
+ Input Parameters
diff --git a/SOURCES/rsyslog-8.24.0-doc-rhbz1696686-imjournal-fsync.patch b/SOURCES/rsyslog-8.24.0-doc-rhbz1696686-imjournal-fsync.patch
new file mode 100644
index 0000000..ef68b32
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-doc-rhbz1696686-imjournal-fsync.patch
@@ -0,0 +1,41 @@
+From 3ba46e563a3a5384fd6d783a8315273c237cb6af Mon Sep 17 00:00:00 2001
+From: Jiri Vymazal <jvymazal@redhat.com>
+Date: Tue, 23 Jul 2019 12:47:09 +0200
+Subject: [PATCH] Documetation for new 'fsync' imjournal option
+
+related to #3762 main repo PR
+---
+ source/configuration/modules/imjournal.rst | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletitions (-)
+
+diff --git a/source/configuration/modules/imjournal.rst b/source/configuration/modules/imjournal.rst
+index d8523ae8..47428fc6 100644
+--- a/source/configuration/modules/imjournal.rst
++++ b/source/configuration/modules/imjournal.rst
+@@ -3,8 +3,7 @@
+ 
+ **Module Name:** imjournal
+ 
+-**Author:** Milan Bartos <mbartos@redhat.com> (This module is **not**
+-project-supported)
++**Author:** Milan Bartos <mbartos@redhat.com>
+ 
+ **Available since**: 7.3.11
+ 
+@@ -107,6 +106,16 @@
+     with each message to work around this problem. Be aware that in some cases this
+     might result in imjournal performance hit.
+ 
++-  **FSync** [**off**/on]
++
++    When there is a hard crash, power loss or similar abrupt end of rsyslog process,
++    there is a risk of state file not being written to persistent storage or possibly
++    being corrupted. This then results in imjournal starting reading elsewhere then 
++    desired and most probably message duplication. To mitigate this problem you can 
++    turn this option on which will force state file writes to persistent physical 
++    storage. Please note that fsync calls are costly, so especially with lower 
++    PersistStateInterval value, this may present considerable performance hit.
++
+ **Caveats/Known Bugs:**
+ 
+ - As stated above, a corrupted systemd journal database can cause major
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1309698-imudp-case-sensitive-option.patch b/SOURCES/rsyslog-8.24.0-rhbz1309698-imudp-case-sensitive-option.patch
new file mode 100644
index 0000000..900ce2f
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1309698-imudp-case-sensitive-option.patch
@@ -0,0 +1,285 @@
+From 9ac54f0d7d70b8a9879889b4522a1d552fca1100 Mon Sep 17 00:00:00 2001
+From: Noriko Hosoi <nhosoi@momo7.localdomain>
+Date: Thu, 12 Jul 2018 11:52:04 -0700
+Subject: [PATCH] Introducing an option preservecase to imudp and imtcp module
+ for managing the case of FROMHOST value.
+
+Usage:
+module(load="imudp" [preservecase="on"|"off"])
+module(load="imtdp" [preservecase="on"|"off"])
+
+If preservecase="on", FROMHOST value is handled in the case sensitive manner.
+If preservecase="off", FROMHOST value is handled in the case insensitive manner.
+
+To maintain the current behaviour, the default value of preservecase is
+"on" for imtcp and "off" for imudp.
+
+Incremented tcpsrvCURR_IF_VERSION by 1.
+
+References:
+https://github.com/rsyslog/rsyslog/pull/2774
+https://bugzilla.redhat.com/show_bug.cgi?id=1309698
+---
+ plugins/imtcp/imtcp.c | 14 ++++++++++++--
+ plugins/imudp/imudp.c | 15 ++++++++++++---
+ runtime/msg.c         |  6 +++++-
+ runtime/msg.h         |  2 ++
+ runtime/net.c         |  2 +-
+ runtime/tcpsrv.c      | 21 +++++++++++++++++++++
+ runtime/tcpsrv.h      |  5 ++++-
+ 7 files changed, 57 insertions(+), 8 deletions(-)
+
+diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
+index 8e3dcc0a21..45fa240b59 100644
+--- a/plugins/imtcp/imtcp.c
++++ b/plugins/imtcp/imtcp.c
+@@ -100,6 +100,7 @@ static struct configSettings_s {
+ 	int iAddtlFrameDelim;
+ 	int bDisableLFDelim;
+ 	int bUseFlowControl;
++	int bPreserveCase;
+ 	uchar *pszStrmDrvrAuthMode;
+ 	uchar *pszInputName;
+ 	uchar *pszBindRuleset;
+@@ -144,6 +145,7 @@ struct modConfData_s {
+ 	uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
+ 	struct cnfarray *permittedPeers;
+ 	sbool configSetViaV2Method;
++	sbool bPreserveCase; /* preserve case of fromhost; true by default */
+ };
+ 
+ static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+@@ -169,7 +171,8 @@ static struct cnfparamdescr modpdescr[] = {
+	{ "keepalive", eCmdHdlrBinary, 0 },
+ 	{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
+ 	{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
+-	{ "keepalive.interval", eCmdHdlrPositiveInt, 0 }
++	{ "keepalive.interval", eCmdHdlrPositiveInt, 0 },
++	{ "preservecase", eCmdHdlrBinary, 0 }
+ };
+ static struct cnfparamblk modpblk =
+ 	{ CNFPARAMBLK_VERSION,
+@@ -375,6 +378,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
+ 		if(pPermPeersRoot != NULL) {
+ 			CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
+ 		}
++		CHKiRet(tcpsrv.SetPreserveCase(pOurTcpsrv, modConf->bPreserveCase));
+ 	}
+ 
+ 	/* initialized, now add socket and listener params */
+@@ -473,6 +477,7 @@ CODESTARTbeginCnfLoad
+ 	loadModConf->pszStrmDrvrAuthMode = NULL;
+ 	loadModConf->permittedPeers = NULL;
+ 	loadModConf->configSetViaV2Method = 0;
++	loadModConf->bPreserveCase = 1; /* default to true */
+ 	bLegacyCnfModGlobalsPermitted = 1;
+ 	/* init legacy config variables */
+ 	cs.pszStrmDrvrAuthMode = NULL;
+@@ -543,6 +548,8 @@ CODESTARTsetModCnf
+ 			loadModConf->pszStrmDrvrName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ 		} else if(!strcmp(modpblk.descr[i].name, "permittedpeer")) {
+ 			loadModConf->permittedPeers = cnfarrayDup(pvals[i].val.d.ar);
++		} else if(!strcmp(modpblk.descr[i].name, "preservecase")) {
++			loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
+ 		} else {
+ 			dbgprintf("imtcp: program error, non-handled "
+ 			  "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+@@ -584,6 +591,7 @@ CODESTARTendCnfLoad
+ 			loadModConf->pszStrmDrvrAuthMode = cs.pszStrmDrvrAuthMode;
+ 			cs.pszStrmDrvrAuthMode = NULL;
+ 		}
++		pModConf->bPreserveCase = cs.bPreserveCase;
+ 	}
+ 	free(cs.pszStrmDrvrAuthMode);
+ 	cs.pszStrmDrvrAuthMode = NULL;
+@@ -731,6 +739,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
+ 	cs.pszInputName = NULL;
+ 	free(cs.pszStrmDrvrAuthMode);
+ 	cs.pszStrmDrvrAuthMode = NULL;
++	cs.bPreserveCase = 1;
+ 	return RS_RET_OK;
+ }
+ 
+@@ -797,7 +806,8 @@ CODEmodInit_QueryRegCFSLineHdlr
+ 			   NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
+ 	CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0, eCmdHdlrInt,
+ 			   NULL, &cs.iStrmDrvrMode, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
+-
++	CHKiRet(regCfSysLineHdlr2(UCHAR_CONSTANT("inputtcpserverpreservecase"), 1, eCmdHdlrBinary,
++			   NULL, &cs.bPreserveCase, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
+ 	CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
+ 				   resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ ENDmodInit
+diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
+index 51a9d712a0..74437781ca 100644
+--- a/plugins/imudp/imudp.c
++++ b/plugins/imudp/imudp.c
+@@ -152,6 +152,7 @@ struct modConfData_s {
+ 	int batchSize;			/* max nbr of input batch --> also recvmmsg() max count */
+ 	int8_t wrkrMax;			/* max nbr of worker threads */
+ 	sbool configSetViaV2Method;
++	sbool bPreserveCase;	/* preserves the case of fromhost; "off" by default */
+ };
+ static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
+@@ -162,7 +163,8 @@ static struct cnfparamdescr modpdescr[] = {
+ 	{ "schedulingpriority", eCmdHdlrInt, 0 },
+ 	{ "batchsize", eCmdHdlrInt, 0 },
+ 	{ "threads", eCmdHdlrPositiveInt, 0 },
+-	{ "timerequery", eCmdHdlrInt, 0 }
++	{ "timerequery", eCmdHdlrInt, 0 },
++	{ "preservecase", eCmdHdlrBinary, 0 }
+ };
+ static struct cnfparamblk modpblk =
+ 	{ CNFPARAMBLK_VERSION,
+@@ -447,8 +449,12 @@ processPacket(struct lstn_s *lstn, struct sockaddr_storage *frominetPrev, int *p
+ 		if(lstn->dfltTZ != NULL)
+ 			MsgSetDfltTZ(pMsg, (char*) lstn->dfltTZ);
+ 		pMsg->msgFlags  = NEEDS_PARSING | PARSE_HOSTNAME | NEEDS_DNSRESOL;
+-		if(*pbIsPermitted == 2)
+-			pMsg->msgFlags  |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
++		if(*pbIsPermitted == 2) {
++			pMsg->msgFlags |= NEEDS_ACLCHK_U; /* request ACL check after resolution */
++		}
++		if(runModConf->bPreserveCase) {
++			pMsg->msgFlags |= PRESERVE_CASE; /* preserve case of fromhost */
++		}
+ 		CHKiRet(msgSetFromSockinfo(pMsg, frominet));
+ 		CHKiRet(ratelimitAddMsg(lstn->ratelimiter, multiSub, pMsg));
+ 		STATSCOUNTER_INC(lstn->ctrSubmit, lstn->mutCtrSubmit);
+@@ -1030,6 +1036,7 @@ CODESTARTbeginCnfLoad
+ 	loadModConf->iTimeRequery = TIME_REQUERY_DFLT;
+ 	loadModConf->iSchedPrio = SCHED_PRIO_UNSET;
+ 	loadModConf->pszSchedPolicy = NULL;
++	loadModConf->bPreserveCase = 0; /* off */
+ 	bLegacyCnfModGlobalsPermitted = 1;
+ 	/* init legacy config vars */
+ 	cs.pszBindRuleset = NULL;
+@@ -1079,6 +1086,8 @@ CODESTARTsetModCnf
+ 			} else {
+ 				loadModConf->wrkrMax = wrkrMax;
+ 			}
++		} else if(!strcmp(modpblk.descr[i].name, "preservecase")) {
++			loadModConf->bPreserveCase = (int) pvals[i].val.d.n;
+ 		} else {
+ 			dbgprintf("imudp: program error, non-handled "
+ 			  "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+diff --git a/runtime/msg.c b/runtime/msg.c
+index c43f813142..9ed4eaf84d 100644
+--- a/runtime/msg.c
++++ b/runtime/msg.c
+@@ -506,7 +506,11 @@ resolveDNS(smsg_t * const pMsg) {
+ 	MsgLock(pMsg);
+ 	CHKiRet(objUse(net, CORE_COMPONENT));
+ 	if(pMsg->msgFlags & NEEDS_DNSRESOL) {
+-		localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
++		if (pMsg->msgFlags & PRESERVE_CASE) {
++			localRet = net.cvthname(pMsg->rcvFrom.pfrominet, NULL, &localName, &ip);
++		} else {
++			localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip);
++		}
+ 		if(localRet == RS_RET_OK) {
+ 			/* we pass down the props, so no need for AddRef */
+ 			MsgSetRcvFromWithoutAddRef(pMsg, localName);
+diff --git a/runtime/msg.h b/runtime/msg.h
+index cd530aca38..1287cb7a4b 100644
+--- a/runtime/msg.h
++++ b/runtime/msg.h
+@@ -144,6 +144,7 @@  struct msg {
+ #define NEEDS_DNSRESOL	0x040	/* fromhost address is unresolved and must be locked up via DNS reverse lookup first */
+ #define NEEDS_ACLCHK_U	0x080	/* check UDP ACLs after DNS resolution has been done in main queue consumer */
+ #define NO_PRI_IN_RAW	0x100	/* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
++#define PRESERVE_CASE	0x200	/* preserve case in fromhost */
+ 
+ /* (syslog) protocol types */
+ #define MSG_LEGACY_PROTOCOL 0
+diff --git a/runtime/net.c b/runtime/net.c
+index d6ff8a3d4d..aef906601c 100644
+--- a/runtime/net.c
++++ b/runtime/net.c
+@@ -1152,7 +1152,7 @@ cvthname(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t *
+ {
+ 	DEFiRet;
+ 	assert(f != NULL);
+-	iRet = dnscacheLookup(f, NULL, fqdn, localName, ip);
++	iRet = dnscacheLookup(f, fqdn, NULL, localName, ip);
+ 	RETiRet;
+ }
+ 
+diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c
+index 61e9ff4d22..d5993b4f00 100644
+--- a/runtime/tcpsrv.c
++++ b/runtime/tcpsrv.c
+@@ -495,6 +495,15 @@ SessAccept(tcpsrv_t *pThis, tcpLstnPortList_t *pLstnInfo, tcps_sess_t **ppSess,
+ 
+ 	/* get the host name */
+ 	CHKiRet(netstrm.GetRemoteHName(pNewStrm, &fromHostFQDN));
++	if (!pThis->bPreserveCase) {
++		/* preserve_case = off */
++		uchar *p;
++		for(p = fromHostFQDN; *p; p++) {
++			if (isupper((int) *p)) {
++				*p = tolower((int) *p);
++			}
++		}
++	}
+ 	CHKiRet(netstrm.GetRemoteIP(pNewStrm, &fromHostIP));
+ 	CHKiRet(netstrm.GetRemAddr(pNewStrm, &addr));
+ 	/* TODO: check if we need to strip the domain name here -- rgerhards, 2008-04-24 */
+@@ -1001,6 +1010,7 @@ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macr
+ 	pThis->ratelimitBurst = 10000;
+ 	pThis->bUseFlowControl = 1;
+ 	pThis->pszDrvrName = NULL;
++	pThis->bPreserveCase = 1; /* preserve case in fromhost; default to true. */
+ ENDobjConstruct(tcpsrv)
+ 
+ 
+@@ -1433,6 +1443,16 @@ SetSessMax(tcpsrv_t *pThis, int iMax)
+ }
+ 
+ 
++static rsRetVal
++SetPreserveCase(tcpsrv_t *pThis, int bPreserveCase)
++{
++	DEFiRet;
++	ISOBJ_TYPE_assert(pThis, tcpsrv);
++	pThis-> bPreserveCase = bPreserveCase;
++	RETiRet;
++}
++
++
+ /* queryInterface function
+  * rgerhards, 2008-02-29
+  */
+@@ -1491,6 +1511,7 @@ CODESTARTobjQueryInterface(tcpsrv)
+ 	pIf->SetRuleset = SetRuleset;
+ 	pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters;
+ 	pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose;
++	pIf->SetPreserveCase = SetPreserveCase;
+ 
+ finalize_it:
+ ENDobjQueryInterface(tcpsrv)
+diff --git a/runtime/tcpsrv.h b/runtime/tcpsrv.h
+index 22a65c20a0..f17b1b4384 100644
+--- a/runtime/tcpsrv.h
++++ b/runtime/tcpsrv.h
+@@ -81,6 +81,7 @@  struct tcpsrv_s {
+ 
+ 	int addtlFrameDelim;	/**< additional frame delimiter for plain TCP syslog framing (e.g. to handle NetScreen) */
+ 	int bDisableLFDelim;	/**< if 1, standard LF frame delimiter is disabled (*very dangerous*) */
++	sbool bPreserveCase;	/**< preserve case in fromhost */
+ 	int ratelimitInterval;
+ 	int ratelimitBurst;
+ 	tcps_sess_t **pSessions;/**< array of all of our sessions */
+@@ -168,8 +169,10 @@  BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
+ 	rsRetVal (*SetKeepAliveTime)(tcpsrv_t*, int);
+ 	/* added v18 */
+ 	rsRetVal (*SetbSPFramingFix)(tcpsrv_t*, sbool);
++	/* added v21 -- Preserve case in fromhost, 2018-08-16 */
++	rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
+ ENDinterface(tcpsrv)
+-#define tcpsrvCURR_IF_VERSION 18 /* increment whenever you change the interface structure! */
++#define tcpsrvCURR_IF_VERSION 21 /* increment whenever you change the interface structure! */
+ /* change for v4:
+  * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
+  * - SetInputName() added -- rgerhards, 2008-12-10
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1549706-corrupt-property-crash.patch b/SOURCES/rsyslog-8.24.0-rhbz1549706-corrupt-property-crash.patch
new file mode 100644
index 0000000..5e5f488
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1549706-corrupt-property-crash.patch
@@ -0,0 +1,29 @@
+From 3a93e5e377cad7acd241f0f93de625657fada25c Mon Sep 17 00:00:00 2001
+From: Derek Smith <derek@slack-corp.com>
+Date: Wed, 21 Jun 2017 13:32:02 +0100
+Subject: [PATCH] type should be set back to VARTYPE_NONE incase we assigned a
+ property type of VARTYPE_STRING while failing to grab the length value
+
+---
+ runtime/obj.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/runtime/obj.c b/runtime/obj.c
+index 2186727ae6..771e5c16a7 100644
+--- a/runtime/obj.c
++++ b/runtime/obj.c
+@@ -664,6 +664,14 @@ rsRetVal objDeserializeProperty(var_t *pProp, strm_t *pStrm)
+ 	if(c != '\n') ABORT_FINALIZE(RS_RET_INVALID_PROPFRAME);
+ 
+ finalize_it:
++	/* ensure the type of var is reset back to VARTYPE_NONE since
++	* the deconstruct method of var might free unallocated memory
++	*/
++	if(iRet != RS_RET_OK && iRet != RS_RET_NO_PROPLINE) {
++		if(step <= 2) {
++			pProp->varType = VARTYPE_NONE;
++		}
++	}
+ 	if(Debug && iRet != RS_RET_OK && iRet != RS_RET_NO_PROPLINE) {
+ 		strm.GetCurrOffset(pStrm, &offs);
+ 		dbgprintf("error %d deserializing property name, offset %lld, step %d\n",
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1600171-omelastic-ES6.patch b/SOURCES/rsyslog-8.24.0-rhbz1600171-omelastic-ES6.patch
new file mode 100644
index 0000000..4948349
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1600171-omelastic-ES6.patch
@@ -0,0 +1,34 @@
+From 8aca362e812827501f0545f4abea140f89fa87e3 Mon Sep 17 00:00:00 2001
+From: Rich Megginson <rmeggins@redhat.com>
+Date: Mon, 16 Jul 2018 15:55:35 -0600
+Subject: [PATCH] Bug 1600171 - Rsyslog omelasticsearch does not work with ES
+ 6.x strict headers
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1600171
+I did not attempt to backport all of the commits that
+touched this particular code, just the code that uses
+the macro for the content type.
+---
+ plugins/omelasticsearch/omelasticsearch.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c
+index 248a369d2..feb6425f7 100644
+--- a/plugins/omelasticsearch/omelasticsearch.c
++++ b/plugins/omelasticsearch/omelasticsearch.c
+@@ -1607,10 +1607,11 @@ curlPostSetup(CURL *handle, HEADER *header, uchar* authBuf, wrkrInstanceData_t *
+ 		curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile);
+ }
+ 
++#define CONTENT_JSON "Content-Type: application/json; charset=utf-8"
+ static rsRetVal
+ curlSetup(wrkrInstanceData_t *pWrkrData, instanceData *pData)
+ {
+-	pWrkrData->curlHeader = curl_slist_append(NULL, "Content-Type: text/json; charset=utf-8");
++	pWrkrData->curlHeader = curl_slist_append(NULL, CONTENT_JSON);
+ 	pWrkrData->curlPostHandle = curl_easy_init();
+ 	if (pWrkrData->curlPostHandle == NULL) {
+ 		return RS_RET_OBJ_CREATION_FAILED;
+-- 
+2.17.1
+
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1627799-cert-chains.patch b/SOURCES/rsyslog-8.24.0-rhbz1627799-cert-chains.patch
new file mode 100644
index 0000000..b90850e
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1627799-cert-chains.patch
@@ -0,0 +1,622 @@
+diff -up rsyslog-8.24.0/plugins/imtcp/imtcp.c.v36tls rsyslog-8.24.0/plugins/imtcp/imtcp.c
+--- rsyslog-8.24.0/plugins/imtcp/imtcp.c.v36tls	2019-08-19 17:37:07.872166694 +0100
++++ rsyslog-8.24.0/plugins/imtcp/imtcp.c	2019-08-19 17:37:07.876166693 +0100
+@@ -100,6 +100,7 @@ static struct configSettings_s {
+ 	int bDisableLFDelim;
+ 	int bUseFlowControl;
+ 	int bPreserveCase;
++	uchar *gnutlsPriorityString;
+ 	uchar *pszStrmDrvrAuthMode;
+ 	uchar *pszInputName;
+ 	uchar *pszBindRuleset;
+@@ -136,6 +137,7 @@ struct modConfData_s {
+ 	int iKeepAliveProbes;
+ 	int iKeepAliveTime;
+ 	sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */
++	uchar *gnutlsPriorityString;
+ 	uchar *pszStrmDrvrName; /* stream driver to use */
+ 	uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
+ 	struct cnfarray *permittedPeers;
+@@ -164,7 +166,8 @@ static struct cnfparamdescr modpdescr[]
+ 	{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
+ 	{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
+ 	{ "keepalive.interval", eCmdHdlrPositiveInt, 0 },
+-	{ "preservecase", eCmdHdlrBinary, 0 }
++	{ "preservecase", eCmdHdlrBinary, 0 },
++	{ "gnutlsprioritystring", eCmdHdlrString, 0 }
+ };
+ static struct cnfparamblk modpblk =
+ 	{ CNFPARAMBLK_VERSION,
+@@ -354,6 +357,7 @@ addListner(modConfData_t *modConf, insta
+ 		CHKiRet(tcpsrv.SetKeepAliveIntvl(pOurTcpsrv, modConf->iKeepAliveIntvl));
+ 		CHKiRet(tcpsrv.SetKeepAliveProbes(pOurTcpsrv, modConf->iKeepAliveProbes));
+ 		CHKiRet(tcpsrv.SetKeepAliveTime(pOurTcpsrv, modConf->iKeepAliveTime));
++		CHKiRet(tcpsrv.SetGnutlsPriorityString(pOurTcpsrv, modConf->gnutlsPriorityString));
+ 		CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, modConf->iTCPSessMax));
+ 		CHKiRet(tcpsrv.SetLstnMax(pOurTcpsrv, modConf->iTCPLstnMax));
+ 		CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, modConf->iStrmDrvrMode));
+@@ -463,6 +467,7 @@ CODESTARTbeginCnfLoad
+ 	loadModConf->bEmitMsgOnClose = 0;
+ 	loadModConf->iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
+ 	loadModConf->bDisableLFDelim = 0;
++	loadModConf->gnutlsPriorityString = NULL;
+ 	loadModConf->pszStrmDrvrName = NULL;
+ 	loadModConf->pszStrmDrvrAuthMode = NULL;
+ 	loadModConf->permittedPeers = NULL;
+@@ -517,6 +522,8 @@ CODESTARTsetModCnf
+ 			loadModConf->iKeepAliveTime = (int) pvals[i].val.d.n;
+ 		} else if(!strcmp(modpblk.descr[i].name, "keepalive.interval")) {
+ 			loadModConf->iKeepAliveIntvl = (int) pvals[i].val.d.n;
++		} else if(!strcmp(modpblk.descr[i].name, "gnutlsprioritystring")) {
++			loadModConf->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ 		} else if(!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
+ 			loadModConf->iStrmDrvrMode = (int) pvals[i].val.d.n;
+ 		} else if(!strcmp(modpblk.descr[i].name, "streamdriver.authmode")) {
+diff -up rsyslog-8.24.0/runtime/netstrm.c.v36tls rsyslog-8.24.0/runtime/netstrm.c
+--- rsyslog-8.24.0/runtime/netstrm.c.v36tls	2017-01-10 09:00:04.000000000 +0000
++++ rsyslog-8.24.0/runtime/netstrm.c	2019-08-19 17:37:07.876166693 +0100
+@@ -280,6 +280,16 @@ SetKeepAliveIntvl(netstrm_t *pThis, int
+ 	RETiRet;
+ }
+ 
++/* gnutls priority string */
++static rsRetVal
++SetGnutlsPriorityString(netstrm_t *pThis, uchar *gnutlsPriorityString)
++{
++	DEFiRet;
++	ISOBJ_TYPE_assert(pThis, netstrm);
++	iRet = pThis->Drvr.SetGnutlsPriorityString(pThis->pDrvrData, gnutlsPriorityString);
++	RETiRet;
++}
++
+ /* check connection - slim wrapper for NSD driver function */
+ static rsRetVal
+ CheckConnection(netstrm_t *pThis)
+@@ -387,6 +397,7 @@ CODESTARTobjQueryInterface(netstrm)
+ 	pIf->SetKeepAliveProbes = SetKeepAliveProbes;
+ 	pIf->SetKeepAliveTime = SetKeepAliveTime;
+ 	pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
++	pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ finalize_it:
+ ENDobjQueryInterface(netstrm)
+ 
+diff -up rsyslog-8.24.0/runtime/netstrm.h.v36tls rsyslog-8.24.0/runtime/netstrm.h
+--- rsyslog-8.24.0/runtime/netstrm.h.v36tls	2017-01-10 09:00:04.000000000 +0000
++++ rsyslog-8.24.0/runtime/netstrm.h	2019-08-19 17:37:07.876166693 +0100
+@@ -75,14 +75,16 @@ BEGINinterface(netstrm) /* name must als
+ 	rsRetVal (*SetKeepAliveProbes)(netstrm_t *pThis, int keepAliveProbes);
+ 	rsRetVal (*SetKeepAliveTime)(netstrm_t *pThis, int keepAliveTime);
+ 	rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl);
++	rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString);
+ ENDinterface(netstrm)
+-#define netstrmCURR_IF_VERSION 8 /* increment whenever you change the interface structure! */
++#define netstrmCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */
+ /* interface version 3 added GetRemAddr()
+  * interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02
+  * interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
+  * interface version 6 changed signature of GetRemoteIP() -- rgerhards, 2013-01-21
+  * interface version 7 added KeepAlive parameter set functions
+  * interface version 8 changed signature of Connect() -- dsa, 2016-11-14
++ * interface version 9 added SetGnutlsPriorityString -- PascalWithopf, 2017-08-08
+  * */
+ 
+ /* prototypes */
+diff -up rsyslog-8.24.0/runtime/netstrms.c.v36tls rsyslog-8.24.0/runtime/netstrms.c
+--- rsyslog-8.24.0/runtime/netstrms.c.v36tls	2016-12-03 17:41:03.000000000 +0000
++++ rsyslog-8.24.0/runtime/netstrms.c	2019-08-19 17:37:07.876166693 +0100
+@@ -113,6 +113,10 @@ CODESTARTobjDestruct(netstrms)
+ 		free(pThis->pBaseDrvrName);
+ 		pThis->pBaseDrvrName = NULL;
+ 	}
++	if(pThis->gnutlsPriorityString != NULL) {
++		free(pThis->gnutlsPriorityString);
++		pThis->gnutlsPriorityString = NULL;
++	}
+ ENDobjDestruct(netstrms)
+ 
+ 
+@@ -196,6 +200,31 @@ GetDrvrAuthMode(netstrms_t *pThis)
+ }
+ 
+ 
++/* Set the priorityString for GnuTLS
++ * PascalWithopf 2017-08-16
++ */
++static rsRetVal
++SetDrvrGnutlsPriorityString(netstrms_t *pThis, uchar *iVal)
++{
++	DEFiRet;
++	ISOBJ_TYPE_assert(pThis, netstrms);
++	CHKmalloc(pThis->gnutlsPriorityString = (uchar*)strdup((char*)iVal));
++finalize_it:
++	RETiRet;
++}
++
++
++/* return the priorityString for GnuTLS
++ * PascalWithopf, 2017-08-16
++ */
++static uchar*
++GetDrvrGnutlsPriorityString(netstrms_t *pThis)
++{
++	ISOBJ_TYPE_assert(pThis, netstrms);
++	return pThis->gnutlsPriorityString;
++}
++
++
+ /* set the driver mode -- rgerhards, 2008-04-30 */
+ static rsRetVal
+ SetDrvrMode(netstrms_t *pThis, int iMode)
+@@ -272,6 +301,8 @@ CODESTARTobjQueryInterface(netstrms)
+ 	pIf->GetDrvrMode = GetDrvrMode;
+ 	pIf->SetDrvrAuthMode = SetDrvrAuthMode;
+ 	pIf->GetDrvrAuthMode = GetDrvrAuthMode;
++	pIf->SetDrvrGnutlsPriorityString = SetDrvrGnutlsPriorityString;
++	pIf->GetDrvrGnutlsPriorityString = GetDrvrGnutlsPriorityString;
+ 	pIf->SetDrvrPermPeers = SetDrvrPermPeers;
+ 	pIf->GetDrvrPermPeers = GetDrvrPermPeers;
+ finalize_it:
+diff -up rsyslog-8.24.0/runtime/netstrms.h.v36tls rsyslog-8.24.0/runtime/netstrms.h
+--- rsyslog-8.24.0/runtime/netstrms.h.v36tls	2016-12-03 17:41:03.000000000 +0000
++++ rsyslog-8.24.0/runtime/netstrms.h	2019-08-19 17:37:07.876166693 +0100
+@@ -33,6 +33,7 @@ struct netstrms_s {
+ 	uchar *pDrvrName;	/**< full base driver name (set when driver is loaded) */
+ 	int iDrvrMode;		/**< current default driver mode */
+ 	uchar *pszDrvrAuthMode;	/**< current driver authentication mode */
++	uchar *gnutlsPriorityString; /**< priorityString for connection */
+ 	permittedPeers_t *pPermPeers;/**< current driver's permitted peers */
+ 
+ 	nsd_if_t Drvr;		/**< our stream driver */
+@@ -52,6 +53,8 @@ BEGINinterface(netstrms) /* name must al
+ 	int      (*GetDrvrMode)(netstrms_t *pThis);
+ 	uchar*   (*GetDrvrAuthMode)(netstrms_t *pThis);
+ 	permittedPeers_t* (*GetDrvrPermPeers)(netstrms_t *pThis);
++	rsRetVal (*SetDrvrGnutlsPriorityString)(netstrms_t *pThis, uchar*);
++	uchar*   (*GetDrvrGnutlsPriorityString)(netstrms_t *pThis);
+ ENDinterface(netstrms)
+ #define netstrmsCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+ 
+diff -up rsyslog-8.24.0/runtime/nsd_gtls.c.v36tls rsyslog-8.24.0/runtime/nsd_gtls.c
+--- rsyslog-8.24.0/runtime/nsd_gtls.c.v36tls	2017-01-10 09:00:04.000000000 +0000
++++ rsyslog-8.24.0/runtime/nsd_gtls.c	2019-08-19 17:39:30.576158227 +0100
+@@ -73,8 +73,20 @@ DEFobjCurrIf(nsd_ptcp)
+ 
+ static int bGlblSrvrInitDone = 0;	/**< 0 - server global init not yet done, 1 - already done */
+ 
+-static pthread_mutex_t mutGtlsStrerror; /**< a mutex protecting the potentially non-reentrant gtlStrerror() function */
++static pthread_mutex_t mutGtlsStrerror;
++/*< a mutex protecting the potentially non-reentrant gtlStrerror() function */
+ 
++/* a macro to abort if GnuTLS error is not acceptable. We split this off from
++ * CHKgnutls() to avoid some Coverity report in cases where we know GnuTLS
++ * failed. Note: gnuRet must already be set accordingly!
++ */
++#define ABORTgnutls { \
++		uchar *pErr = gtlsStrerror(gnuRet); \
++		LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", \
++	gnuRet, __FILE__, __LINE__, pErr); \
++		free(pErr); \
++		ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \
++}
+ /* a macro to check GnuTLS calls against unexpected errors */
+ #define CHKgnutls(x) { \
+ 	gnuRet = (x); \
+@@ -82,10 +94,7 @@ static pthread_mutex_t mutGtlsStrerror;
+ 		errmsg.LogError(0, RS_RET_GNUTLS_ERR, "error reading file - a common cause is that the file  does not exist"); \
+ 		ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \
+ 	} else if(gnuRet != 0) { \
+-		uchar *pErr = gtlsStrerror(gnuRet); \
+-		errmsg.LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \
+-		free(pErr); \
+-		ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \
++		ABORTgnutls; \
+ 	} \
+ }
+ 
+@@ -192,9 +201,12 @@ gtlsLoadOurCertKey(nsd_gtls_t *pThis)
+ 
+ 	/* try load certificate */
+ 	CHKiRet(readFile(certFile, &data));
+-	CHKgnutls(gnutls_x509_crt_init(&pThis->ourCert));
+-	pThis->bOurCertIsInit = 1;
+-	CHKgnutls(gnutls_x509_crt_import(pThis->ourCert, &data, GNUTLS_X509_FMT_PEM));
++	pThis->nOurCerts = sizeof(pThis->pOurCerts) / sizeof(gnutls_x509_crt_t);
++	gnuRet = gnutls_x509_crt_list_import(pThis->pOurCerts, &pThis->nOurCerts,
++		&data, GNUTLS_X509_FMT_PEM,  GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
++	if(gnuRet < 0) {
++		ABORTgnutls;
++	}
+ 	free(data.data);
+ 	data.data = NULL;
+ 
+@@ -210,7 +222,9 @@ finalize_it:
+ 		if(data.data != NULL)
+ 			free(data.data);
+ 		if(pThis->bOurCertIsInit) {
+-			gnutls_x509_crt_deinit(pThis->ourCert);
++			for(unsigned i=0; i<pThis->nOurCerts; ++i) {
++				gnutls_x509_crt_deinit(pThis->pOurCerts[i]);
++			}
+ 			pThis->bOurCertIsInit = 0;
+ 		}
+ 		if(pThis->bOurKeyIsInit) {
+@@ -255,8 +269,8 @@ gtlsClientCertCallback(gnutls_session_t
+ #else
+ 	st->type = GNUTLS_CRT_X509;
+ #endif
+-	st->ncerts = 1;
+-	st->cert.x509 = &pThis->ourCert;
++	st->ncerts = pThis->nOurCerts;
++	st->cert.x509 = pThis->pOurCerts;
+ 	st->key.x509 = pThis->ourKey;
+ 	st->deinit_all = 0;
+ 
+@@ -532,8 +546,8 @@ gtlsRecordRecv(nsd_gtls_t *pThis)
+ 		dbgprintf("GnuTLS receive requires a retry (this most probably is OK and no error condition)\n");
+ 		ABORT_FINALIZE(RS_RET_RETRY);
+ 	} else {
+-		int gnuRet; /* TODO: build a specific function for GnuTLS error reporting */
+-		CHKgnutls(lenRcvd); /* this will abort the function */
++		int gnuRet = lenRcvd;
++		ABORTgnutls;
+ 	}
+ 
+ finalize_it:
+@@ -646,7 +660,7 @@ gtlsInitSession(nsd_gtls_t *pThis)
+ 	pThis->bIsInitiator = 0;
+ 
+ 	/* avoid calling all the priority functions, since the defaults are adequate. */
+-	CHKgnutls(gnutls_set_default_priority(session));
++
+ 	CHKgnutls(gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred));
+ 
+ 	/* request client certificate if any.  */
+@@ -1204,7 +1218,9 @@ CODESTARTobjDestruct(nsd_gtls)
+ 	}
+ 
+ 	if(pThis->bOurCertIsInit)
+-		gnutls_x509_crt_deinit(pThis->ourCert);
++                for(unsigned i=0; i<pThis->nOurCerts; ++i) {
++			gnutls_x509_crt_deinit(pThis->pOurCerts[i]);
++                }
+ 	if(pThis->bOurKeyIsInit)
+ 		gnutls_x509_privkey_deinit(pThis->ourKey);
+ 	if(pThis->bHaveSess)
+@@ -1299,6 +1315,21 @@ finalize_it:
+ }
+ 
+ 
++/* gnutls priority string
++ * PascalWithopf 2017-08-16
++ */
++static rsRetVal
++SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString)
++{
++	DEFiRet;
++	nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
++
++	ISOBJ_TYPE_assert((pThis), nsd_gtls);
++	pThis->gnutlsPriorityString = gnutlsPriorityString;
++	RETiRet;
++}
++
++
+ /* Provide access to the underlying OS socket. This is primarily
+  * useful for other drivers (like nsd_gtls) who utilize ourselfs
+  * for some of their functionality. -- rgerhards, 2008-04-18
+@@ -1476,6 +1507,7 @@ AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew
+ 	int gnuRet;
+ 	nsd_gtls_t *pNew = NULL;
+ 	nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
++	const char *error_position;
+ 
+ 	ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ 	CHKiRet(nsd_gtlsConstruct(&pNew)); // TODO: prevent construct/destruct!
+@@ -1493,6 +1525,19 @@ AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew
+ 	gtlsSetTransportPtr(pNew, ((nsd_ptcp_t*) (pNew->pTcp))->sock);
+ 	pNew->authMode = pThis->authMode;
+ 	pNew->pPermPeers = pThis->pPermPeers;
++	pNew->gnutlsPriorityString = pThis->gnutlsPriorityString;
++	/* here is the priorityString set */
++	if(pNew->gnutlsPriorityString != NULL) {
++		if(gnutls_priority_set_direct(pNew->sess,
++					(const char*) pNew->gnutlsPriorityString,
++					&error_position)==GNUTLS_E_INVALID_REQUEST) {
++			LogError(0, RS_RET_GNUTLS_ERR, "Syntax Error in"
++					" Priority String: \"%s\"\n", error_position);
++		}
++	} else {
++		/* Use default priorities */
++		CHKgnutls(gnutls_set_default_priority(pNew->sess));
++	}
+ 
+ 	/* we now do the handshake. This is a bit complicated, because we are 
+ 	 * on non-blocking sockets. Usually, the handshake will not complete
+@@ -1673,6 +1718,31 @@ EnableKeepAlive(nsd_t *pNsd)
+ 	return nsd_ptcp.EnableKeepAlive(pThis->pTcp);
+ }
+ 
++/*
++ * SNI should not be used if the hostname is a bare IP address
++ */
++static int
++SetServerNameIfPresent(nsd_gtls_t *pThis, uchar *host) {
++	struct sockaddr_in sa;
++	struct sockaddr_in6 sa6;
++
++	int inet_pton_ret = inet_pton(AF_INET, CHAR_CONVERT(host), &(sa.sin_addr));
++
++	if (inet_pton_ret == 0) { // host wasn't a bare IPv4 address: try IPv6
++		inet_pton_ret = inet_pton(AF_INET6, CHAR_CONVERT(host), &(sa6.sin6_addr));
++	}
++
++	switch(inet_pton_ret) {
++		case 1: // host is a valid IP address: don't use SNI
++			return 0;
++		case 0: // host isn't a valid IP address: assume it's a domain name, use SNI
++			return gnutls_server_name_set(pThis->sess, GNUTLS_NAME_DNS, host, ustrlen(host));
++		default: // unexpected error
++			return -1;
++	}
++
++}
++
+ /* open a connection to a remote host (server). With GnuTLS, we always
+  * open a plain tcp socket and then, if in TLS mode, do a handshake on it.
+  * rgerhards, 2008-03-19
+@@ -1685,6 +1755,7 @@ Connect(nsd_t *pNsd, int family, uchar *
+ 	nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ 	int sock;
+ 	int gnuRet;
++	const char *error_position;
+ #	ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY
+ 	static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 };
+ #	endif
+@@ -1704,6 +1775,8 @@ Connect(nsd_t *pNsd, int family, uchar *
+ 	pThis->bHaveSess = 1;
+ 	pThis->bIsInitiator = 1;
+ 
++	CHKgnutls(SetServerNameIfPresent(pThis, host));
++
+ 	/* in the client case, we need to set a callback that ensures our certificate
+ 	 * will be presented to the server even if it is not signed by one of the server's
+ 	 * trusted roots. This is necessary to support fingerprint authentication.
+@@ -1721,8 +1794,19 @@ Connect(nsd_t *pNsd, int family, uchar *
+ 		FINALIZE; /* we have an error case! */
+ 	}
+ 
+-	/* Use default priorities */
+-	CHKgnutls(gnutls_set_default_priority(pThis->sess));
++	/*priority string setzen*/
++	if(pThis->gnutlsPriorityString != NULL) {
++		if(gnutls_priority_set_direct(pThis->sess,
++					(const char*) pThis->gnutlsPriorityString,
++					&error_position)==GNUTLS_E_INVALID_REQUEST) {
++			LogError(0, RS_RET_GNUTLS_ERR, "Syntax Error in"
++					" Priority String: \"%s\"\n", error_position);
++		}
++	} else {
++		/* Use default priorities */
++		CHKgnutls(gnutls_set_default_priority(pThis->sess));
++	}
++
+ #	ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY
+ 	/* The gnutls_certificate_type_set_priority function is deprecated
+ 	 * and not available in recent GnuTLS versions. However, there is no
+@@ -1806,6 +1890,7 @@ CODESTARTobjQueryInterface(nsd_gtls)
+ 	pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
+ 	pIf->SetKeepAliveProbes = SetKeepAliveProbes;
+ 	pIf->SetKeepAliveTime = SetKeepAliveTime;
++	pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ finalize_it:
+ ENDobjQueryInterface(nsd_gtls)
+ 
+diff -up rsyslog-8.24.0/runtime/nsd_gtls.h.v36tls rsyslog-8.24.0/runtime/nsd_gtls.h
+--- rsyslog-8.24.0/runtime/nsd_gtls.h.v36tls	2016-12-03 17:41:03.000000000 +0000
++++ rsyslog-8.24.0/runtime/nsd_gtls.h	2019-08-19 17:37:07.878166693 +0100
+@@ -25,6 +25,7 @@
+ #include "nsd.h"
+ 
+ #define NSD_GTLS_MAX_RCVBUF 8 * 1024 /* max size of buffer for message reception */
++#define NSD_GTLS_MAX_CERT 10 /* max number of certs in our chain */
+ 
+ typedef enum {
+ 	gtlsRtry_None = 0,	/**< no call needs to be retried */
+@@ -56,7 +57,10 @@ struct nsd_gtls_s {
+ 				 * set to 1 and changed to 0 after the first report. It is changed back to 1 after
+ 				 * one successful authentication. */
+ 	permittedPeers_t *pPermPeers; /* permitted peers */
+-	gnutls_x509_crt_t ourCert;	/**< our certificate, if in client mode (unused in server mode) */
++	uchar *gnutlsPriorityString;	/* gnutls priority string */
++	gnutls_x509_crt_t pOurCerts[NSD_GTLS_MAX_CERT];	/**< our certificate, if in client mode
++							(unused in server mode) */
++	unsigned int nOurCerts;  /* number of certificates in our chain */
+ 	gnutls_x509_privkey_t ourKey;	/**< our private key, if in client mode (unused in server mode) */
+ 	short	bOurCertIsInit;	/**< 1 if our certificate is initialized and must be deinit on destruction */
+ 	short	bOurKeyIsInit;	/**< 1 if our private key is initialized and must be deinit on destruction */
+diff -up rsyslog-8.24.0/runtime/nsd.h.v36tls rsyslog-8.24.0/runtime/nsd.h
+--- rsyslog-8.24.0/runtime/nsd.h.v36tls	2017-01-10 09:00:04.000000000 +0000
++++ rsyslog-8.24.0/runtime/nsd.h	2019-08-19 17:37:07.878166693 +0100
+@@ -83,14 +83,17 @@ BEGINinterface(nsd) /* name must also be
+ 	rsRetVal (*SetKeepAliveIntvl)(nsd_t *pThis, int keepAliveIntvl);
+ 	rsRetVal (*SetKeepAliveProbes)(nsd_t *pThis, int keepAliveProbes);
+ 	rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime);
++	/* v10 */
++	rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString);
+ ENDinterface(nsd)
+-#define nsdCURR_IF_VERSION 9 /* increment whenever you change the interface structure! */
++#define nsdCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */
+ /* interface version 4 added GetRemAddr()
+  * interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02
+  * interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06
+  * interface version 7 changed signature ofGetRempoteIP() -- rgerhards, 2013-01-21
+  * interface version 8 added keep alive parameter set functions
+  * interface version 9 changed signature of Connect() -- dsa, 2016-11-14
++ * interface version 10 added SetGnutlsPriorityString() -- PascalWithopf, 2017-08-08
+  */
+ 
+ /* interface  for the select call */
+diff -up rsyslog-8.24.0/runtime/nsd_ptcp.c.v36tls rsyslog-8.24.0/runtime/nsd_ptcp.c
+--- rsyslog-8.24.0/runtime/nsd_ptcp.c.v36tls	2017-01-10 09:00:04.000000000 +0000
++++ rsyslog-8.24.0/runtime/nsd_ptcp.c	2019-08-19 17:37:07.879166693 +0100
+@@ -176,6 +176,23 @@ finalize_it:
+ }
+ 
+ 
++/* Set priorityString
++ * PascalWithopf 2017-08-18 */
++static rsRetVal
++SetGnutlsPriorityString(nsd_t __attribute__((unused)) *pNsd, uchar *iVal)
++{
++	DEFiRet;
++	if(iVal != NULL) {
++		LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: "
++		"gnutlsPriorityString '%s' not supported by ptcp netstream "
++		"driver", iVal);
++		ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
++	}
++finalize_it:
++	RETiRet;
++}
++
++
+ /* Set the permitted peers. This is a dummy, always returning an
+  * error because we do not support fingerprint authentication.
+  * rgerhards, 2008-05-17
+@@ -535,6 +552,7 @@ LstnInit(netstrms_t *pNS, void *pUsr, rs
+ 		CHKiRet(pNS->Drvr.SetMode(pNewNsd, netstrms.GetDrvrMode(pNS)));
+ 		CHKiRet(pNS->Drvr.SetAuthMode(pNewNsd, netstrms.GetDrvrAuthMode(pNS)));
+ 		CHKiRet(pNS->Drvr.SetPermPeers(pNewNsd, netstrms.GetDrvrPermPeers(pNS)));
++		CHKiRet(pNS->Drvr.SetGnutlsPriorityString(pNewNsd, netstrms.GetDrvrGnutlsPriorityString(pNS)));
+ 		CHKiRet(netstrms.CreateStrm(pNS, &pNewStrm));
+ 		pNewStrm->pDrvrData = (nsd_t*) pNewNsd;
+ 		pNewNsd = NULL;
+@@ -854,6 +872,7 @@ CODESTARTobjQueryInterface(nsd_ptcp)
+ 	pIf->SetSock = SetSock;
+ 	pIf->SetMode = SetMode;
+ 	pIf->SetAuthMode = SetAuthMode;
++	pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ 	pIf->SetPermPeers = SetPermPeers;
+ 	pIf->Rcv = Rcv;
+ 	pIf->Send = Send;
+diff -up rsyslog-8.24.0/runtime/tcpsrv.c.v36tls rsyslog-8.24.0/runtime/tcpsrv.c
+--- rsyslog-8.24.0/runtime/tcpsrv.c.v36tls	2019-08-19 17:37:07.874166693 +0100
++++ rsyslog-8.24.0/runtime/tcpsrv.c	2019-08-19 17:37:07.880166693 +0100
+@@ -470,6 +470,9 @@ SessAccept(tcpsrv_t *pThis, tcpLstnPortL
+ 	}
+ 
+ 	/* we found a free spot and can construct our session object */
++	if(pThis->gnutlsPriorityString != NULL) {
++		CHKiRet(netstrm.SetGnutlsPriorityString(pNewStrm, pThis->gnutlsPriorityString));
++	}
+ 	CHKiRet(tcps_sess.Construct(&pSess));
+ 	CHKiRet(tcps_sess.SetTcpsrv(pSess, pThis));
+ 	CHKiRet(tcps_sess.SetLstnInfo(pSess, pLstnInfo));
+@@ -1001,6 +1004,8 @@ tcpsrvConstructFinalize(tcpsrv_t *pThis)
+ 		CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode));
+ 	if(pThis->pPermPeers != NULL)
+ 		CHKiRet(netstrms.SetDrvrPermPeers(pThis->pNS, pThis->pPermPeers));
++	if(pThis->gnutlsPriorityString != NULL)
++		CHKiRet(netstrms.SetDrvrGnutlsPriorityString(pThis->pNS, pThis->gnutlsPriorityString));
+ 	CHKiRet(netstrms.ConstructFinalize(pThis->pNS));
+ 
+ 	/* set up listeners */
+@@ -1173,6 +1178,16 @@ SetKeepAliveTime(tcpsrv_t *pThis, int iV
+ }
+ 
+ static rsRetVal
++SetGnutlsPriorityString(tcpsrv_t *pThis, uchar *iVal)
++{
++	DEFiRet;
++	DBGPRINTF("tcpsrv: gnutlsPriorityString set to %s\n",
++		(iVal == NULL) ? "(null)" : (const char*) iVal);
++	pThis->gnutlsPriorityString = iVal;
++	RETiRet;
++}
++
++static rsRetVal
+ SetOnMsgReceive(tcpsrv_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t*, uchar*, int))
+ {
+ 	DEFiRet;
+@@ -1414,6 +1429,7 @@ CODESTARTobjQueryInterface(tcpsrv)
+ 	pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
+ 	pIf->SetKeepAliveProbes = SetKeepAliveProbes;
+ 	pIf->SetKeepAliveTime = SetKeepAliveTime;
++	pIf->SetGnutlsPriorityString = SetGnutlsPriorityString;
+ 	pIf->SetUsrP = SetUsrP;
+ 	pIf->SetInputName = SetInputName;
+ 	pIf->SetOrigin = SetOrigin;
+diff -up rsyslog-8.24.0/runtime/tcpsrv.h.v36tls rsyslog-8.24.0/runtime/tcpsrv.h
+--- rsyslog-8.24.0/runtime/tcpsrv.h.v36tls	2019-08-19 17:37:07.874166693 +0100
++++ rsyslog-8.24.0/runtime/tcpsrv.h	2019-08-19 17:37:07.880166693 +0100
+@@ -61,6 +61,7 @@ struct tcpsrv_s {
+ 	int iKeepAliveTime;	/**< socket layer KEEPALIVE timeout */
+ 	netstrms_t *pNS;	/**< pointer to network stream subsystem */
+ 	int iDrvrMode;		/**< mode of the stream driver to use */
++	uchar *gnutlsPriorityString;	/**< priority string for gnutls */
+ 	uchar *pszDrvrAuthMode;	/**< auth mode of the stream driver to use */
+ 	uchar *pszDrvrName;	/**< name of stream driver to use */
+ 	uchar *pszInputName;	/**< value to be used as input name */
+@@ -169,6 +170,8 @@ BEGINinterface(tcpsrv) /* name must also
+ 	rsRetVal (*SetKeepAliveTime)(tcpsrv_t*, int);
+ 	/* added v18 */
+ 	rsRetVal (*SetbSPFramingFix)(tcpsrv_t*, sbool);
++	/* added v19 -- PascalWithopf, 2017-08-08 */
++	rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t*, uchar*);
+ 	/* added v21 -- Preserve case in fromhost, 2018-08-16 */
+ 	rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase);
+ ENDinterface(tcpsrv)
+diff -up rsyslog-8.24.0/tools/omfwd.c.v36tls rsyslog-8.24.0/tools/omfwd.c
+--- rsyslog-8.24.0/tools/omfwd.c.v36tls	2019-08-19 17:37:07.848166695 +0100
++++ rsyslog-8.24.0/tools/omfwd.c	2019-08-19 17:37:07.881166693 +0100
+@@ -91,6 +91,7 @@ typedef struct _instanceData {
+ 	int iKeepAliveIntvl;
+ 	int iKeepAliveProbes;
+ 	int iKeepAliveTime;
++	uchar *gnutlsPriorityString;
+ 
+ #	define	FORW_UDP 0
+ #	define	FORW_TCP 1
+@@ -138,6 +139,7 @@ typedef struct configSettings_s {
+ 	int iKeepAliveIntvl;
+ 	int iKeepAliveProbes;
+ 	int iKeepAliveTime;
++	uchar *gnutlsPriorityString;
+ 	permittedPeers_t *pPermPeers;
+ } configSettings_t;
+ static configSettings_t cs;
+@@ -169,6 +171,7 @@ static struct cnfparamdescr actpdescr[]
+ 	{ "keepalive.probes", eCmdHdlrPositiveInt, 0 },
+ 	{ "keepalive.time", eCmdHdlrPositiveInt, 0 },
+ 	{ "keepalive.interval", eCmdHdlrPositiveInt, 0 },
++	{ "gnutlsprioritystring", eCmdHdlrString, 0 },
+ 	{ "streamdriver", eCmdHdlrGetWord, 0 },
+ 	{ "streamdrivermode", eCmdHdlrInt, 0 },
+ 	{ "streamdriverauthmode", eCmdHdlrGetWord, 0 },
+@@ -717,6 +720,9 @@ static rsRetVal TCPSendInit(void *pvData
+ 			CHKiRet(netstrm.SetDrvrPermPeers(pWrkrData->pNetstrm, pData->pPermPeers));
+ 		}
+ 		/* params set, now connect */
++		if(pData->gnutlsPriorityString != NULL) {
++			CHKiRet(netstrm.SetGnutlsPriorityString(pWrkrData->pNetstrm, pData->gnutlsPriorityString));
++		}
+ 		CHKiRet(netstrm.Connect(pWrkrData->pNetstrm, glbl.GetDefPFFamily(),
+ 			(uchar*)pData->port, (uchar*)pData->target, pData->device));
+ 
+@@ -960,6 +966,7 @@ setInstParamDefaults(instanceData *pData
+ 	pData->iKeepAliveProbes = 0;
+ 	pData->iKeepAliveIntvl = 0;
+ 	pData->iKeepAliveTime = 0;
++	pData->gnutlsPriorityString = NULL;
+ 	pData->bResendLastOnRecon = 0; 
+ 	pData->bSendToAll = -1;  /* unspecified */
+ 	pData->iUDPSendDelay = 0;
+@@ -1046,6 +1053,8 @@ CODESTARTnewActInst
+ 			pData->iKeepAliveIntvl = (int) pvals[i].val.d.n;
+ 		} else if(!strcmp(actpblk.descr[i].name, "keepalive.time")) {
+ 			pData->iKeepAliveTime = (int) pvals[i].val.d.n;
++		} else if(!strcmp(actpblk.descr[i].name, "gnutlsprioritystring")) {
++			pData->gnutlsPriorityString = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ 		} else if(!strcmp(actpblk.descr[i].name, "streamdriver")) {
+ 			pData->pszStrmDrvr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ 		} else if(!strcmp(actpblk.descr[i].name, "streamdrivermode")) {
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1649250-imfile-rotation.patch b/SOURCES/rsyslog-8.24.0-rhbz1649250-imfile-rotation.patch
index 85cb451..c52abc1 100644
--- a/SOURCES/rsyslog-8.24.0-rhbz1649250-imfile-rotation.patch
+++ b/SOURCES/rsyslog-8.24.0-rhbz1649250-imfile-rotation.patch
@@ -142,7 +142,7 @@ index 2d494c612..5b52591ef 100644
 +checkTruncation(strm_t *const pThis)
 +{
 +	DEFiRet;
-+	int ret;
++	off64_t ret;
 +	off64_t backseek;
 +	assert(pThis->bReopenOnTruncate);
 +
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1684236-omelastic-sigsegv.patch b/SOURCES/rsyslog-8.24.0-rhbz1684236-omelastic-sigsegv.patch
new file mode 100644
index 0000000..2f839a6
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1684236-omelastic-sigsegv.patch
@@ -0,0 +1,65 @@
+From 48dd54fd6d1edeb5dcdde95935a3ca9d2a6ab52e Mon Sep 17 00:00:00 2001
+From: Rich Megginson <rmeggins@redhat.com>
+Date: Wed, 6 Mar 2019 10:23:28 -0700
+Subject: [PATCH] Bug 1684236 - rsyslog-8.24.0-34.el7.x86_64 SIGSEGV when using
+ rsyslog-elasticsearch-8.24.0-34
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1684236
+
+Cause: When omelasticsearch has a problem sending data to
+Elasticsearch because the connection was broken, the curl api
+returns an error code that was not being checked.  The
+omelasticsearch code also assumed that the reply field would
+always be allocated, but it is not in this error case.
+
+Consequence: rsyslog crashes when the connection to Elasticsearch
+is lost while attempting to send data to Elasticsearch.
+
+Fix: Check for the correct error code (CURLE_GOT_NOTHING), and
+also check that the reply field was allocated.
+
+Result: rsyslog does not crash when the connection to Elasticsearch
+is lost while attempting to send data to Elasticsearch.
+---
+ plugins/omelasticsearch/omelasticsearch.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c
+index 248a369d2..d0c3f91d5 100644
+--- a/plugins/omelasticsearch/omelasticsearch.c
++++ b/plugins/omelasticsearch/omelasticsearch.c
+@@ -1431,6 +1431,7 @@ curlPost(wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls
+ 	    || code == CURLE_COULDNT_RESOLVE_PROXY
+ 	    || code == CURLE_COULDNT_CONNECT
+ 	    || code == CURLE_WRITE_ERROR
++	    || code == CURLE_GOT_NOTHING
+ 	   ) {
+ 		STATSCOUNTER_INC(indexHTTPReqFail, mutIndexHTTPReqFail);
+ 		indexHTTPFail += nmsgs;
+@@ -1441,15 +1442,20 @@ curlPost(wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls
+ 	}
+ 
+ 	DBGPRINTF("omelasticsearch: pWrkrData replyLen = '%d'\n", pWrkrData->replyLen);
+-	if(pWrkrData->replyLen > 0) {
++	if(NULL != pWrkrData->reply) {
++	    if(pWrkrData->replyLen > 0) {
+ 		pWrkrData->reply[pWrkrData->replyLen] = '\0'; /* Append 0 Byte if replyLen is above 0 - byte has been reserved in malloc */
++	    }
++	    CHKiRet(checkResult(pWrkrData, message));
++	    DBGPRINTF("omelasticsearch: pWrkrData reply: '%s'\n", pWrkrData->reply);
++	} else {
++	    DBGPRINTF("omelasticsearch: pWrkrData reply is NULL\n");
+ 	}
+-	DBGPRINTF("omelasticsearch: pWrkrData reply: '%s'\n", pWrkrData->reply);
+ 
+-	CHKiRet(checkResult(pWrkrData, message));
+ finalize_it:
+ 	incrementServerIndex(pWrkrData);
+ 	free(pWrkrData->reply);
++	pWrkrData->reply = NULL;
+ 	RETiRet;
+ }
+ 
+-- 
+2.20.1
+
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1696686-imjournal-fsync.patch b/SOURCES/rsyslog-8.24.0-rhbz1696686-imjournal-fsync.patch
new file mode 100644
index 0000000..430dbd1
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1696686-imjournal-fsync.patch
@@ -0,0 +1,114 @@
+From 628d791b26062945fad4afa5985f6b84f46f16d4 Mon Sep 17 00:00:00 2001
+From: Jiri Vymazal <jvymazal@redhat.com>
+Date: Tue, 23 Jul 2019 11:28:31 +0200
+Subject: [PATCH] Add "fsync" option for imjournal
+
+The new option makes possible to force physical write of stateFile
+to persistent storage, ensuring we do not lose/duplicate messages
+in case of hard crash or power loss.
+---
+ plugins/imjournal/imjournal.c | 41 +++++++++++++++----
+ 1 file changed, 32 insertions(+), 9 deletitions(-)
+
+diff --git a/plugins/imjournal/imjournal.c b/plugins/imjournal/imjournal.c
+index 5739bf408c..6c8829243a 100644
+--- a/plugins/imjournal/imjournal.c
++++ b/plugins/imjournal/imjournal.c
+@@ -24,6 +24,7 @@
+ #include "config.h"
+ #include "rsyslog.h"
+ #include <stdio.h>
++#include <dirent.h>
+ #include <assert.h>
+ #include <string.h>
+ #include <stdarg.h>
+@@ -81,6 +82,7 @@ static struct configSettings_s {
+ 	int bUseJnlPID;
+ 	char *dfltTag;
+ 	int bWorkAroundJournalBug;
++	int bFsync;
+ } cs;
+ 
+ static rsRetVal facilityHdlr(uchar **pp, void *pVal);
+@@ -99,7 +99,8 @@ static struct cnfparamdescr modpdescr[] = {
+ 	{ "defaultfacility", eCmdHdlrString, 0 },
+ 	{ "usepidfromsystem", eCmdHdlrBinary, 0 },
+ 	{ "defaulttag", eCmdHdlrGetWord, 0 },
+-	{ "workaroundjournalbug", eCmdHdlrBinary, 0 }
++	{ "workaroundjournalbug", eCmdHdlrBinary, 0 },
++	{ "fsync", eCmdHdlrBinary, 0 }
+ };
+ static struct cnfparamblk modpblk =
+ 	{ CNFPARAMBLK_VERSION,
+@@ -437,7 +437,7 @@ persistJournalState(int trySave)
+ persistJournalState(int trySave)
+ {
+ 	DEFiRet;
+-	FILE *sf; /* state file */
++	FILE *sf = NULL; /* state file */
+ 	char tmp_sf[MAXFNAME];
+ 	int ret = 0;
+ 
+@@ -468,13 +468,6 @@ persistJournalState(int trySave)
+ 	ret = fputs(last_cursor, sf);
+ 	if (ret < 0) {
+ 		errmsg.LogError(errno, RS_RET_IO_ERROR, "imjournal: failed to save cursor to: '%s'", tmp_sf);
+-		ret = fclose(sf);
+-		ABORT_FINALIZE(RS_RET_IO_ERROR);
+-	}
+-
+-	ret = fclose(sf);
+-	if (ret < 0) {
+-		errmsg.LogError(errno, RS_RET_IO_ERROR, "imjournal: fclose() failed for path: '%s'", tmp_sf);
+ 		ABORT_FINALIZE(RS_RET_IO_ERROR);
+ 	}
+ 
+@@ -484,7 +477,30 @@ persistJournalState(int trySave)
+ 		ABORT_FINALIZE(RS_RET_IO_ERROR);
+ 	}
+ 
++	if (cs.bFsync) {
++		if (fsync(fileno(sf)) != 0) {
++			LogError(errno, RS_RET_IO_ERROR, "imjournal: fsync on '%s' failed", cs.stateFile);
++			ABORT_FINALIZE(RS_RET_IO_ERROR);
++		}
++		/* In order to guarantee physical write we need to force parent sync as well */
++		DIR *wd;
++		if (!(wd = opendir((char *)glbl.GetWorkDir()))) {
++			LogError(errno, RS_RET_IO_ERROR, "imjournal: failed to open '%s' directory", glbl.GetWorkDir());
++			ABORT_FINALIZE(RS_RET_IO_ERROR);
++		}
++		if (fsync(dirfd(wd)) != 0) {
++			LogError(errno, RS_RET_IO_ERROR, "imjournal: fsync on '%s' failed", glbl.GetWorkDir());
++			ABORT_FINALIZE(RS_RET_IO_ERROR);
++		}
++	}
++
+ finalize_it:
++	if (sf != NULL) {
++		if (fclose(sf) == EOF) {
++			LogError(errno, RS_RET_IO_ERROR, "imjournal: fclose() failed for path: '%s'", tmp_sf);
++			iRet = RS_RET_IO_ERROR;
++		}
++	}
+ 	RETiRet;
+ }
+ 
+@@ -746,6 +747,8 @@ CODESTARTbeginCnfLoad
+ 	cs.iDfltFacility = DFLT_FACILITY;
+ 	cs.dfltTag = NULL;
+ 	cs.bUseJnlPID = 0;
++	cs.bWorkAroundJournalBug = 0;
++	cs.bFsync = 0;
+ ENDbeginCnfLoad
+ 
+ 
+@@ -943,6 +963,8 @@ CODESTARTsetModCnf
+ 			cs.dfltTag = (char *)es_str2cstr(pvals[i].val.d.estr, NULL);
+ 		} else if (!strcmp(modpblk.descr[i].name, "workaroundjournalbug")) {
+ 			cs.bWorkAroundJournalBug = (int) pvals[i].val.d.n;
++		} else if (!strcmp(modpblk.descr[i].name, "fsync")) {
++			cs.bFsync = (int) pvals[i].val.d.n;
+ 		} else {
+ 			dbgprintf("imjournal: program error, non-handled "
+ 				"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1744682-ratelimiter-segfault.patch b/SOURCES/rsyslog-8.24.0-rhbz1744682-ratelimiter-segfault.patch
new file mode 100644
index 0000000..6089930
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1744682-ratelimiter-segfault.patch
@@ -0,0 +1,41 @@
+From b54769b4d8371ce1d60e3c43172a445336ec79b6 Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Mon, 24 Sep 2018 13:27:26 +0200
+Subject: [PATCH] bugfix imfile: segfault in ratelimiter
+
+imfile crashes inside rate limit processing, often when log
+files are rotated. However, this could occur in any case where
+the monitored files was closed by imfile, it rotation is just
+the most probable cause for this (moving the file to another
+directory or deleting it also can trigger the same issue, for
+example). The root cause was invalid sequence of operations.
+
+closes https://github.com/rsyslog/rsyslog/issues/3021
+---
+ plugins/imfile/imfile.c | 8 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
+index e710f7c44c..f4a4ef9b72 100644
+--- a/plugins/imfile/imfile.c
++++ b/plugins/imfile/imfile.c
+@@ -915,9 +915,6 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
+ 			}
+ 		}
+ 	}
+-	if(act->ratelimiter != NULL) {
+-		ratelimitDestruct(act->ratelimiter);
+-	}
+ 	if(act->pStrm != NULL) {
+ 		const instanceConf_t *const inst = act->edge->instarr[0];// TODO: same file, multiple instances?
+ 		pollFile(act); /* get any left-over data */
+@@ -934,6 +931,9 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
+ 			unlink((char*)statefn);
+ 		}
+ 	}
++	if(act->ratelimiter != NULL) {
++		ratelimitDestruct(act->ratelimiter);
++	}
+ 	#ifdef HAVE_INOTIFY_INIT
+ 	if(act->wd != -1) {
+ 		wdmapDel(act->wd);
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1746497-ratelimiter-segfault.patch b/SOURCES/rsyslog-8.24.0-rhbz1746497-ratelimiter-segfault.patch
deleted file mode 100644
index 6089930..0000000
--- a/SOURCES/rsyslog-8.24.0-rhbz1746497-ratelimiter-segfault.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From b54769b4d8371ce1d60e3c43172a445336ec79b6 Mon Sep 17 00:00:00 2001
-From: Rainer Gerhards <rgerhards@adiscon.com>
-Date: Mon, 24 Sep 2018 13:27:26 +0200
-Subject: [PATCH] bugfix imfile: segfault in ratelimiter
-
-imfile crashes inside rate limit processing, often when log
-files are rotated. However, this could occur in any case where
-the monitored files was closed by imfile, it rotation is just
-the most probable cause for this (moving the file to another
-directory or deleting it also can trigger the same issue, for
-example). The root cause was invalid sequence of operations.
-
-closes https://github.com/rsyslog/rsyslog/issues/3021
----
- plugins/imfile/imfile.c | 8 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
-index e710f7c44c..f4a4ef9b72 100644
---- a/plugins/imfile/imfile.c
-+++ b/plugins/imfile/imfile.c
-@@ -915,9 +915,6 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
- 			}
- 		}
- 	}
--	if(act->ratelimiter != NULL) {
--		ratelimitDestruct(act->ratelimiter);
--	}
- 	if(act->pStrm != NULL) {
- 		const instanceConf_t *const inst = act->edge->instarr[0];// TODO: same file, multiple instances?
- 		pollFile(act); /* get any left-over data */
-@@ -934,6 +931,9 @@ act_obj_destroy(act_obj_t *const act, const int is_deleted)
- 			unlink((char*)statefn);
- 		}
- 	}
-+	if(act->ratelimiter != NULL) {
-+		ratelimitDestruct(act->ratelimiter);
-+	}
- 	#ifdef HAVE_INOTIFY_INIT
- 	if(act->wd != -1) {
- 		wdmapDel(act->wd);
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1763746-file-id.patch b/SOURCES/rsyslog-8.24.0-rhbz1763746-file-id.patch
new file mode 100644
index 0000000..2238bfc
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1763746-file-id.patch
@@ -0,0 +1,602 @@
+From 70ea76962bfe9ffed2bd604898e43e0e3b17645d Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Thu, 23 Aug 2018 10:15:21 +0200
+Subject: [PATCH] omfile: implement file-id, used in state file
+
+This ensures that files with the same inodes are not accidently treated
+as equal, at least within the limits of the file id hash (see doc for
+details).
+
+We use the siphash reference implementation to generate our non-cryptographic
+hash.
+
+State file handling was invalid. When a file was moved and re-created
+rsyslog could use the file_id if the new file to write the old files'
+state file. This could make the file reader stuck until it reached the
+previous offset. Depending on file sizes this could never happen AND
+would cause large message loss. This situation was timing dependent
+(a race) and most frequently occurred under log rotation. In polling
+mode the bug was less likely, but could also occur.
+---
+ plugins/imfile/Makefile.am      |   2 +-
+ plugins/imfile/imfile.c         | 190 ++++++++++++++++++-----
+ plugins/imfile/siphash.c        | 185 ++++++++++++++++++++++++++++++++
+ 3 files changed, 381 insertions(+), 19 deletions(-)
+ create mode 100644 plugins/imfile/siphash.c
+
+diff --git a/plugins/imfile/Makefile.am b/plugins/imfile/Makefile.am
+index f4df0ed687..9e137efdc8 100644
+--- a/plugins/imfile/Makefile.am
++++ b/plugins/imfile/Makefile.am
+@@ -1,6 +1,6 @@
+ pkglib_LTLIBRARIES = imfile.la
+ 
+-imfile_la_SOURCES = imfile.c
++imfile_la_SOURCES = imfile.c siphash.c
+ imfile_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
+ imfile_la_LDFLAGS = -module -avoid-version
+ imfile_la_LIBADD = 
+diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
+index 4bc6078bda..14f4f1f495 100644
+--- a/plugins/imfile/imfile.c
++++ b/plugins/imfile/imfile.c
+@@ -66,6 +66,8 @@
+ MODULE_CNFNAME("imfile")
+ 
+ /* defines */
++#define FILE_ID_HASH_SIZE 20	/* max size of a file_id hash */
++#define FILE_ID_SIZE	512	/* how many bytes are used for file-id? */
+ 
+ /* Module static data */
+ DEF_IMOD_STATIC_DATA	/* must be present, starts static data */
+@@ -75,6 +77,9 @@
+ DEFobjCurrIf(prop)
+ DEFobjCurrIf(ruleset)
+ 
++extern int rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
++	uint8_t *out, const size_t outlen); /* see siphash.c */
++
+ static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
+ 
+ #define NUM_MULTISUB 1024 /* default max number of submits */
+@@ -155,8 +160,10 @@
+ 	int wd;
+ 	time_t timeoutBase; /* what time to calculate the timeout against? */
+ 	/* file dynamic data */
++	char file_id[FILE_ID_HASH_SIZE]; /* file id for this entry, once we could obtain it */
+ 	int in_move;	/* workaround for inotify move: if set, state file must not be deleted */
+ 	ino_t ino;	/* current inode nbr */
++	int fd;		/* fd to file in order to obtain file_id (needs to be preserved across move) */
+ 	strm_t *pStrm;	/* its stream (NULL if not assigned) */
+ 	int nRecords; /**< How many records did we process before persisting the stream? */
+ 	ratelimit_t *ratelimiter;
+@@ -187,7 +194,7 @@
+ static int getBasename(uchar *const __restrict__ basen, uchar *const __restrict__ path);
+ static void act_obj_unlink(act_obj_t *act);
+ static uchar * getStateFileName(const act_obj_t *, uchar *, const size_t);
+-static int getFullStateFileName(const uchar *const, uchar *const pszout, const size_t ilenout);
++static int getFullStateFileName(const uchar *const, const char *const, uchar *const pszout, const size_t ilenout);
+ 
+ 
+ #define OPMODE_POLLING 0
+@@ -328,7 +335,7 @@
+ 		  act->name, statefn);
+ 
+ 	/* Get full path and file name */
+-	lenSFNam = getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam));
++	lenSFNam = getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
+ 
+ 	/* check if the file exists */
+ 	if(stat((char*) pszSFNam, &stat_buf) == -1) {
+@@ -561,16 +568,25 @@
+                        }
+ 		}
+ 	}
++	DBGPRINTF("need to add new active object '%s' in '%s' - checking if accessible\n", name, edge->path);
++	const int fd = open(name, O_RDONLY | O_CLOEXEC);
++	if(fd < 0) {
++		if (is_file) { LogMsg(errno, RS_RET_ERR, LOG_WARNING, "imfile: error accessing file '%s'", name);
++		} else { DBGPRINTF("imfile: error accessing file '%s'", name); }
++		FINALIZE;
++	}
+ 	DBGPRINTF("add new active object '%s' in '%s'\n", name, edge->path);
+ 	CHKmalloc(act = calloc(sizeof(act_obj_t), 1));
+ 	CHKmalloc(act->name = strdup(name));
+-       if (-1 == getBasename((uchar*)basename, (uchar*)name)) {
+-               CHKmalloc(act->basename = strdup(name)); /* assume basename is same as name */
+-       } else {
+-               CHKmalloc(act->basename = strdup(basename));
+-       }
++	if (-1 == getBasename((uchar*)basename, (uchar*)name)) {
++		CHKmalloc(act->basename = strdup(name)); /* assume basename is same as name */
++	} else {
++		CHKmalloc(act->basename = strdup(basename));
++	}
+ 	act->edge = edge;
+ 	act->ino = ino;
++	act->fd = fd;
++	act->file_id[0] = '\0';
+ 	act->is_symlink = is_symlink;
+        if (source) { /* we are target of symlink */
+                CHKmalloc(act->source_name = strdup(source));
+@@ -813,7 +828,7 @@
+ 		pollFile(act); /* get any left-over data */
+ 		if(inst->bRMStateOnDel) {
+ 			statefn = getStateFileName(act, statefile, sizeof(statefile));
+-			getFullStateFileName(statefn, toDel, sizeof(toDel));
++			getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check!
+ 			statefn = toDel;
+ 		}
+ 		persistStrmState(act);
+@@ -832,6 +847,9 @@
+ 		wdmapDel(act->wd);
+ 	}
+ 	#endif
++	if(act->fd >= 0) {
++		close(act->fd);
++	}
+ 	#if defined(OS_SOLARIS) && defined (HAVE_PORT_SOURCE_FILE)
+ 	if(act->pfinf != NULL) {
+ 		free(act->pfinf->fobj.fo_name);
+@@ -1029,7 +1047,7 @@
+  * open or otherwise modify disk file state.
+  */
+ static int
+-getFullStateFileName(const uchar *const pszstatefile, uchar *const pszout, const size_t ilenout)
++getFullStateFileName(const uchar *const pszstatefile, const char *const file_id, uchar *const pszout, const size_t ilenout)
+ {
+ 	int lenout;
+ 	const uchar* pszworkdir;
+@@ -1038,14 +1056,69 @@
+ 	pszworkdir = glblGetWorkDirRaw();
+ 
+ 	/* Construct file name */
+-	lenout = snprintf((char*)pszout, ilenout, "%s/%s",
+-			     (char*) (pszworkdir == NULL ? "." : (char*) pszworkdir), (char*)pszstatefile);
++	lenout = snprintf((char*)pszout, ilenout, "%s/%s%s%s",
++		(char*) (pszworkdir == NULL ? "." : (char*) pszworkdir), (char*)pszstatefile,
++		(*file_id == '\0') ? "" : ":", file_id);
+ 
+ 	/* return out length */
+ 	return lenout;
+ }
+ 
+ 
++/* hash function for file-id
++ * Takes a block of data and returns a string with the hash value.
++ *
++ * Currently one provided by Aaaron Wiebe based on perl's hashing algorithm
++ * (so probably pretty generic). Not for excessively large strings!
++ * TODO: re-think the hash function!
++ */
++#if defined(__clang__)
++#pragma GCC diagnostic ignored "-Wunknown-attributes"
++#endif
++static void __attribute__((nonnull(1,3)))
++#if defined(__clang__)
++__attribute__((no_sanitize("unsigned-integer-overflow")))
++#endif
++get_file_id_hash(const char *data, size_t lendata,
++	char *const hash_str, const size_t len_hash_str)
++{
++	assert(len_hash_str >= 17); /* we always generate 8-byte strings */
++
++	size_t i;
++	uint8_t out[8], k[16];
++	for (i = 0; i < 16; ++i)
++		k[i] = i;
++	memset(out, 0, sizeof(out));
++	rs_siphash((const uint8_t *)data, lendata, k, out, 8);
++
++	for(i = 0 ; i < 8 ; ++i) {
++		if(2 * i+1 >= len_hash_str)
++			break;
++		snprintf(hash_str+(2*i), 3, "%2.2x", out[i]);
++	}
++}
++
++
++
++/* this returns the file-id for a given file
++ */
++static void getFileID(act_obj_t *const act)
++{
++	/* save the old id for cleaning purposes */
++	strncpy(act->file_id_prev, (const char*)act->file_id, FILE_ID_HASH_SIZE);
++	act->file_id[0] = '\0';
++	assert(act->fd >= 0); /* fd must have been opened at act_obj_t creation! */
++	char filedata[FILE_ID_SIZE];
++	lseek(act->fd, 0, SEEK_SET); /* Seek to beginning of file so we have correct id */
++	const int r = read(act->fd, filedata, FILE_ID_SIZE);
++	if(r == FILE_ID_SIZE) {
++		get_file_id_hash(filedata, sizeof(filedata), act->file_id, sizeof(act->file_id));
++	} else {
++		DBGPRINTF("getFileID partial or error read, ret %d\n", r);
++	}
++	DBGPRINTF("getFileID for '%s', file_id_hash '%s'\n", act->name, act->file_id);
++}
++
+ /* this generates a state file name suitable for the given file. To avoid
+  * malloc calls, it must be passed a buffer which should be MAXFNAME large.
+  * Note: the buffer is not necessarily populated ... always ONLY use the
+@@ -1060,7 +1135,7 @@
+ {
+ 	DBGPRINTF("getStateFileName for '%s'\n", act->name);
+ 	snprintf((char*)buf, lenbuf - 1, "imfile-state:%lld", (long long) act->ino);
+-	DBGPRINTF("getStateFileName:  stat file name now is %s\n", buf);
++	DBGPRINTF("getStateFileName:  state file name now is %s\n", buf);
+ 	return buf;
+ }
+ 
+@@ -1136,18 +1209,45 @@
+ 	const instanceConf_t *const inst = act->edge->instarr[0];// TODO: same file, multiple instances?
+ 
+ 	uchar *const statefn = getStateFileName(act, statefile, sizeof(statefile));
++	getFileID(act);
+ 
+-	getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam));
++	getFullStateFileName(statefn, act->file_id, pszSFNam, sizeof(pszSFNam));
+ 	DBGPRINTF("trying to open state for '%s', state file '%s'\n", act->name, pszSFNam);
+ 
+ 	/* check if the file exists */
+ 	fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
+ 	if(fd < 0) {
+ 		if(errno == ENOENT) {
+-			DBGPRINTF("NO state file (%s) exists for '%s' - trying to see if "
+-				"old-style file exists\n", pszSFNam, act->name);
+-			CHKiRet(OLD_openFileWithStateFile(act));
+-			FINALIZE;
++			if(act->file_id[0] != '\0') {
++				const char *pszSFNamHash = strdup((const char*)pszSFNam);
++				CHKmalloc(pszSFNamHash);
++				DBGPRINTF("state file %s for %s does not exist - trying to see if "
++					"inode-only file exists\n", pszSFNam, act->name);
++				getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
++				fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
++				if(fd >= 0) {
++					dbgprintf("found inode-only state file, renaming it now that we "
++						"know the file_id, new name: %s\n", pszSFNamHash);
++					/* we now can use identify the file, so let's rename it */
++					if(rename((const char*)pszSFNam, pszSFNamHash) != 0) {
++						LogError(errno, RS_RET_IO_ERROR,
++							"imfile error trying to rename state file for '%s' - "
++							"ignoring this error, usually this means a file no "
++							"longer file is left over, but this may also cause "
++							"some real trouble. Still the best we can do ",
++							act->name);
++						free((void*) pszSFNamHash);
++						ABORT_FINALIZE(RS_RET_IO_ERROR);
++					}
++				}
++				free((void*) pszSFNamHash);
++			}
++			if(fd < 0) {
++				DBGPRINTF("state file %s for %s does not exist - trying to see if "
++					"old-style file exists\n", pszSFNam, act->name);
++				CHKiRet(OLD_openFileWithStateFile(act));
++				FINALIZE;
++			}
+ 		} else {
+ 			LogError(errno, RS_RET_IO_ERROR,
+ 				"imfile error trying to access state file for '%s'",
+@@ -1156,6 +1256,7 @@
+ 		}
+ 	}
+ 
++	DBGPRINTF("opened state file %s for %s\n", pszSFNam, act->name);
+ 	CHKiRet(strm.Construct(&act->pStrm));
+ 
+ 	struct json_object *jval;
+@@ -1289,6 +1390,7 @@
+ {
+ 	int64 strtOffs;
+ 	DEFiRet;
++	int64_t startOffs = 0;
+ 	int nProcessed = 0;
+ 
+ 	DBGPRINTF("pollFileReal enter, pStrm %p, name '%s'\n", act->pStrm, act->name);
+@@ -1301,6 +1403,7 @@
+ 		CHKiRet(openFile(act)); /* open file */
+ 	}
+ 
++	startOffs = act->pStrm->iCurrOffs;	
+ 	/* loop below will be exited when strmReadLine() returns EOF */
+ 	while(glbl.GetGlobalInputTermState() == 0) {
+ 		if(inst->maxLinesAtOnce != 0 && nProcessed >= inst->maxLinesAtOnce)
+@@ -1313,6 +1416,11 @@
+ 				inst->escapeLF, &strtOffs));
+ 		}
+ 		++nProcessed;
++		if(startOffs < FILE_ID_SIZE && act->pStrm->iCurrOffs >= FILE_ID_SIZE) {
++			dbgprintf("initiating state file write as sufficient data is now present; file=%s\n", act->name);
++			persistStrmState(act);
++			startOffs = act->pStrm->iCurrOffs; /* disable check */
++		}
+ 		runModConf->bHadFileData = 1; /* this is just a flag, so set it and forget it */
+ 		CHKiRet(enqLine(act, *pCStr, strtOffs)); /* process line */
+ 		rsCStrDestruct(pCStr); /* discard string (must be done by us!) */
+@@ -2122,7 +2230,8 @@
+ 	uchar statefname[MAXFNAME];
+ 
+ 	uchar *const statefn = getStateFileName(act, statefile, sizeof(statefile));
+-	getFullStateFileName(statefn, statefname, sizeof(statefname));
++	getFileID(act);
++	getFullStateFileName(statefn, act->file_id, statefname, sizeof(statefname));
+ 	DBGPRINTF("persisting state for '%s', state file '%s'\n", act->name, statefname);
+ 
+ 	struct json_object *jval = NULL;
+diff --git a/plugins/imfile/siphash.c b/plugins/imfile/siphash.c
+new file mode 100644
+index 0000000000..8d5fac7343
+--- /dev/null
++++ b/plugins/imfile/siphash.c
+@@ -0,0 +1,185 @@
++/* SipHash reference C implementation
++ *
++ * Copyright (c) 2012-2016 Jean-Philippe Aumasson
++ * <jeanphilippe.aumasson@gmail.com>
++ * Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
++ *
++ * Slightly adapted by rsyslog in regard to build system and code style
++ * check.
++ *
++ * To the extent possible under law, the author(s) have dedicated all copyright
++ * and related and neighboring rights to this software to the public domain
++ * worldwide. This software is distributed without any warranty.
++ *
++ * You should have received a copy of the CC0 Public Domain Dedication along
++ * with
++ * this software. If not, see
++ * <http://creativecommons.org/publicdomain/zero/1.0/>.
++ *
++ * For details on siphash see https://131002.net/siphash/
++ */
++#include <assert.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <string.h>
++
++/* default: SipHash-2-4 */
++#define cROUNDS 2
++#define dROUNDS 4
++
++#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
++
++#define U32TO8_LE(p, v)                                                        \
++	(p)[0] = (uint8_t)((v));                                                   \
++	(p)[1] = (uint8_t)((v) >> 8);                                              \
++	(p)[2] = (uint8_t)((v) >> 16);                                             \
++	(p)[3] = (uint8_t)((v) >> 24);
++
++#define U64TO8_LE(p, v)                                                        \
++	U32TO8_LE((p), (uint32_t)((v)));                                           \
++	U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
++
++#define U8TO64_LE(p)                                                           \
++	(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |                        \
++	((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |                 \
++	((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |                 \
++	((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
++
++#define SIPROUND                                                               \
++	do {                                                                       \
++		v0 += v1;                                                              \
++		v1 = ROTL(v1, 13);                                                     \
++		v1 ^= v0;                                                              \
++		v0 = ROTL(v0, 32);                                                     \
++		v2 += v3;                                                              \
++		v3 = ROTL(v3, 16);                                                     \
++		v3 ^= v2;                                                              \
++		v0 += v3;                                                              \
++		v3 = ROTL(v3, 21);                                                     \
++		v3 ^= v0;                                                              \
++		v2 += v1;                                                              \
++		v1 = ROTL(v1, 17);                                                     \
++		v1 ^= v2;                                                              \
++		v2 = ROTL(v2, 32);                                                     \
++	} while (0)
++
++#ifdef DEBUG
++#define TRACE                                                                  \
++	do {                                                                       \
++		printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32),       \
++		       (uint32_t)v0);                                                  \
++		printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32),       \
++		       (uint32_t)v1);                                                  \
++		printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32),       \
++		       (uint32_t)v2);                                                  \
++		printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32),       \
++		       (uint32_t)v3);                                                  \
++	} while (0)
++#else
++#define TRACE
++#endif
++
++extern int rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
++	uint8_t *out, const size_t outlen); /* avoid compiler warning */
++#if defined(__clang__)
++#pragma GCC diagnostic ignored "-Wunknown-attributes"
++#endif
++int
++#if defined(__clang__)
++__attribute__((no_sanitize("unsigned-integer-overflow")))
++#endif
++rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
++	uint8_t *out, const size_t outlen) {
++
++	uint64_t v0 = 0x736f6d6570736575ULL;
++	uint64_t v1 = 0x646f72616e646f6dULL;
++	uint64_t v2 = 0x6c7967656e657261ULL;
++	uint64_t v3 = 0x7465646279746573ULL;
++	uint64_t k0 = U8TO64_LE(k);
++	uint64_t k1 = U8TO64_LE(k + 8);
++	uint64_t m;
++	int i;
++	const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
++	const int left = inlen & 7;
++	uint64_t b = ((uint64_t)inlen) << 56;
++	assert((outlen == 8) || (outlen == 16));
++	v3 ^= k1;
++	v2 ^= k0;
++	v1 ^= k1;
++	v0 ^= k0;
++
++	if (outlen == 16)
++	v1 ^= 0xee;
++
++	for (; in != end; in += 8) {
++		m = U8TO64_LE(in);
++		v3 ^= m;
++
++		TRACE;
++		for (i = 0; i < cROUNDS; ++i)
++		    SIPROUND;
++
++		v0 ^= m;
++	}
++
++	switch (left) {
++	case 7:
++		b |= ((uint64_t)in[6]) << 48;
++		/*FALLTHROUGH*/
++	case 6:
++		b |= ((uint64_t)in[5]) << 40;
++		/*FALLTHROUGH*/
++	case 5:
++		b |= ((uint64_t)in[4]) << 32;
++		/*FALLTHROUGH*/
++	case 4:
++		b |= ((uint64_t)in[3]) << 24;
++		/*FALLTHROUGH*/
++	case 3:
++		b |= ((uint64_t)in[2]) << 16;
++		/*FALLTHROUGH*/
++	case 2:
++		b |= ((uint64_t)in[1]) << 8;
++		/*FALLTHROUGH*/
++	case 1:
++		b |= ((uint64_t)in[0]);
++		break;
++	case 0:
++	default:
++		break;
++	}
++
++	v3 ^= b;
++
++	TRACE;
++	for (i = 0; i < cROUNDS; ++i)
++		SIPROUND;
++
++	v0 ^= b;
++
++	if (outlen == 16)
++		v2 ^= 0xee;
++	else
++		v2 ^= 0xff;
++
++	TRACE;
++	for (i = 0; i < dROUNDS; ++i)
++		SIPROUND;
++
++	b = v0 ^ v1 ^ v2 ^ v3;
++	U64TO8_LE(out, b);
++
++	if (outlen == 8)
++		return 0;
++
++	v1 ^= 0xdd;
++
++	TRACE;
++	for (i = 0; i < dROUNDS; ++i)
++		SIPROUND;
++
++	b = v0 ^ v1 ^ v2 ^ v3;
++	U64TO8_LE(out + 8, b);
++
++	return 0;
++}
+--- a/plugins/imfile/imfile.c
++++ b/plugins/imfile/imfile.c
+@@ -182,6 +182,7 @@ struct act_obj_s {
+ 	time_t timeoutBase; /* what time to calculate the timeout against? */
+ 	/* file dynamic data */
+ 	char file_id[FILE_ID_HASH_SIZE]; /* file id for this entry, once we could obtain it */
++	char file_id_prev[FILE_ID_HASH_SIZE]; /* previous file id for this entry, set if changed */
+ 	int in_move;	/* workaround for inotify move: if set, state file must not be deleted */
+ 	ino_t ino;	/* current inode nbr */
+ 	int fd;		/* fd to file in order to obtain file_id (needs to be preserved across move) */
+@@ -727,6 +728,7 @@ act_obj_add(fs_edge_t *const edge, const char *const name, const int is_file,
+ 	act->ino = ino;
+ 	act->fd = fd;
+ 	act->file_id[0] = '\0';
++	act->file_id_prev[0] = '\0';
+ 	act->is_symlink = is_symlink;
+        if (source) { /* we are target of symlink */
+                CHKmalloc(act->source_name = strdup(source));
+@@ -1378,28 +1380,13 @@ openFileWithStateFile(act_obj_t *const act)
+ 	if(fd < 0) {
+ 		if(errno == ENOENT) {
+ 			if(act->file_id[0] != '\0') {
+-				const char *pszSFNamHash = strdup((const char*)pszSFNam);
+-				CHKmalloc(pszSFNamHash);
+ 				DBGPRINTF("state file %s for %s does not exist - trying to see if "
+ 					"inode-only file exists\n", pszSFNam, act->name);
+ 				getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
+ 				fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
+ 				if(fd >= 0) {
+-					dbgprintf("found inode-only state file, renaming it now that we "
+-						"know the file_id, new name: %s\n", pszSFNamHash);
+-					/* we now can use identify the file, so let's rename it */
+-					if(rename((const char*)pszSFNam, pszSFNamHash) != 0) {
+-						LogError(errno, RS_RET_IO_ERROR,
+-							"imfile error trying to rename state file for '%s' - "
+-							"ignoring this error, usually this means a file no "
+-							"longer file is left over, but this may also cause "
+-							"some real trouble. Still the best we can do ",
+-							act->name);
+-						free((void*) pszSFNamHash);
+-						ABORT_FINALIZE(RS_RET_IO_ERROR);
+-					}
++					dbgprintf("found inode-only state file, will be renamed at next persist\n");
+ 				}
+-				free((void*) pszSFNamHash);
+ 			}
+ 			if(fd < 0) {
+ 				DBGPRINTF("state file %s for %s does not exist - trying to see if "
+@@ -2609,6 +2596,24 @@ atomicWriteStateFile(const char *fn, const char *content)
+ 	RETiRet;
+ }
+ 
++static void
++removeOldStatefile(const uchar *statefn, const char *hashToDelete)
++{
++	int ret;
++	uchar statefname[MAXFNAME];
++
++	getFullStateFileName(statefn, hashToDelete, statefname, sizeof(statefname));
++	DBGPRINTF("removing old state file: '%s'\n", statefname);
++	ret = unlink((const char*)statefname);
++	if(ret != 0 && errno != ENOENT) {
++		LogError(errno, RS_RET_IO_ERROR,
++			"imfile error trying to delete old state file: '%s' - ignoring this "
++			"error, usually this means a file no longer file is left over, but "
++			"this may also cause some real trouble. Still the best we can do ",
++			statefname);
++	}
++}
++
+ 
+ /* This function persists information for a specific file being monitored.
+  * To do so, it simply persists the stream object. We do NOT abort on error
+@@ -2660,6 +2664,10 @@ persistStrmState(act_obj_t *const act)
+ 	CHKiRet(atomicWriteStateFile((const char*)statefname, jstr));
+ 	json_object_put(json);
+ 
++	if (strncmp((const char *)act->file_id_prev, (const char *)act->file_id, FILE_ID_HASH_SIZE)) {
++		removeOldStatefile(statefn, act->file_id_prev);
++	}
++
+ finalize_it:
+ 	if(iRet != RS_RET_OK) {
+ 		errmsg.LogError(0, iRet, "imfile: could not persist state "
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1768320-pmaixfw-CVE.patch b/SOURCES/rsyslog-8.24.0-rhbz1768320-pmaixfw-CVE.patch
new file mode 100644
index 0000000..2f5d5c1
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1768320-pmaixfw-CVE.patch
@@ -0,0 +1,36 @@
+From 10549ba915556c557b22b3dac7e4cb73ad22d3d8 Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Fri, 27 Sep 2019 13:36:02 +0200
+Subject: [PATCH] pmaixforwardedfrom bugfix: potential misadressing
+
+---
+ contrib/pmaixforwardedfrom/pmaixforwardedfrom.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c b/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c
+index 37157c7d4a..ebf12ebbef 100644
+--- a/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c
++++ b/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c
+@@ -109,6 +109,10 @@ CODESTARTparse
+ 	}
+ 	/* bump the message portion up by skipLen(23 or 5) characters to overwrite the "Message forwarded from " or "From " with the hostname */
+ 	lenMsg -=skipLen;
++	if(lenMsg < 2) {
++		dbgprintf("not a AIX message forwarded from message has nothing after header\n");
++		ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE);
++	}
+ 	memmove(p2parse, p2parse + skipLen, lenMsg);
+ 	*(p2parse + lenMsg) = '\n';
+ 	*(p2parse + lenMsg + 1)  = '\0';
+@@ -120,6 +124,11 @@ really an AIX log, but has a similar preamble */
+ 		--lenMsg;
+ 		++p2parse;
+ 	}
++	if (lenMsg < 1) {
++		dbgprintf("not a AIX message forwarded from message has nothing after colon "
++			"or no colon at all\n");
++		ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE);
++	}
+ 	if (lenMsg && *p2parse != ':') {
+ 	DBGPRINTF("not a AIX message forwarded from mangled log but similar enough that the preamble has been removed\n");
+ 		ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE);
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1768323-pmcisco-CVE.patch b/SOURCES/rsyslog-8.24.0-rhbz1768323-pmcisco-CVE.patch
new file mode 100644
index 0000000..bc14c9a
--- /dev/null
+++ b/SOURCES/rsyslog-8.24.0-rhbz1768323-pmcisco-CVE.patch
@@ -0,0 +1,34 @@
+From abc0960a7561e18944a0e08d48f4eb570ea7435a Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Fri, 27 Sep 2019 15:02:52 +0200
+Subject: [PATCH] pmcisconames bugfix: potential misadressing
+
+---
+ contrib/pmcisconames/pmcisconames.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/contrib/pmcisconames/pmcisconames.c b/contrib/pmcisconames/pmcisconames.c
+index 7f376ad170..39506ce592 100644
+--- a/contrib/pmcisconames/pmcisconames.c
++++ b/contrib/pmcisconames/pmcisconames.c
+@@ -119,6 +119,11 @@ CODESTARTparse
+ 		--lenMsg;
+ 		++p2parse;
+ 	}
++	/* Note: we deliberately count the 0-byte below because we need to go chars+1! */
++	if(lenMsg < (int) sizeof(OpeningText)) {
++		dbgprintf("pmcisconames: too short for being cisco messages\n");
++		ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE);
++	}
+ 	/* skip the space after the hostname */
+ 	lenMsg -=1;
+ 	p2parse +=1;
+@@ -126,7 +131,7 @@ CODESTARTparse
+         /* if the syslog tag is : and the next thing starts with a % assume that this is a mangled cisco log and fix it */
+ 	if(strncasecmp((char*) p2parse, OpeningText, sizeof(OpeningText)-1) != 0) {
+ 		/* wrong opening text */
+-	DBGPRINTF("not a cisco name mangled log!\n");
++		DBGPRINTF("not a cisco name mangled log!\n");
+ 		ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE);
+ 	}
+ 	/* bump the message portion up by two characters to overwrite the extra : */
diff --git a/SOURCES/rsyslog-8.24.0-rhbz1805675-file-id.patch b/SOURCES/rsyslog-8.24.0-rhbz1805675-file-id.patch
deleted file mode 100644
index 4843de4..0000000
--- a/SOURCES/rsyslog-8.24.0-rhbz1805675-file-id.patch
+++ /dev/null
@@ -1,610 +0,0 @@
-From 70ea76962bfe9ffed2bd604898e43e0e3b17645d Mon Sep 17 00:00:00 2001
-From: Rainer Gerhards <rgerhards@adiscon.com>
-Date: Thu, 23 Aug 2018 10:15:21 +0200
-Subject: [PATCH] omfile: implement file-id, used in state file
-
-This ensures that files with the same inodes are not accidently treated
-as equal, at least within the limits of the file id hash (see doc for
-details).
-
-We use the siphash reference implementation to generate our non-cryptographic
-hash.
-
-State file handling was invalid. When a file was moved and re-created
-rsyslog could use the file_id if the new file to write the old files'
-state file. This could make the file reader stuck until it reached the
-previous offset. Depending on file sizes this could never happen AND
-would cause large message loss. This situation was timing dependent
-(a race) and most frequently occurred under log rotation. In polling
-mode the bug was less likely, but could also occur.
----
- plugins/imfile/Makefile.am      |   2 +-
- plugins/imfile/imfile.c         | 190 ++++++++++++++++++-----
- plugins/imfile/siphash.c        | 185 ++++++++++++++++++++++++++++++++
- 3 files changed, 381 insertions(+), 19 deletions(-)
- create mode 100644 plugins/imfile/siphash.c
-
-diff --git a/plugins/imfile/Makefile.am b/plugins/imfile/Makefile.am
-index f4df0ed687..9e137efdc8 100644
---- a/plugins/imfile/Makefile.am
-+++ b/plugins/imfile/Makefile.am
-@@ -1,6 +1,6 @@
- pkglib_LTLIBRARIES = imfile.la
- 
--imfile_la_SOURCES = imfile.c
-+imfile_la_SOURCES = imfile.c siphash.c
- imfile_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS)
- imfile_la_LDFLAGS = -module -avoid-version
- imfile_la_LIBADD = 
-diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
-index 4bc6078bda..14f4f1f495 100644
---- a/plugins/imfile/imfile.c
-+++ b/plugins/imfile/imfile.c
-@@ -66,6 +66,8 @@
- MODULE_CNFNAME("imfile")
- 
- /* defines */
-+#define FILE_ID_HASH_SIZE 20	/* max size of a file_id hash */
-+#define FILE_ID_SIZE	512	/* how many bytes are used for file-id? */
- 
- /* Module static data */
- DEF_IMOD_STATIC_DATA	/* must be present, starts static data */
-@@ -75,6 +77,9 @@
- DEFobjCurrIf(prop)
- DEFobjCurrIf(ruleset)
- 
-+extern int rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
-+	uint8_t *out, const size_t outlen); /* see siphash.c */
-+
- static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
- 
- #define NUM_MULTISUB 1024 /* default max number of submits */
-@@ -155,8 +160,10 @@
- 	int wd;
- 	time_t timeoutBase; /* what time to calculate the timeout against? */
- 	/* file dynamic data */
-+	char file_id[FILE_ID_HASH_SIZE]; /* file id for this entry, once we could obtain it */
- 	int in_move;	/* workaround for inotify move: if set, state file must not be deleted */
- 	ino_t ino;	/* current inode nbr */
-+	int fd;		/* fd to file in order to obtain file_id (needs to be preserved across move) */
- 	strm_t *pStrm;	/* its stream (NULL if not assigned) */
- 	int nRecords; /**< How many records did we process before persisting the stream? */
- 	ratelimit_t *ratelimiter;
-@@ -187,7 +194,7 @@
- static int getBasename(uchar *const __restrict__ basen, uchar *const __restrict__ path);
- static void act_obj_unlink(act_obj_t *act);
- static uchar * getStateFileName(const act_obj_t *, uchar *, const size_t);
--static int getFullStateFileName(const uchar *const, uchar *const pszout, const size_t ilenout);
-+static int getFullStateFileName(const uchar *const, const char *const, uchar *const pszout, const size_t ilenout);
- 
- 
- #define OPMODE_POLLING 0
-@@ -328,7 +335,7 @@
- 		  act->name, statefn);
- 
- 	/* Get full path and file name */
--	lenSFNam = getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam));
-+	lenSFNam = getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
- 
- 	/* check if the file exists */
- 	if(stat((char*) pszSFNam, &stat_buf) == -1) {
-@@ -561,16 +568,25 @@
-                        }
- 		}
- 	}
-+	DBGPRINTF("need to add new active object '%s' in '%s' - checking if accessible\n", name, edge->path);
-+	const int fd = open(name, O_RDONLY | O_CLOEXEC);
-+	if(fd < 0) {
-+		if (is_file) { LogMsg(errno, RS_RET_ERR, LOG_WARNING, "imfile: error accessing file '%s'", name);
-+		} else { DBGPRINTF("imfile: error accessing file '%s'", name); }
-+		FINALIZE;
-+	}
- 	DBGPRINTF("add new active object '%s' in '%s'\n", name, edge->path);
- 	CHKmalloc(act = calloc(sizeof(act_obj_t), 1));
- 	CHKmalloc(act->name = strdup(name));
--       if (-1 == getBasename((uchar*)basename, (uchar*)name)) {
--               CHKmalloc(act->basename = strdup(name)); /* assume basename is same as name */
--       } else {
--               CHKmalloc(act->basename = strdup(basename));
--       }
-+	if (-1 == getBasename((uchar*)basename, (uchar*)name)) {
-+		CHKmalloc(act->basename = strdup(name)); /* assume basename is same as name */
-+	} else {
-+		CHKmalloc(act->basename = strdup(basename));
-+	}
- 	act->edge = edge;
- 	act->ino = ino;
-+	act->fd = fd;
-+	act->file_id[0] = '\0';
- 	act->is_symlink = is_symlink;
-        if (source) { /* we are target of symlink */
-                CHKmalloc(act->source_name = strdup(source));
-@@ -813,7 +828,7 @@
- 		pollFile(act); /* get any left-over data */
- 		if(inst->bRMStateOnDel) {
- 			statefn = getStateFileName(act, statefile, sizeof(statefile));
--			getFullStateFileName(statefn, toDel, sizeof(toDel));
-+			getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check!
- 			statefn = toDel;
- 		}
- 		persistStrmState(act);
-@@ -832,6 +847,9 @@
- 		wdmapDel(act->wd);
- 	}
- 	#endif
-+	if(act->fd >= 0) {
-+		close(act->fd);
-+	}
- 	#if defined(OS_SOLARIS) && defined (HAVE_PORT_SOURCE_FILE)
- 	if(act->pfinf != NULL) {
- 		free(act->pfinf->fobj.fo_name);
-@@ -1029,7 +1047,7 @@
-  * open or otherwise modify disk file state.
-  */
- static int
--getFullStateFileName(const uchar *const pszstatefile, uchar *const pszout, const size_t ilenout)
-+getFullStateFileName(const uchar *const pszstatefile, const char *const file_id, uchar *const pszout, const size_t ilenout)
- {
- 	int lenout;
- 	const uchar* pszworkdir;
-@@ -1038,14 +1056,68 @@
- 	pszworkdir = glblGetWorkDirRaw();
- 
- 	/* Construct file name */
--	lenout = snprintf((char*)pszout, ilenout, "%s/%s",
--			     (char*) (pszworkdir == NULL ? "." : (char*) pszworkdir), (char*)pszstatefile);
-+	lenout = snprintf((char*)pszout, ilenout, "%s/%s%s%s",
-+		(char*) (pszworkdir == NULL ? "." : (char*) pszworkdir), (char*)pszstatefile,
-+		(*file_id == '\0') ? "" : ":", file_id);
- 
- 	/* return out length */
- 	return lenout;
- }
- 
- 
-+/* hash function for file-id
-+ * Takes a block of data and returns a string with the hash value.
-+ *
-+ * Currently one provided by Aaaron Wiebe based on perl's hashing algorithm
-+ * (so probably pretty generic). Not for excessively large strings!
-+ * TODO: re-think the hash function!
-+ */
-+#if defined(__clang__)
-+#pragma GCC diagnostic ignored "-Wunknown-attributes"
-+#endif
-+static void __attribute__((nonnull(1,3)))
-+#if defined(__clang__)
-+__attribute__((no_sanitize("unsigned-integer-overflow")))
-+#endif
-+get_file_id_hash(const char *data, size_t lendata,
-+	char *const hash_str, const size_t len_hash_str)
-+{
-+	assert(len_hash_str >= 17); /* we always generate 8-byte strings */
-+
-+	size_t i;
-+	uint8_t out[8], k[16];
-+	for (i = 0; i < 16; ++i)
-+		k[i] = i;
-+	memset(out, 0, sizeof(out));
-+	rs_siphash((const uint8_t *)data, lendata, k, out, 8);
-+
-+	for(i = 0 ; i < 8 ; ++i) {
-+		if(2 * i+1 >= len_hash_str)
-+			break;
-+		snprintf(hash_str+(2*i), 3, "%2.2x", out[i]);
-+	}
-+}
-+
-+
-+
-+/* this returns the file-id for a given file
-+ */
-+static void getFileID(act_obj_t *const act)
-+{
-+	/* save the old id for cleaning purposes */
-+	strncpy(act->file_id_prev, (const char*)act->file_id, FILE_ID_HASH_SIZE);
-+	act->file_id[0] = '\0';
-+	assert(act->fd >= 0); /* fd must have been opened at act_obj_t creation! */
-+	char filedata[FILE_ID_SIZE];
-+	const int r = read(act->fd, filedata, FILE_ID_SIZE);
-+	if(r == FILE_ID_SIZE) {
-+		get_file_id_hash(filedata, sizeof(filedata), act->file_id, sizeof(act->file_id));
-+	} else {
-+		DBGPRINTF("getFileID partial or error read, ret %d\n", r);
-+	}
-+	DBGPRINTF("getFileID for '%s', file_id_hash '%s'\n", act->name, act->file_id);
-+}
-+
- /* this generates a state file name suitable for the given file. To avoid
-  * malloc calls, it must be passed a buffer which should be MAXFNAME large.
-  * Note: the buffer is not necessarily populated ... always ONLY use the
-@@ -1060,7 +1135,7 @@
- {
- 	DBGPRINTF("getStateFileName for '%s'\n", act->name);
- 	snprintf((char*)buf, lenbuf - 1, "imfile-state:%lld", (long long) act->ino);
--	DBGPRINTF("getStateFileName:  stat file name now is %s\n", buf);
-+	DBGPRINTF("getStateFileName:  state file name now is %s\n", buf);
- 	return buf;
- }
- 
-@@ -1136,18 +1209,45 @@
- 	const instanceConf_t *const inst = act->edge->instarr[0];// TODO: same file, multiple instances?
- 
- 	uchar *const statefn = getStateFileName(act, statefile, sizeof(statefile));
-+	getFileID(act);
- 
--	getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam));
-+	getFullStateFileName(statefn, act->file_id, pszSFNam, sizeof(pszSFNam));
- 	DBGPRINTF("trying to open state for '%s', state file '%s'\n", act->name, pszSFNam);
- 
- 	/* check if the file exists */
- 	fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
- 	if(fd < 0) {
- 		if(errno == ENOENT) {
--			DBGPRINTF("NO state file (%s) exists for '%s' - trying to see if "
--				"old-style file exists\n", pszSFNam, act->name);
--			CHKiRet(OLD_openFileWithStateFile(act));
--			FINALIZE;
-+			if(act->file_id[0] != '\0') {
-+				const char *pszSFNamHash = strdup((const char*)pszSFNam);
-+				CHKmalloc(pszSFNamHash);
-+				DBGPRINTF("state file %s for %s does not exist - trying to see if "
-+					"inode-only file exists\n", pszSFNam, act->name);
-+				getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
-+				fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
-+				if(fd >= 0) {
-+					dbgprintf("found inode-only state file, renaming it now that we "
-+						"know the file_id, new name: %s\n", pszSFNamHash);
-+					/* we now can use identify the file, so let's rename it */
-+					if(rename((const char*)pszSFNam, pszSFNamHash) != 0) {
-+						LogError(errno, RS_RET_IO_ERROR,
-+							"imfile error trying to rename state file for '%s' - "
-+							"ignoring this error, usually this means a file no "
-+							"longer file is left over, but this may also cause "
-+							"some real trouble. Still the best we can do ",
-+							act->name);
-+						free((void*) pszSFNamHash);
-+						ABORT_FINALIZE(RS_RET_IO_ERROR);
-+					}
-+				}
-+				free((void*) pszSFNamHash);
-+			}
-+			if(fd < 0) {
-+				DBGPRINTF("state file %s for %s does not exist - trying to see if "
-+					"old-style file exists\n", pszSFNam, act->name);
-+				CHKiRet(OLD_openFileWithStateFile(act));
-+				FINALIZE;
-+			}
- 		} else {
- 			LogError(errno, RS_RET_IO_ERROR,
- 				"imfile error trying to access state file for '%s'",
-@@ -1156,6 +1256,7 @@
- 		}
- 	}
- 
-+	DBGPRINTF("opened state file %s for %s\n", pszSFNam, act->name);
- 	CHKiRet(strm.Construct(&act->pStrm));
- 
- 	struct json_object *jval;
-@@ -1289,6 +1390,7 @@
- {
- 	int64 strtOffs;
- 	DEFiRet;
-+	int64_t startOffs = 0;
- 	int nProcessed = 0;
- 
- 	DBGPRINTF("pollFileReal enter, pStrm %p, name '%s'\n", act->pStrm, act->name);
-@@ -1301,6 +1403,7 @@
- 		CHKiRet(openFile(act)); /* open file */
- 	}
- 
-+	startOffs = act->pStrm->iCurrOffs;	
- 	/* loop below will be exited when strmReadLine() returns EOF */
- 	while(glbl.GetGlobalInputTermState() == 0) {
- 		if(inst->maxLinesAtOnce != 0 && nProcessed >= inst->maxLinesAtOnce)
-@@ -1313,6 +1416,11 @@
- 				inst->escapeLF, &strtOffs));
- 		}
- 		++nProcessed;
-+		if(startOffs < FILE_ID_SIZE && act->pStrm->iCurrOffs >= FILE_ID_SIZE) {
-+			dbgprintf("initiating state file write as sufficient data is now present; file=%s\n", act->name);
-+			persistStrmState(act);
-+			startOffs = act->pStrm->iCurrOffs; /* disable check */
-+		}
- 		runModConf->bHadFileData = 1; /* this is just a flag, so set it and forget it */
- 		CHKiRet(enqLine(act, *pCStr, strtOffs)); /* process line */
- 		rsCStrDestruct(pCStr); /* discard string (must be done by us!) */
-@@ -2122,7 +2230,8 @@
- 	uchar statefname[MAXFNAME];
- 
- 	uchar *const statefn = getStateFileName(act, statefile, sizeof(statefile));
--	getFullStateFileName(statefn, statefname, sizeof(statefname));
-+	getFileID(act);
-+	getFullStateFileName(statefn, act->file_id, statefname, sizeof(statefname));
- 	DBGPRINTF("persisting state for '%s', state file '%s'\n", act->name, statefname);
- 
- 	struct json_object *jval = NULL;
-diff --git a/plugins/imfile/siphash.c b/plugins/imfile/siphash.c
-new file mode 100644
-index 0000000000..8d5fac7343
---- /dev/null
-+++ b/plugins/imfile/siphash.c
-@@ -0,0 +1,185 @@
-+/* SipHash reference C implementation
-+ *
-+ * Copyright (c) 2012-2016 Jean-Philippe Aumasson
-+ * <jeanphilippe.aumasson@gmail.com>
-+ * Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
-+ *
-+ * Slightly adapted by rsyslog in regard to build system and code style
-+ * check.
-+ *
-+ * To the extent possible under law, the author(s) have dedicated all copyright
-+ * and related and neighboring rights to this software to the public domain
-+ * worldwide. This software is distributed without any warranty.
-+ *
-+ * You should have received a copy of the CC0 Public Domain Dedication along
-+ * with
-+ * this software. If not, see
-+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
-+ *
-+ * For details on siphash see https://131002.net/siphash/
-+ */
-+#include <assert.h>
-+#include <stdint.h>
-+#include <stdio.h>
-+#include <string.h>
-+
-+/* default: SipHash-2-4 */
-+#define cROUNDS 2
-+#define dROUNDS 4
-+
-+#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
-+
-+#define U32TO8_LE(p, v)                                                        \
-+	(p)[0] = (uint8_t)((v));                                                   \
-+	(p)[1] = (uint8_t)((v) >> 8);                                              \
-+	(p)[2] = (uint8_t)((v) >> 16);                                             \
-+	(p)[3] = (uint8_t)((v) >> 24);
-+
-+#define U64TO8_LE(p, v)                                                        \
-+	U32TO8_LE((p), (uint32_t)((v)));                                           \
-+	U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
-+
-+#define U8TO64_LE(p)                                                           \
-+	(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) |                        \
-+	((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) |                 \
-+	((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) |                 \
-+	((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
-+
-+#define SIPROUND                                                               \
-+	do {                                                                       \
-+		v0 += v1;                                                              \
-+		v1 = ROTL(v1, 13);                                                     \
-+		v1 ^= v0;                                                              \
-+		v0 = ROTL(v0, 32);                                                     \
-+		v2 += v3;                                                              \
-+		v3 = ROTL(v3, 16);                                                     \
-+		v3 ^= v2;                                                              \
-+		v0 += v3;                                                              \
-+		v3 = ROTL(v3, 21);                                                     \
-+		v3 ^= v0;                                                              \
-+		v2 += v1;                                                              \
-+		v1 = ROTL(v1, 17);                                                     \
-+		v1 ^= v2;                                                              \
-+		v2 = ROTL(v2, 32);                                                     \
-+	} while (0)
-+
-+#ifdef DEBUG
-+#define TRACE                                                                  \
-+	do {                                                                       \
-+		printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32),       \
-+		       (uint32_t)v0);                                                  \
-+		printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32),       \
-+		       (uint32_t)v1);                                                  \
-+		printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32),       \
-+		       (uint32_t)v2);                                                  \
-+		printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32),       \
-+		       (uint32_t)v3);                                                  \
-+	} while (0)
-+#else
-+#define TRACE
-+#endif
-+
-+extern int rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
-+	uint8_t *out, const size_t outlen); /* avoid compiler warning */
-+#if defined(__clang__)
-+#pragma GCC diagnostic ignored "-Wunknown-attributes"
-+#endif
-+int
-+#if defined(__clang__)
-+__attribute__((no_sanitize("unsigned-integer-overflow")))
-+#endif
-+rs_siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
-+	uint8_t *out, const size_t outlen) {
-+
-+	uint64_t v0 = 0x736f6d6570736575ULL;
-+	uint64_t v1 = 0x646f72616e646f6dULL;
-+	uint64_t v2 = 0x6c7967656e657261ULL;
-+	uint64_t v3 = 0x7465646279746573ULL;
-+	uint64_t k0 = U8TO64_LE(k);
-+	uint64_t k1 = U8TO64_LE(k + 8);
-+	uint64_t m;
-+	int i;
-+	const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
-+	const int left = inlen & 7;
-+	uint64_t b = ((uint64_t)inlen) << 56;
-+	assert((outlen == 8) || (outlen == 16));
-+	v3 ^= k1;
-+	v2 ^= k0;
-+	v1 ^= k1;
-+	v0 ^= k0;
-+
-+	if (outlen == 16)
-+	v1 ^= 0xee;
-+
-+	for (; in != end; in += 8) {
-+		m = U8TO64_LE(in);
-+		v3 ^= m;
-+
-+		TRACE;
-+		for (i = 0; i < cROUNDS; ++i)
-+		    SIPROUND;
-+
-+		v0 ^= m;
-+	}
-+
-+	switch (left) {
-+	case 7:
-+		b |= ((uint64_t)in[6]) << 48;
-+		/*FALLTHROUGH*/
-+	case 6:
-+		b |= ((uint64_t)in[5]) << 40;
-+		/*FALLTHROUGH*/
-+	case 5:
-+		b |= ((uint64_t)in[4]) << 32;
-+		/*FALLTHROUGH*/
-+	case 4:
-+		b |= ((uint64_t)in[3]) << 24;
-+		/*FALLTHROUGH*/
-+	case 3:
-+		b |= ((uint64_t)in[2]) << 16;
-+		/*FALLTHROUGH*/
-+	case 2:
-+		b |= ((uint64_t)in[1]) << 8;
-+		/*FALLTHROUGH*/
-+	case 1:
-+		b |= ((uint64_t)in[0]);
-+		break;
-+	case 0:
-+	default:
-+		break;
-+	}
-+
-+	v3 ^= b;
-+
-+	TRACE;
-+	for (i = 0; i < cROUNDS; ++i)
-+		SIPROUND;
-+
-+	v0 ^= b;
-+
-+	if (outlen == 16)
-+		v2 ^= 0xee;
-+	else
-+		v2 ^= 0xff;
-+
-+	TRACE;
-+	for (i = 0; i < dROUNDS; ++i)
-+		SIPROUND;
-+
-+	b = v0 ^ v1 ^ v2 ^ v3;
-+	U64TO8_LE(out, b);
-+
-+	if (outlen == 8)
-+		return 0;
-+
-+	v1 ^= 0xdd;
-+
-+	TRACE;
-+	for (i = 0; i < dROUNDS; ++i)
-+		SIPROUND;
-+
-+	b = v0 ^ v1 ^ v2 ^ v3;
-+	U64TO8_LE(out + 8, b);
-+
-+	return 0;
-+}
---- a/plugins/imfile/imfile.c
-+++ b/plugins/imfile/imfile.c
-@@ -182,6 +182,7 @@ struct act_obj_s {
- 	time_t timeoutBase; /* what time to calculate the timeout against? */
- 	/* file dynamic data */
- 	char file_id[FILE_ID_HASH_SIZE]; /* file id for this entry, once we could obtain it */
-+	char file_id_prev[FILE_ID_HASH_SIZE]; /* previous file id for this entry, set if changed */
- 	int in_move;	/* workaround for inotify move: if set, state file must not be deleted */
- 	ino_t ino;	/* current inode nbr */
- 	int fd;		/* fd to file in order to obtain file_id (needs to be preserved across move) */
-@@ -727,6 +728,7 @@ act_obj_add(fs_edge_t *const edge, const char *const name, const int is_file,
- 	act->ino = ino;
- 	act->fd = fd;
- 	act->file_id[0] = '\0';
-+	act->file_id_prev[0] = '\0';
- 	act->is_symlink = is_symlink;
-        if (source) { /* we are target of symlink */
-                CHKmalloc(act->source_name = strdup(source));
-@@ -1378,28 +1380,13 @@ openFileWithStateFile(act_obj_t *const act)
- 	if(fd < 0) {
- 		if(errno == ENOENT) {
- 			if(act->file_id[0] != '\0') {
--				const char *pszSFNamHash = strdup((const char*)pszSFNam);
--				CHKmalloc(pszSFNamHash);
- 				DBGPRINTF("state file %s for %s does not exist - trying to see if "
- 					"inode-only file exists\n", pszSFNam, act->name);
- 				getFullStateFileName(statefn, "", pszSFNam, sizeof(pszSFNam));
- 				fd = open((char*)pszSFNam, O_CLOEXEC | O_NOCTTY | O_RDONLY, 0600);
- 				if(fd >= 0) {
--					dbgprintf("found inode-only state file, renaming it now that we "
--						"know the file_id, new name: %s\n", pszSFNamHash);
--					/* we now can use identify the file, so let's rename it */
--					if(rename((const char*)pszSFNam, pszSFNamHash) != 0) {
--						LogError(errno, RS_RET_IO_ERROR,
--							"imfile error trying to rename state file for '%s' - "
--							"ignoring this error, usually this means a file no "
--							"longer file is left over, but this may also cause "
--							"some real trouble. Still the best we can do ",
--							act->name);
--						free((void*) pszSFNamHash);
--						ABORT_FINALIZE(RS_RET_IO_ERROR);
--					}
-+					dbgprintf("found inode-only state file, will be renamed at next persist\n");
- 				}
--				free((void*) pszSFNamHash);
- 			}
- 			if(fd < 0) {
- 				DBGPRINTF("state file %s for %s does not exist - trying to see if "
-@@ -2609,6 +2596,28 @@ atomicWriteStateFile(const char *fn, const char *content)
- 	RETiRet;
- }
- 
-+static void
-+removeOldStatefile(const uchar *statefn, const char *hashToDelete)
-+{
-+	int ret;
-+	uchar statefname[MAXFNAME];
-+
-+	getFullStateFileName(statefn, hashToDelete, statefname, sizeof(statefname));
-+	ret = unlink((const char*)statefname);
-+	if(ret != 0) {
-+		if (errno != ENOENT) {
-+			LogError(errno, RS_RET_IO_ERROR,
-+				"imfile error trying to delete old state file: '%s' - ignoring this "
-+				"error, usually this means a file no longer file is left over, but "
-+				"this may also cause some real trouble. Still the best we can do ",
-+				statefname);
-+		} else {
-+			DBGPRINTF("trying to delete no longer valid statefile '%s' which no "
-+				  "longer exists (probably already deleted)\n", statefname);
-+		}
-+	}
-+}
-+
- 
- /* This function persists information for a specific file being monitored.
-  * To do so, it simply persists the stream object. We do NOT abort on error
-@@ -2660,6 +2664,15 @@ persistStrmState(act_obj_t *const act)
- 	CHKiRet(atomicWriteStateFile((const char*)statefname, jstr));
- 	json_object_put(json);
- 
-+	/* check for presence of inode-only statefile and delete if exitsts */
-+	if (act->file_id[0] != '\0') {
-+		removeOldStatefile(statefn, "");
-+	}
-+	/* file-id changed (truncated?), remove the old hash statefile */
-+	if (strncmp((const char *)act->file_id_prev, (const char *)act->file_id, FILE_ID_HASH_SIZE)) {
-+		removeOldStatefile(statefn, act->file_id_prev);
-+	}
-+
- finalize_it:
- 	if(iRet != RS_RET_OK) {
- 		errmsg.LogError(0, iRet, "imfile: could not persist state "
diff --git a/SPECS/rsyslog.spec b/SPECS/rsyslog.spec
index 4473e21..c3743e7 100644
--- a/SPECS/rsyslog.spec
+++ b/SPECS/rsyslog.spec
@@ -14,7 +14,7 @@
 Summary: Enhanced system logging and kernel message trapping daemon
 Name: rsyslog
 Version: 8.24.0
-Release: 41%{?dist}.4
+Release: 52%{?dist}
 License: (GPLv3+ and ASL 2.0)
 Group: System Environment/Daemons
 URL: http://www.rsyslog.com/
@@ -115,8 +115,18 @@ Patch52: rsyslog-8.24.0-doc-rhbz1625935-mmkubernetes-CRI-O.patch
 Patch53: rsyslog-8.24.0-rhbz1656860-imfile-buffer-overflow.patch
 Patch54: rsyslog-8.24.0-rhbz1725067-imjournal-memleak.patch
 
-Patch55: rsyslog-8.24.0-rhbz1746497-ratelimiter-segfault.patch
-Patch56: rsyslog-8.24.0-rhbz1805675-file-id.patch
+Patch55: rsyslog-8.24.0-doc-rhbz1696686-imjournal-fsync.patch
+Patch56: rsyslog-8.24.0-rhbz1696686-imjournal-fsync.patch
+Patch57: rsyslog-8.24.0-rhbz1684236-omelastic-sigsegv.patch
+Patch58: rsyslog-8.24.0-doc-rhbz1309698-imudp-case-sensitive-option.patch
+Patch59: rsyslog-8.24.0-rhbz1309698-imudp-case-sensitive-option.patch
+Patch60: rsyslog-8.24.0-rhbz1627799-cert-chains.patch
+Patch61: rsyslog-8.24.0-rhbz1744682-ratelimiter-segfault.patch
+Patch62: rsyslog-8.24.0-rhbz1549706-corrupt-property-crash.patch
+Patch63: rsyslog-8.24.0-rhbz1768320-pmaixfw-CVE.patch
+Patch64: rsyslog-8.24.0-rhbz1768323-pmcisco-CVE.patch
+Patch65: rsyslog-8.24.0-rhbz1763746-file-id.patch
+Patch66: rsyslog-8.24.0-rhbz1600171-omelastic-ES6.patch
 
 %package crypto
 Summary: Encryption support
@@ -348,6 +358,8 @@ container metadata.
 %patch40 -p1
 %patch41 -p1
 %patch52 -p1
+%patch55 -p1
+%patch58 -p1
 #regenerate the docs
 mv build/searchindex.js searchindex_backup.js
 sphinx-build -b html source build
@@ -422,8 +434,18 @@ mv build doc
 %patch53 -p1 -b .imfile-buffer-overflow
 %patch54 -p1 -b .imjournal-memleak
 
-%patch55 -p1 -b .ratelimit-crash
-%patch56 -p1 -b .file_id-fix
+#%patch55 is applied right after doc setup
+%patch56 -p1 -b .imjournal-fsync
+%patch57 -p1 -b .elastic-sigsegv
+#%patch58 is applied right after doc setup
+%patch59 -p1 -b .udp-case-sensitive
+%patch60 -p1 -b .cert-chains
+%patch61 -p1 -b .ratelimit-crash
+%patch62 -p1 -b .corrupt-property
+%patch63 -p1 -b .pmAIX-CVE
+%patch64 -p1 -b .pmCisco-CVE
+%patch65 -p1 -b .file-id
+%patch66 -p1 -b .omelastic-ES6
 
 autoreconf 
 
@@ -683,28 +705,62 @@ done
 %{_libdir}/rsyslog/mmkubernetes.so
 
 %changelog
-* Tue Mar 03 2020 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41.4
-RHEL 7.7.z ERRATUM
-- edited patch fixing hashed file_ids for imfile statefiles
-  resolves: rhbz#1805675
-
-* Fri Feb 21 2020 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41.3
-RHEL 7.7.z ERRATUM
-- added patch fixing hash file_id feature to properly monitor files
-  after rotation
-  resolves: rhbz#1805675
-
-* Mon Sep 23 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41.2
-RHEL 7.7.z ERRATUM
-- edited imjournal memleaks patch to fix introduced regression
-  resolves: rhbz#1752424
-
-* Mon Sep 02 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41.1
-RHEL 7.7.z ERRATUM
-- added patch resolving possible segfault in core-ratelimiter
-  resolves: rhbz#1746497
-
-* Tue Jul 23 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41
+* Wed Nov 27 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-52
+RHEL 7.8 ERRATUM
+- edited patch file ID for imfile to not log useless errors
+  also improved file-id behavior to adress newly found problems
+  resolves: rhbz#1763746
+
+* Thu Nov 07 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-49
+RHEL 7.8 ERRATUM
+- fixed fsync patch to actually revognize the new option
+  resolves: rhbz#1696686 (failedQA)
+
+* Wed Nov 06 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-48
+RHEL 7.8 ERRATUM
+- added patch resolving crash on wrong MsgProperty
+  resolves: rhbz#1549706
+- added patch resolving CVE in pmaixforward module
+  resolves: rhbz#1768320
+- added patch resolving CVE in pmcisconames module
+  resolves: rhbz#1768323
+- added patch implementing file ID for imfile
+  resolves: rhbz#1763746
+- added patch fixing omelasticsearch with ES 6.X
+  resolves: rhbz#1600171
+
+* Thu Sep 05 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-47
+RHEL 7.8 ERRATUM
+- edited imfile truncation detection patch with reression fix
+  resolves: rhbz#1744856
+
+* Wed Aug 28 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-46
+RHEL 7.8 ERRATUM
+- Support Intermediate Certificate Chains in rsyslog
+  resolves: rhbz#1627799
+- fixed WorAroundJournalBug patch to not cause leaks
+  resolves: rhbz#1744617
+- added patch fixing possible segfault in rate-limiter
+  resolves: rhbz#1744682
+
+* Mon Aug 12 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-45
+RHEL 7.8 ERRATUM
+- fixed fsync patch according to covscan results
+  resolves: rhbz#1696686
+
+* Fri Aug 09 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-44
+RHEL 7.8 ERRATUM
+- added patch and doc-patch for new caseSensitive imUDP/TCP option
+  resolves: rhbz#1309698
+
+* Fri Aug 02 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-41
+RHEL 7.8 ERRATUM
+- added patch and doc-patch with new "fsync" imjournal option
+  resolves: rhbz#1696686
+- added patch resolving omelasticsearch crash on "nothing" reply
+  resolves: rhbz#1684236
+
+* Mon Jul 01 2019 Jiri Vymazal <jvymazal@redhat.com> - 8.24.0-39
 RHEL 7.7.z ERRATUM
 - added patch resolving memory leaks in imjournal
   resolves: rhbz#1725067