From b74fa054f988248577b755e2cccb90b049e022fe Mon Sep 17 00:00:00 2001 From: zhouwenpei Date: Thu, 4 Aug 2022 15:45:00 +0800 Subject: [PATCH] backport patches from upstream and enable check (cherry picked from commit 91560e31fc8ccd8836f5bfe67047b0e1d9915463) --- ...k-when-free-action-worker-data-table.patch | 50 ++++ ...k-when-globally-de-initialize-GnuTLS.patch | 29 ++ ...l-terminated-string-used-with-strlen.patch | 35 +++ ...4395-by-correctly-checking-for-EPIPE.patch | 37 +++ ...Fix-error-handling-in-gtlsRecordRecv.patch | 268 ++++++++++++++++++ ...rker-thread-starvation-on-extreme-tr.patch | 65 +++++ ...the-order-of-doHUP-and-processImInte.patch | 46 +++ ...crease-number-of-to-be-processed-fds.patch | 32 +++ ...f-liblogging-stdlog-is-not-available.patch | 35 +++ rsyslog.spec | 23 +- 10 files changed, 616 insertions(+), 4 deletions(-) create mode 100644 backport-Fix-memory-leak-when-free-action-worker-data-table.patch create mode 100644 backport-Fix-memory-leak-when-globally-de-initialize-GnuTLS.patch create mode 100644 backport-Fix-non-null-terminated-string-used-with-strlen.patch create mode 100644 backport-Fixes-4395-by-correctly-checking-for-EPIPE.patch create mode 100644 backport-gnutls-bugfix-Fix-error-handling-in-gtlsRecordRecv.patch create mode 100644 backport-imptcp-bugfix-worker-thread-starvation-on-extreme-tr.patch create mode 100644 backport-rsyslogd-adjust-the-order-of-doHUP-and-processImInte.patch create mode 100644 backport-tcpsrv-do-not-decrease-number-of-to-be-processed-fds.patch create mode 100644 backport-testbench-skip-omfwd_fast_imuxsock.sh-if-liblogging-stdlog-is-not-available.patch diff --git a/backport-Fix-memory-leak-when-free-action-worker-data-table.patch b/backport-Fix-memory-leak-when-free-action-worker-data-table.patch new file mode 100644 index 0000000..811d203 --- /dev/null +++ b/backport-Fix-memory-leak-when-free-action-worker-data-table.patch @@ -0,0 +1,50 @@ +From 63e5d6845aedd649eee1f807e85784a066163ad0 Mon Sep 17 00:00:00 2001 +From: seuzw930 <76191785+seuzw930@users.noreply.github.com> +Date: Mon, 18 Jul 2022 15:43:17 +0800 +Subject: [PATCH] Fix memory leak when free action worker data table + +During free action worker data table when action destruct, worker instance in worker data table were not null. It resulted in memory leak and this patch fixes this behaviour. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/d59feba46b8d8c2c3c5c25c6fc6e99f93bdae8b9 +--- + action.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/action.c b/action.c +index e0d05ed..4cea500 100644 +--- a/action.c ++++ b/action.c +@@ -326,6 +326,20 @@ actionResetQueueParams(void) + RETiRet; + } + ++/* free action worker data table ++*/ ++static void freeWrkrDataTable(action_t * const pThis) ++{ ++ int freeSpot; ++ for(freeSpot = 0; freeSpot < pThis->wrkrDataTableSize; ++freeSpot) { ++ if(pThis->wrkrDataTable[freeSpot] != NULL) { ++ pThis->pMod->mod.om.freeWrkrInstance(pThis->wrkrDataTable[freeSpot]); ++ pThis->wrkrDataTable[freeSpot] = NULL; ++ } ++ } ++ free(pThis->wrkrDataTable); ++ return; ++} + + /* destructs an action descriptor object + * rgerhards, 2007-08-01 +@@ -363,7 +377,7 @@ rsRetVal actionDestruct(action_t * const pThis) + free(pThis->pszName); + free(pThis->ppTpl); + free(pThis->peParamPassing); +- free(pThis->wrkrDataTable); ++ freeWrkrDataTable(pThis); + + finalize_it: + free(pThis); +-- +2.33.0 + diff --git a/backport-Fix-memory-leak-when-globally-de-initialize-GnuTLS.patch b/backport-Fix-memory-leak-when-globally-de-initialize-GnuTLS.patch new file mode 100644 index 0000000..f0a09cc --- /dev/null +++ b/backport-Fix-memory-leak-when-globally-de-initialize-GnuTLS.patch @@ -0,0 +1,29 @@ +From 81236d6ec506dd84c78e6c09fc39d5019ea483f2 Mon Sep 17 00:00:00 2001 +From: seuzw930 <76191785+seuzw930@users.noreply.github.com> +Date: Thu, 7 Jul 2022 20:47:11 +0800 +Subject: [PATCH] Fix memory leak when globally de-initialize GnuTLS + +During globally de-initialize GnuTLS, server anon credentials and server DH parameters for anon mode were not null. It resulted in memory leak and this patch fixes this behaviour. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/8e13d9d718d26b15263ecd53e26fed1a2af3f3e9 +--- + runtime/nsd_gtls.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c +index 01b0ec6..8f13810 100644 +--- a/runtime/nsd_gtls.c ++++ b/runtime/nsd_gtls.c +@@ -1307,6 +1307,8 @@ static rsRetVal + gtlsGlblExit(void) + { + DEFiRet; ++ gnutls_anon_free_server_credentials(anoncredSrv); ++ gnutls_dh_params_deinit(dh_params); + gnutls_global_deinit(); + RETiRet; + } +-- +2.33.0 + diff --git a/backport-Fix-non-null-terminated-string-used-with-strlen.patch b/backport-Fix-non-null-terminated-string-used-with-strlen.patch new file mode 100644 index 0000000..862853b --- /dev/null +++ b/backport-Fix-non-null-terminated-string-used-with-strlen.patch @@ -0,0 +1,35 @@ +From 6aeec7bf83135224400362598f0cc7ebef655195 Mon Sep 17 00:00:00 2001 +From: David Buckley +Date: Tue, 12 Apr 2022 17:38:49 +0100 +Subject: [PATCH] Fix non-null-terminated-string used with strlen + +The `failedmsg_entry` expects a null-terminated string in `key`, but +here we allocate with malloc and copy a string-with-length-n into only +the first n bytes. If the final byte is null, this is by coincidence +only. + +We've observed this by means of seeing random binary data appended to +keys submitted to kafka apparently at random, and this looks like a +smoking gun. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/2c8c9db065cef3b5086c90c3782ac48da40c8b2f +--- + plugins/omkafka/omkafka.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/plugins/omkafka/omkafka.c b/plugins/omkafka/omkafka.c +index 850dfc0..e6cb2ea 100644 +--- a/plugins/omkafka/omkafka.c ++++ b/plugins/omkafka/omkafka.c +@@ -350,6 +350,7 @@ const size_t msglen, const char *const topicname) + return NULL; + } + memcpy(etry->key, key, keylen); ++ etry->key[keylen] = '\0'; + } else { + etry->key=NULL; + } +-- +2.33.0 + diff --git a/backport-Fixes-4395-by-correctly-checking-for-EPIPE.patch b/backport-Fixes-4395-by-correctly-checking-for-EPIPE.patch new file mode 100644 index 0000000..63fa974 --- /dev/null +++ b/backport-Fixes-4395-by-correctly-checking-for-EPIPE.patch @@ -0,0 +1,37 @@ +From 640af90afaf13bef5a99a458ed8e862359588d8f Mon Sep 17 00:00:00 2001 +From: Kailash Sethuraman +Date: Thu, 13 Jan 2022 13:52:46 -0500 +Subject: [PATCH] Fixes #4395 by correctly checking for EPIPE. + +kmsg is a unique device, which can recover from EPIPE errors. +The original code checked for this, but checked the return value for the libc +read call, which always returns -1 and sets the appropriate errno. + +This meant that when an EPIPE error actually happened, the fd was infinitely retried. The 'for loop' was broken out of, but the readikmsg() function is repeatedly called. + +Note: there is an additional bug here. The readikmsg function needs better error checking on the fd. I suspect that this was rarely an issue because /dev/kmsg goes truly invalid when the system is actually shutting down. + +The fix here is to check the return value as well as the errno. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/feb6420148c351072a190990622b58124fd44506 +--- + contrib/imkmsg/kmsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/contrib/imkmsg/kmsg.c b/contrib/imkmsg/kmsg.c +index beb4076..5a3f45e 100644 +--- a/contrib/imkmsg/kmsg.c ++++ b/contrib/imkmsg/kmsg.c +@@ -214,7 +214,7 @@ readkmsg(void) + if (i > 0) { + /* successful read of message of nonzero length */ + pRcv[i] = '\0'; +- } else if (i == -EPIPE) { ++ } else if (i < 0 && errno == EPIPE) { + imkmsgLogIntMsg(LOG_WARNING, + "imkmsg: some messages in circular buffer got overwritten"); + continue; +-- +2.33.0 + diff --git a/backport-gnutls-bugfix-Fix-error-handling-in-gtlsRecordRecv.patch b/backport-gnutls-bugfix-Fix-error-handling-in-gtlsRecordRecv.patch new file mode 100644 index 0000000..0f932a3 --- /dev/null +++ b/backport-gnutls-bugfix-Fix-error-handling-in-gtlsRecordRecv.patch @@ -0,0 +1,268 @@ +From 325203e4e2b2cc53283d9dbdff0aa677aded1e0d Mon Sep 17 00:00:00 2001 +From: Andre lorbach +Date: Wed, 9 Mar 2022 17:58:05 +0100 +Subject: [PATCH] gnutls bugfix: Fix error handling in gtlsRecordRecv + +There was a rare possibility that the E_AGAIN/E_INTERRUPT handling +could cause an infinite loop (100% CPU Usage), for example when a TLS +handshake is interrupted at a certain stage. + +- After gnutls_record_recv is called, and E_AGAIN/E_INTERRUPT error + occurs, we need to do additional read/write direction handling + with gnutls_record_get_direction. +- After the second call of gnutls_record_recv (Expand buffer) + we needed to also check the eror codes for E_AGAIN/E_INTERRUPT + to do propper errorhandling. +- Add extra debug output based on ossl driver. +- Potential fix for 100% CPU Loop Receiveloop after gtlsRecordRecv + in doRetry call. + +see also: https://github.com/rsyslog/rsyslog/issues/4818 + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/aefcfa4d0f6e213c9fac814c3e6bd53970b7e90e +--- + runtime/nsd_gtls.c | 39 ++++++++++++++++++++++++++++++--------- + runtime/nsd_gtls.h | 5 +++++ + runtime/nsdsel_gtls.c | 28 +++++++++++++++++++++------- + runtime/tcpsrv.c | 11 +++++++---- + tests/imtcp-tls-basic.sh | 3 +++ + 5 files changed, 66 insertions(+), 20 deletions(-) + +diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c +index 6fc300c..01b0ec6 100644 +--- a/runtime/nsd_gtls.c ++++ b/runtime/nsd_gtls.c +@@ -550,8 +550,10 @@ gtlsRecordRecv(nsd_gtls_t *pThis) + DEFiRet; + + ISOBJ_TYPE_assert(pThis, nsd_gtls); +- DBGPRINTF("gtlsRecordRecv: start\n"); + ++ DBGPRINTF("gtlsRecordRecv: start (Pending Data: %zd | Wanted Direction: %s)\n", ++ gnutls_record_check_pending(pThis->sess), ++ (gnutls_record_get_direction(pThis->sess) == gtlsDir_READ ? "READ" : "WRITE") ); + lenRcvd = gnutls_record_recv(pThis->sess, pThis->pszRcvBuf, NSD_GTLS_MAX_RCVBUF); + if(lenRcvd >= 0) { + DBGPRINTF("gtlsRecordRecv: gnutls_record_recv received %zd bytes\n", lenRcvd); +@@ -575,14 +577,30 @@ gtlsRecordRecv(nsd_gtls_t *pThis) + (NSD_GTLS_MAX_RCVBUF+lenRcvd)); + pThis->lenRcvBuf = NSD_GTLS_MAX_RCVBUF+lenRcvd; + } else { +- goto sslerr; ++ if (lenRcvd == GNUTLS_E_AGAIN || lenRcvd == GNUTLS_E_INTERRUPTED) { ++ goto sslerragain; /* Go to ERR AGAIN handling */ ++ } else { ++ /* Do all other error handling */ ++ int gnuRet = lenRcvd; ++ ABORTgnutls; ++ } + } + } + } else if(lenRcvd == GNUTLS_E_AGAIN || lenRcvd == GNUTLS_E_INTERRUPTED) { +-sslerr: +- pThis->rtryCall = gtlsRtry_recv; +- dbgprintf("GnuTLS receive requires a retry (this most probably is OK and no error condition)\n"); +- ABORT_FINALIZE(RS_RET_RETRY); ++sslerragain: ++ /* Check if the underlaying file descriptor needs to read or write data!*/ ++ if (gnutls_record_get_direction(pThis->sess) == gtlsDir_READ) { ++ pThis->rtryCall = gtlsRtry_recv; ++ dbgprintf("GnuTLS receive requires a retry, this most probably is OK and no error condition\n"); ++ ABORT_FINALIZE(RS_RET_RETRY); ++ } else { ++ uchar *pErr = gtlsStrerror(lenRcvd); ++ LogError(0, RS_RET_GNUTLS_ERR, "GnuTLS receive error %zd has wrong read direction(wants write) " ++ "- this could be caused by a broken connection. GnuTLS reports: %s\n", ++ lenRcvd, pErr); ++ free(pErr); ++ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); ++ } + } else { + int gnuRet = lenRcvd; + ABORTgnutls; +@@ -2031,6 +2049,7 @@ static rsRetVal + Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) + { + int iSent; ++ int wantsWriteData = 0; + nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd; + DEFiRet; + ISOBJ_TYPE_assert(pThis, nsd_gtls); +@@ -2051,10 +2070,12 @@ Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) + break; + } + if(iSent != GNUTLS_E_INTERRUPTED && iSent != GNUTLS_E_AGAIN) { ++ /* Check if the underlaying file descriptor needs to read or write data!*/ ++ wantsWriteData = gnutls_record_get_direction(pThis->sess); + uchar *pErr = gtlsStrerror(iSent); +- LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d - this " +- "could be caused by a broken connection. GnuTLS reports: %s \n", +- iSent, pErr); ++ LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d, wantsWriteData=%d - this " ++ "could be caused by a broken connection. GnuTLS reports: %s\n", ++ iSent, wantsWriteData, pErr); + free(pErr); + gnutls_perror(iSent); + ABORT_FINALIZE(RS_RET_GNUTLS_ERR); +diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h +index a3ef59f..b9988ae 100644 +--- a/runtime/nsd_gtls.h ++++ b/runtime/nsd_gtls.h +@@ -33,6 +33,11 @@ typedef enum { + gtlsRtry_recv = 2 + } gtlsRtryCall_t; /**< IDs of calls that needs to be retried */ + ++typedef enum { ++ gtlsDir_READ = 0, /**< GNUTLS wants READ */ ++ gtlsDir_WRITE = 1 /**< GNUTLS wants WRITE */ ++} gtlsDirection_t; ++ + typedef nsd_if_t nsd_gtls_if_t; /* we just *implement* this interface */ + + /* the nsd_gtls object */ +diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c +index 6ed7187..01cfb05 100644 +--- a/runtime/nsdsel_gtls.c ++++ b/runtime/nsdsel_gtls.c +@@ -81,6 +81,7 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp) + + ISOBJ_TYPE_assert(pThis, nsdsel_gtls); + ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls); ++ DBGPRINTF("Add on nsd %p:\n", pNsdGTLS); + if(pNsdGTLS->iMode == 1) { + if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) { + ++pThis->iBufferRcvReady; +@@ -99,6 +100,7 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp) + } + } + ++ dbgprintf("nsdsel_gtls: reached end on nsd %p, calling nsdsel_ptcp.Add with waitOp %d... \n", pNsdGTLS, waitOp); + /* if we reach this point, we need no special handling */ + CHKiRet(nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, waitOp)); + +@@ -120,7 +122,8 @@ Select(nsdsel_t *pNsdsel, int *piNumReady) + if(pThis->iBufferRcvReady > 0) { + /* we still have data ready! */ + *piNumReady = pThis->iBufferRcvReady; +- dbgprintf("nsdsel_gtls: doing dummy select, data present\n"); ++ dbgprintf("nsdsel_gtls: doing dummy select for %p->iBufferRcvReady=%d, data present\n", ++ pThis, pThis->iBufferRcvReady); + } else { + iRet = nsdsel_ptcp.Select(pThis->pTcp, piNumReady); + } +@@ -138,7 +141,7 @@ doRetry(nsd_gtls_t *pNsd) + DEFiRet; + int gnuRet; + +- dbgprintf("GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall); ++ dbgprintf("doRetry: GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall); + + /* We follow a common scheme here: first, we do the systen call and + * then we check the result. So far, the result is checked after the +@@ -151,7 +154,7 @@ doRetry(nsd_gtls_t *pNsd) + case gtlsRtry_handshake: + gnuRet = gnutls_handshake(pNsd->sess); + if(gnuRet == GNUTLS_E_AGAIN || gnuRet == GNUTLS_E_INTERRUPTED) { +- dbgprintf("GnuTLS handshake retry did not finish - " ++ dbgprintf("doRetry: GnuTLS handshake retry did not finish - " + "setting to retry (this is OK and can happen)\n"); + FINALIZE; + } else if(gnuRet == 0) { +@@ -167,9 +170,20 @@ doRetry(nsd_gtls_t *pNsd) + } + break; + case gtlsRtry_recv: +- dbgprintf("retrying gtls recv, nsd: %p\n", pNsd); +- CHKiRet(gtlsRecordRecv(pNsd)); +- pNsd->rtryCall = gtlsRtry_None; /* we are done */ ++ dbgprintf("doRetry: retrying gtls recv, nsd: %p\n", pNsd); ++ iRet = gtlsRecordRecv(pNsd); ++ if (iRet == RS_RET_RETRY) { ++ // Check if there is pending data ++ size_t stBytesLeft = gnutls_record_check_pending(pNsd->sess); ++ if (stBytesLeft > 0) { ++ // We are in retry and more data waiting, finalize it ++ goto finalize_it; ++ } else { ++ dbgprintf("doRetry: gtlsRecordRecv returned RETRY, but there is no pending" ++ "data on nsd: %p\n", pNsd); ++ } ++ } ++ pNsd->rtryCall = gtlsRtry_None; /* no more data, we are done */ + gnuRet = 0; + break; + case gtlsRtry_None: +@@ -241,7 +255,7 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady) + * socket. -- rgerhards, 2010-11-20 + */ + if(pThis->iBufferRcvReady) { +- dbgprintf("nsd_gtls: dummy read, buffer not available for this FD\n"); ++ dbgprintf("nsd_gtls: dummy read, %p->buffer not available for this FD\n", pThis); + *pbIsReady = 0; + FINALIZE; + } +diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c +index 61c9444..06b9abe 100644 +--- a/runtime/tcpsrv.c ++++ b/runtime/tcpsrv.c +@@ -596,14 +596,15 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess, nspoll_t *pPoll) + int oserr = 0; + + ISOBJ_TYPE_assert(pThis, tcpsrv); +- DBGPRINTF("netstream %p with new data\n", (*ppSess)->pStrm); ++ prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); ++ DBGPRINTF("netstream %p with new data from remote peer %s\n", (*ppSess)->pStrm, pszPeer); + /* Receive message */ + iRet = pThis->pRcvData(*ppSess, buf, sizeof(buf), &iRcvd, &oserr); + switch(iRet) { + case RS_RET_CLOSED: + if(pThis->bEmitMsgOnClose) { + errno = 0; +- prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); ++ // prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); + LogError(0, RS_RET_PEER_CLOSED_CONN, "Netstream session %p closed by remote " + "peer %s.\n", (*ppSess)->pStrm, pszPeer); + } +@@ -619,13 +620,13 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t **ppSess, nspoll_t *pPoll) + /* in this case, something went awfully wrong. + * We are instructed to terminate the session. + */ +- prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); ++ // prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); + LogError(oserr, localRet, "Tearing down TCP Session from %s", pszPeer); + CHKiRet(closeSess(pThis, ppSess, pPoll)); + } + break; + default: +- prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); ++ // prop.GetString((*ppSess)->fromHostIP, &pszPeer, &lenPeer); + LogError(oserr, iRet, "netstream session %p from %s will be closed due to error", + (*ppSess)->pStrm, pszPeer); + CHKiRet(closeSess(pThis, ppSess, pPoll)); +@@ -835,6 +836,8 @@ RunSelect(tcpsrv_t *pThis, nsd_epworkset_t workset[], size_t sizeWorkset) + while(iTCPSess != -1) { + /* TODO: access to pNsd is NOT really CLEAN, use method... */ + CHKiRet(nssel.Add(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD)); ++ DBGPRINTF("tcpsrv process session %d:\n", iTCPSess); ++ + /* now get next... */ + iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess); + } +diff --git a/tests/imtcp-tls-basic.sh b/tests/imtcp-tls-basic.sh +index 8643389..58c5946 100755 +--- a/tests/imtcp-tls-basic.sh ++++ b/tests/imtcp-tls-basic.sh +@@ -4,6 +4,9 @@ + . ${srcdir:=.}/diag.sh init + export NUMMESSAGES=50000 + export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check ++# uncomment for debugging support: ++#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" ++#export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" + generate_conf + add_conf ' + global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" +-- +2.33.0 + diff --git a/backport-imptcp-bugfix-worker-thread-starvation-on-extreme-tr.patch b/backport-imptcp-bugfix-worker-thread-starvation-on-extreme-tr.patch new file mode 100644 index 0000000..e3a7e2e --- /dev/null +++ b/backport-imptcp-bugfix-worker-thread-starvation-on-extreme-tr.patch @@ -0,0 +1,65 @@ +From 54cbda6cde9bf667d699f7b0093d48a3983edb42 Mon Sep 17 00:00:00 2001 +From: Rainer Gerhards +Date: Fri, 4 Mar 2022 11:39:11 +0100 +Subject: [PATCH] imptcp bugfix: worker thread starvation on extreme traffic + +When connectes were totally busy, without any pause, the assigened worker +did never terminate its reading loop. As such, it could not service any +other conenctions. If this happened multiple time and to all configured +workers, all other connections could not be processed at all. This extreme +scenario is very unlikely, as the whole issue is relatively unlikely. + +In practice, the issue could lead to somewhat degraded performance and +resolved itself after some time (in practice no connection is 100% busy +for an extended period of time). + +Note that this patch sets a fixed limit of 16 iterations for very busy +connections. This sounds like a good compromise between non-starvation +and performance. The exact number may be made configurable if there +is really need to. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/34e72ced504458d804f8d1049be67ea8cc00a4b4 +--- + plugins/imptcp/imptcp.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c +index e47a7c9..72e32dd 100644 +--- a/plugins/imptcp/imptcp.c ++++ b/plugins/imptcp/imptcp.c +@@ -10,7 +10,7 @@ + * + * File begun on 2010-08-10 by RGerhards + * +- * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH. ++ * Copyright 2007-2022 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * +@@ -1391,7 +1391,7 @@ addEPollSock(epolld_type_t typ, void *ptr, int sock, epolld_t **pEpd) + epd->ptr = ptr; + epd->sock = sock; + *pEpd = epd; +- epd->ev.events = EPOLLIN|EPOLLET|EPOLLONESHOT; ++ epd->ev.events = EPOLLIN|EPOLLONESHOT; + epd->ev.data.ptr = (void*) epd; + + if(epoll_ctl(epollfd, EPOLL_CTL_ADD, sock, &(epd->ev)) != 0) { +@@ -1938,11 +1938,12 @@ sessActivity(ptcpsess_t *const pSess, int *const continue_polling) + int remsock = 0; /* init just to keep compiler happy... :-( */ + sbool bEmitOnClose = 0; + char rcvBuf[128*1024]; ++ int runs = 0; + DEFiRet; + + DBGPRINTF("imptcp: new activity on session socket %d\n", pSess->sock); + +- while(1) { ++ while(runs++ < 16) { + lenBuf = sizeof(rcvBuf); + lenRcv = recv(pSess->sock, rcvBuf, lenBuf, 0); + +-- +2.33.0 + diff --git a/backport-rsyslogd-adjust-the-order-of-doHUP-and-processImInte.patch b/backport-rsyslogd-adjust-the-order-of-doHUP-and-processImInte.patch new file mode 100644 index 0000000..0cfb6e9 --- /dev/null +++ b/backport-rsyslogd-adjust-the-order-of-doHUP-and-processImInte.patch @@ -0,0 +1,46 @@ +From e2d129880b6830bf7d26ab46d957b944f73f96e1 Mon Sep 17 00:00:00 2001 +From: Yun Zhou +Date: Thu, 24 Mar 2022 16:34:09 +0800 +Subject: [PATCH] rsyslogd: adjust the order of doHUP() and processImInternal() + +After call doHUP(), probably there is a internal log in the list. However, it +will not be wrote out immediately, because the mainloop will be blocked at +pselect in wait_timeout() until a long timeout or next message occur. +More deadly, the log may be lost if the deamon exits unexpectedly. + +We might as well put processImInternal() after doHUP(), so that the message +will be flushed out immediately. + +Fixes: 723f6fdfa6(rsyslogd: Fix race between signals and main loop timeout) +Signed-off-by: Yun Zhou +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/857f77906f95681aa15c7ba3f88cbda8952f7e5f +--- + tools/rsyslogd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/rsyslogd.c b/tools/rsyslogd.c +index 9a126dd..8410d44 100644 +--- a/tools/rsyslogd.c ++++ b/tools/rsyslogd.c +@@ -1966,8 +1966,6 @@ mainloop(void) + sigaddset(&sigblockset, SIGUSR1); + + do { +- processImInternal(); +- + pthread_sigmask(SIG_BLOCK, &sigblockset, &origmask); + if(bChildDied) { + reapChild(); +@@ -1988,6 +1986,8 @@ mainloop(void) + g_bRecordQueue = 0; + } + ++ processImInternal(); ++ + if(bFinished) + break; /* exit as quickly as possible */ + +-- +2.33.0 + diff --git a/backport-tcpsrv-do-not-decrease-number-of-to-be-processed-fds.patch b/backport-tcpsrv-do-not-decrease-number-of-to-be-processed-fds.patch new file mode 100644 index 0000000..6c70e5e --- /dev/null +++ b/backport-tcpsrv-do-not-decrease-number-of-to-be-processed-fds.patch @@ -0,0 +1,32 @@ +From d909290dc2d9ffab86409e054abd1abaaf998571 Mon Sep 17 00:00:00 2001 +From: Iwan Timmer +Date: Fri, 29 Apr 2022 15:14:27 +0200 +Subject: [PATCH] tcpsrv: do not decrease number of to be processed fds on + error + +nfds should only be decreased for processed streams and not for +streams returning an error code, like RS_RET_RETRY. + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/6ffc14fd450b90872272871130d29ab3ecf85f6f +--- + runtime/tcpsrv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/runtime/tcpsrv.c b/runtime/tcpsrv.c +index 06b9abe..2c91c2e 100644 +--- a/runtime/tcpsrv.c ++++ b/runtime/tcpsrv.c +@@ -880,7 +880,8 @@ RunSelect(tcpsrv_t *pThis, nsd_epworkset_t workset[], size_t sizeWorkset) + processWorkset(pThis, NULL, iWorkset, workset); + iWorkset = 0; + } +- --nfds; /* indicate we have processed one */ ++ if(bIsReady) ++ --nfds; /* indicate we have processed one */ + } + iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess); + } +-- +2.33.0 + diff --git a/backport-testbench-skip-omfwd_fast_imuxsock.sh-if-liblogging-stdlog-is-not-available.patch b/backport-testbench-skip-omfwd_fast_imuxsock.sh-if-liblogging-stdlog-is-not-available.patch new file mode 100644 index 0000000..5305235 --- /dev/null +++ b/backport-testbench-skip-omfwd_fast_imuxsock.sh-if-liblogging-stdlog-is-not-available.patch @@ -0,0 +1,35 @@ +From 62167fe37ee7af43d9eca49c8e025fa89959db20 Mon Sep 17 00:00:00 2001 +From: Michael Biebl +Date: Tue, 19 Oct 2021 23:00:50 +0200 +Subject: [PATCH] testbench: skip omfwd_fast_imuxsock.sh if liblogging-stdlog + is not available + +Fixes #4712 + +Conflict:NA +Reference:https://github.com/rsyslog/rsyslog/commit/440fd1d51c5aa7763d3d810b542a7e373a6738eb +--- + tests/omfwd_fast_imuxsock.sh | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tests/omfwd_fast_imuxsock.sh b/tests/omfwd_fast_imuxsock.sh +index bb35b58..10f9f19 100755 +--- a/tests/omfwd_fast_imuxsock.sh ++++ b/tests/omfwd_fast_imuxsock.sh +@@ -4,6 +4,13 @@ + . ${srcdir:=.}/diag.sh init + skip_platform "SunOS" "We have no ATOMIC BUILTINS, so OverallQueueSize counting of imdiag is NOT threadsafe and the counting will fail on SunOS" + ++./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 ++no_liblogging_stdlog=$? ++if [ $no_liblogging_stdlog -ne 0 ];then ++ echo "liblogging-stdlog not available - skipping test" ++ exit 77 ++fi ++ + # export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" + export NUMMESSAGES=100000 + +-- +2.33.0 + diff --git a/rsyslog.spec b/rsyslog.spec index eae4fbc..3f82d94 100644 --- a/rsyslog.spec +++ b/rsyslog.spec @@ -7,7 +7,7 @@ Name: rsyslog Version: 8.2110.0 -Release: 9 +Release: 10 Summary: The rocket-fast system for log processing License: (GPLv3+ and ASL 2.0) URL: http://www.rsyslog.com/ @@ -32,6 +32,16 @@ Patch9005: print-main-queue-info-to-journal-when-receive-USR1-signal.patch %endif Patch9006: bugfix-CVE-2022-24903.patch +Patch6000: backport-testbench-skip-omfwd_fast_imuxsock.sh-if-liblogging-stdlog-is-not-available.patch +Patch6001: backport-Fixes-4395-by-correctly-checking-for-EPIPE.patch +Patch6002: backport-rsyslogd-adjust-the-order-of-doHUP-and-processImInte.patch +Patch6003: backport-gnutls-bugfix-Fix-error-handling-in-gtlsRecordRecv.patch +Patch6004: backport-Fix-non-null-terminated-string-used-with-strlen.patch +Patch6005: backport-tcpsrv-do-not-decrease-number-of-to-be-processed-fds.patch +Patch6006: backport-imptcp-bugfix-worker-thread-starvation-on-extreme-tr.patch +Patch6007: backport-Fix-memory-leak-when-globally-de-initialize-GnuTLS.patch +Patch6008: backport-Fix-memory-leak-when-free-action-worker-data-table.patch + BuildRequires: gcc autoconf automake bison dos2unix flex pkgconfig python3-docutils libtool BuildRequires: libgcrypt-devel libuuid-devel zlib-devel krb5-devel libnet-devel gnutls-devel BuildRequires: libfastjson-devel >= 0.99.8 libestr-devel >= 0.1.9 python-sphinx @@ -265,7 +275,7 @@ export HIREDIS_LIBS="-L%{_libdir} -lhiredis" %configure \ --prefix=/usr \ --disable-static \ - --disable-testbench \ + --enable-testbench \ --enable-elasticsearch \ --enable-generate-man-pages \ --enable-gnutls \ @@ -338,7 +348,10 @@ install -m 0500 %{SOURCE6} $RPM_BUILD_ROOT%{_bindir}/os_check_timezone_for_rsysl install -m 0500 %{SOURCE9} $RPM_BUILD_ROOT%{_bindir}/timezone_update.sh cp -r doc/* $RPM_BUILD_ROOT%{rsyslog_docdir}/html - +rm -f %{buildroot}%{_libdir}/rsyslog/imdiag.so +rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_getaddrinfo.so +rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_gethostname.so +rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_gethostname_nonfqdn.so %delete_la %pre @@ -417,7 +430,6 @@ done %exclude %{rsyslog_docdir}/html %exclude %{rsyslog_docdir}/mysql-createDB.sql %exclude %{rsyslog_docdir}/pgsql-createDB.sql -%exclude %{_libdir}/rsyslog/imdiag.so %files hiredis %{_libdir}/rsyslog/omhiredis.so @@ -493,6 +505,9 @@ done %{_mandir}/man1/rscryutil.1.gz %changelog +* Thu Aug 04 2022 zhouwenpei - 8.2110.0-10 +- backport patches from upstream and enable check + * Mon May 23 2022 zhanghaolian - 8.2110.0-9 - fix CVE-2022-24903 -- Gitee