From 9315e534f87ce824d35538272ce82c5c6c79b08f Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 27 2022 12:32:50 +0000 Subject: import rsyslog-8.2102.0-105.el9 --- diff --git a/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-doc.patch b/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-doc.patch new file mode 100644 index 0000000..b717972 --- /dev/null +++ b/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-doc.patch @@ -0,0 +1,47 @@ +diff -up rsyslog-8.2102.0/doc/configuration/modules/imfile.html.state-file-leaking-doc rsyslog-8.2102.0/doc/configuration/modules/imfile.html +--- rsyslog-8.2102.0/doc/configuration/modules/imfile.html.state-file-leaking-doc 2021-02-15 12:53:31.000000000 +0100 ++++ rsyslog-8.2102.0/doc/configuration/modules/imfile.html 2022-03-29 10:35:07.187827004 +0200 +@@ -294,6 +294,28 @@ rsyslog needs write permissions to work + also might require SELinux definitions (or similar for other enhanced security + systems).

+ ++
++

deleteStateOnFileMove

++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
typedefaultmandatoryobsolete legacy directive
binaryoffnonone
++

This parameter controls if state files are deleted if their associated main file is rotated via move. Usually, this is a good idea, because otherwise state files are not deleted when log rotation occurs.

++ ++

However, there is one situation where not deleting associated state file after log rotation makes sense: this is the case if a monitored file is later moved back to the same location as it was before.

++
+ +
+

Input Parameters

+@@ -1214,6 +1236,7 @@ and Others.

+
  • sortFiles
  • +
  • PollingInterval
  • +
  • statefile.directory
  • ++
  • deleteStateOnFileMove
  • + + +
  • Input Parameters
      +@@ -1311,4 +1334,4 @@ and Others.

      + + +- +\ No newline at end of file ++ diff --git a/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-fix.patch b/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-fix.patch new file mode 100644 index 0000000..161f90c --- /dev/null +++ b/SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-fix.patch @@ -0,0 +1,162 @@ +diff -up rsyslog-8.2102.0/plugins/imfile/imfile.c.state-file-leaking rsyslog-8.2102.0/plugins/imfile/imfile.c +--- rsyslog-8.2102.0/plugins/imfile/imfile.c.state-file-leaking 2021-01-18 11:21:14.000000000 +0100 ++++ rsyslog-8.2102.0/plugins/imfile/imfile.c 2022-03-28 12:51:03.572554843 +0200 +@@ -259,6 +259,7 @@ struct modConfData_s { + Must be manually reset to 0 if desired. Helper for + polling mode. + */ ++ sbool deleteStateOnFileMove; + }; + static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */ + static modConfData_t *runModConf = NULL;/* modConf ptr to use for run process */ +@@ -305,7 +306,8 @@ static struct cnfparamdescr modpdescr[] + { "sortfiles", eCmdHdlrBinary, 0 }, + { "statefile.directory", eCmdHdlrString, 0 }, + { "normalizepath", eCmdHdlrBinary, 0 }, +- { "mode", eCmdHdlrGetWord, 0 } ++ { "mode", eCmdHdlrGetWord, 0 }, ++ { "deletestateonfilemove", eCmdHdlrBinary, 0 } + }; + static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, +@@ -545,11 +547,20 @@ static int + in_setupWatch(act_obj_t *const act, const int is_file) + { + int wd = -1; ++ int flags; + if(runModConf->opMode != OPMODE_INOTIFY) + goto done; + +- wd = inotify_add_watch(ino_fd, act->name, +- (is_file) ? IN_MODIFY|IN_DONT_FOLLOW : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO); ++ // wd = inotify_add_watch(ino_fd, act->name, ++ // (is_file) ? IN_MODIFY|IN_DONT_FOLLOW : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO); ++ if(is_file) ++ flags = IN_MODIFY|IN_DONT_FOLLOW; ++ else if(runModConf->deleteStateOnFileMove) ++ flags = IN_CREATE|IN_DELETE|IN_MOVED_TO; ++ else ++ flags = IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO; ++ wd = inotify_add_watch(ino_fd, act->name, flags); ++ + if(wd < 0) { + if (errno == EACCES) { /* There is high probability of selinux denial on top-level paths */ + DBGPRINTF("imfile: permission denied when adding watch for '%s'\n", act->name); +@@ -713,7 +724,7 @@ act_obj_add(fs_edge_t *const edge, const + char basename[MAXFNAME]; + DEFiRet; + int fd = -1; +- ++ + DBGPRINTF("act_obj_add: edge %p, name '%s' (source '%s')\n", edge, name, source? source : "---"); + for(act = edge->active ; act != NULL ; act = act->next) { + if(!strcmp(act->name, name)) { +@@ -977,9 +988,18 @@ act_obj_destroy(act_obj_t *const act, co + if(act == NULL) + return; + +- DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n", +- act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted, +- act->in_move); ++ // DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n", ++ // act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted, ++ // act->in_move); ++ if (runModConf->deleteStateOnFileMove) { ++ DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d\n", ++ act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted); ++ } else { ++ DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n", ++ act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, ++ is_deleted, act->in_move); ++ } ++ + if(act->is_symlink && is_deleted) { + act_obj_t *target_act; + for(target_act = act->edge->active ; target_act != NULL ; target_act = target_act->next) { +@@ -996,13 +1016,15 @@ act_obj_destroy(act_obj_t *const act, co + pollFile(act); /* get any left-over data */ + if(inst->bRMStateOnDel) { + statefn = getStateFileName(act, statefile, sizeof(statefile)); +- getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check! ++ // getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check! ++ getFullStateFileName(statefn, act->file_id, toDel, sizeof(toDel)); // TODO: check! + statefn = toDel; + } + persistStrmState(act); + strm.Destruct(&act->pStrm); + /* we delete state file after destruct in case strm obj initiated a write */ +- if(is_deleted && !act->in_move && inst->bRMStateOnDel) { ++ // if(is_deleted && !act->in_move && inst->bRMStateOnDel) { ++ if(is_deleted && inst->bRMStateOnDel && (runModConf->deleteStateOnFileMove || !act->in_move)) { + DBGPRINTF("act_obj_destroy: deleting state file %s\n", statefn); + unlink((char*)statefn); + } +@@ -1012,6 +1034,7 @@ act_obj_destroy(act_obj_t *const act, co + } + #ifdef HAVE_INOTIFY_INIT + if(act->wd != -1) { ++ inotify_rm_watch(ino_fd, act->wd); + wdmapDel(act->wd); + } + #endif +@@ -2026,6 +2049,7 @@ CODESTARTbeginCnfLoad + loadModConf->timeoutGranularity = 1000; /* default: 1 second */ + loadModConf->haveReadTimeouts = 0; /* default: no timeout */ + loadModConf->normalizePath = 1; ++ loadModConf->deleteStateOnFileMove = 0; + loadModConf->sortFiles = GLOB_NOSORT; + loadModConf->stateFileDirectory = NULL; + loadModConf->conf_tree = calloc(sizeof(fs_node_t), 1); +@@ -2085,6 +2109,8 @@ CODESTARTsetModCnf + loadModConf->stateFileDirectory = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(modpblk.descr[i].name, "normalizepath")) { + loadModConf->normalizePath = (sbool) pvals[i].val.d.n; ++ } else if(!strcmp(modpblk.descr[i].name, "deletestateonfilemove")) { ++ loadModConf->deleteStateOnFileMove = (sbool) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "mode")) { + if(!es_strconstcmp(pvals[i].val.d.estr, "polling")) + loadModConf->opMode = OPMODE_POLLING; +@@ -2388,16 +2414,35 @@ in_processEvent(struct inotify_event *ev + DBGPRINTF("in_processEvent process Event %x is_file %d, act->name '%s'\n", + ev->mask, etry->act->edge->is_file, etry->act->name); + +- if((ev->mask & IN_MOVED_FROM)) { +- flag_in_move(etry->act->edge->node->edges, ev->name); +- } +- if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) { +- fs_node_walk(etry->act->edge->node, poll_tree); +- } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) { +- in_handleFileEvent(ev, etry); // esentially poll_file()! ++ // if((ev->mask & IN_MOVED_FROM)) { ++ // flag_in_move(etry->act->edge->node->edges, ev->name); ++ // } ++ // if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) { ++ // fs_node_walk(etry->act->edge->node, poll_tree); ++ // } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) { ++ // in_handleFileEvent(ev, etry); // esentially poll_file()! ++ // } else { ++ // fs_node_walk(etry->act->edge->node, poll_tree); ++ // } ++ if(!runModConf->deleteStateOnFileMove) { ++ if((ev->mask & IN_MOVED_FROM)) { ++ flag_in_move(etry->act->edge->node->edges, ev->name); ++ } ++ if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) { ++ fs_node_walk(etry->act->edge->node, poll_tree); ++ } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) { ++ in_handleFileEvent(ev, etry); // esentially poll_file()! ++ } else { ++ fs_node_walk(etry->act->edge->node, poll_tree); ++ } + } else { +- fs_node_walk(etry->act->edge->node, poll_tree); ++ if((ev->mask & IN_MODIFY) && etry->act->edge->is_file && !(etry->act->is_symlink)) { ++ in_handleFileEvent(ev, etry); // esentially poll_file()! ++ } else { ++ fs_node_walk(etry->act->edge->node, poll_tree); ++ } + } ++ + done: return; + } + diff --git a/SOURCES/rsyslog-8.2102.0-rhbz2046158-gnutls-broken-connection.patch b/SOURCES/rsyslog-8.2102.0-rhbz2046158-gnutls-broken-connection.patch new file mode 100644 index 0000000..0c3a3a7 --- /dev/null +++ b/SOURCES/rsyslog-8.2102.0-rhbz2046158-gnutls-broken-connection.patch @@ -0,0 +1,215 @@ +diff -up rsyslog-8.2102.0/runtime/nsd_gtls.c.orig rsyslog-8.2102.0/runtime/nsd_gtls.c +--- rsyslog-8.2102.0/runtime/nsd_gtls.c.orig 2022-04-11 09:26:17.826271989 +0200 ++++ rsyslog-8.2102.0/runtime/nsd_gtls.c 2022-04-11 09:33:28.702012052 +0200 +@@ -556,7 +556,9 @@ 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) { +@@ -581,14 +583,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; +@@ -1978,6 +1996,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); +@@ -1998,10 +2017,12 @@ Send(nsd_t *pNsd, uchar *pBuf, ssize_t * + 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 -up rsyslog-8.2102.0/runtime/nsd_gtls.h.orig rsyslog-8.2102.0/runtime/nsd_gtls.h +--- rsyslog-8.2102.0/runtime/nsd_gtls.h.orig 2022-04-11 09:26:32.744262781 +0200 ++++ rsyslog-8.2102.0/runtime/nsd_gtls.h 2022-04-11 09:34:29.909982895 +0200 +@@ -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 -up rsyslog-8.2102.0/runtime/nsdsel_gtls.c.orig rsyslog-8.2102.0/runtime/nsdsel_gtls.c +--- rsyslog-8.2102.0/runtime/nsdsel_gtls.c.orig 2022-04-11 09:26:42.529256742 +0200 ++++ rsyslog-8.2102.0/runtime/nsdsel_gtls.c 2022-04-11 09:38:27.425869737 +0200 +@@ -81,6 +81,7 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsds + + 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,8 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsds + } + } + ++ 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 +123,8 @@ Select(nsdsel_t *pNsdsel, int *piNumRead + 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 +142,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 +155,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 +171,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 +256,7 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, + * 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 -up rsyslog-8.2102.0/runtime/tcpsrv.c.orig rsyslog-8.2102.0/runtime/tcpsrv.c +--- rsyslog-8.2102.0/runtime/tcpsrv.c.orig 2022-04-11 09:27:00.376245726 +0200 ++++ rsyslog-8.2102.0/runtime/tcpsrv.c 2022-04-11 09:41:57.885777708 +0200 +@@ -609,14 +609,15 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t * + 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); + } +@@ -632,13 +633,13 @@ doReceive(tcpsrv_t *pThis, tcps_sess_t * + /* 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)); +@@ -838,6 +839,7 @@ RunSelect(tcpsrv_t *pThis, nsd_epworkset + 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/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize-doc.patch b/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize-doc.patch new file mode 100644 index 0000000..01a6fc4 --- /dev/null +++ b/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize-doc.patch @@ -0,0 +1,51 @@ +--- a/source/configuration/actions.rst 2020-01-13 09:35:54.000000000 +0100 ++++ b/source/configuration/actions.rst 2022-03-09 10:46:23.945881936 +0100 +@@ -90,6 +90,12 @@ + provided to the action in question, the action name as well as + the rsyslog status code roughly explaining why it failed. + ++- **action.errorfile.maxsize** integer ++ ++ In some cases, error file needs to be limited in size. ++ This option allows specifying a maximum size, in bytes, for the error file. ++ When error file reaches that size, no more errors are written to it. ++ + - **action.execOnlyOnceEveryInterval** integer + + Execute action only if the last execute is at last seconds in the +--- a/build/_sources/configuration/actions.rst.txt 2020-01-13 09:35:54.000000000 +0100 ++++ b/build/_sources/configuration/actions.rst.txt 2022-03-09 11:17:44.391213038 +0100 +@@ -90,6 +90,12 @@ + provided to the action in question, the action name as well as + the rsyslog status code roughly explaining why it failed. + ++- **action.errorfile.maxsize** integer ++ ++ In some cases, error file needs to be limited in size. ++ This option allows specifying a maximum size, in bytes, for the error file. ++ When error file reaches that size, no more errors are written to it. ++ + - **action.execOnlyOnceEveryInterval** integer + + Execute action only if the last execute is at last seconds in the +--- a/build/configuration/actions.html 2021-02-15 12:53:30.000000000 +0100 ++++ b/build/configuration/actions.html 2022-03-09 11:27:04.035799702 +0100 +@@ -122,6 +122,11 @@ + provided to the action in question, the action name as well as + the rsyslog status code roughly explaining why it failed.

      + ++
    • action.errorfile.maxsize integer

      ++

      In some cases, error file needs to be limited in size. ++This option allows specifying a maximum size, in bytes, for the error file. ++When error file reaches that size, no more errors are written to it.

      ++
    • +
    • action.execOnlyOnceEveryInterval integer

      +

      Execute action only if the last execute is at last seconds in the + past (more info in ommail, but may be used with any action)

      +@@ -672,4 +677,4 @@ + + +- +\ No newline at end of file ++ diff --git a/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize.patch b/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize.patch new file mode 100644 index 0000000..ba5bec9 --- /dev/null +++ b/SOURCES/rsyslog-8.2102.0-rhbz2064318-errfile-maxsize.patch @@ -0,0 +1,192 @@ +--- rsyslog-8.2102.0-ori/action.c 2021-02-15 12:06:16.000000000 +0100 ++++ rsyslog-8.2102.0-changes/action.c 2022-03-10 11:00:11.027242300 +0100 +@@ -198,6 +198,7 @@ + { "name", eCmdHdlrGetWord, 0 }, /* legacy: actionname */ + { "type", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: actionname */ + { "action.errorfile", eCmdHdlrString, 0 }, ++ { "action.errorfile.maxsize", eCmdHdlrInt, 0 }, + { "action.writeallmarkmessages", eCmdHdlrBinary, 0 }, /* legacy: actionwriteallmarkmessages */ + { "action.execonlyeverynthtime", eCmdHdlrInt, 0 }, /* legacy: actionexeconlyeverynthtime */ + { "action.execonlyeverynthtimetimeout", eCmdHdlrInt, 0 }, /* legacy: actionexeconlyeverynthtimetimeout */ +@@ -400,6 +401,8 @@ + pThis->iResumeRetryCount = 0; + pThis->pszName = NULL; + pThis->pszErrFile = NULL; ++ pThis->maxErrFileSize = 0; ++ pThis->errFileWritten = 0; + pThis->pszExternalStateFile = NULL; + pThis->fdErrFile = -1; + pThis->bWriteAllMarkMsgs = 1; +@@ -1436,6 +1439,14 @@ + pThis->pszName, pThis->pszErrFile); + goto done; + } ++ if (pThis->maxErrFileSize > 0) { ++ struct stat statbuf; ++ if (fstat(pThis->fdErrFile, &statbuf) == -1) { ++ LogError(errno, RS_RET_ERR, "failed to fstat %s", pThis->pszErrFile); ++ goto done; ++ } ++ pThis->errFileWritten += statbuf.st_size; ++ } + } + + for(int i = 0 ; i < nparams ; ++i) { +@@ -1454,16 +1465,26 @@ + char *const rendered = strdup((char*)fjson_object_to_json_string(etry)); + if(rendered == NULL) + goto done; +- const size_t toWrite = strlen(rendered) + 1; +- /* note: we use the '\0' inside the string to store a LF - we do not +- * otherwise need it and it safes us a copy/realloc. +- */ +- rendered[toWrite-1] = '\n'; /* NO LONGER A STRING! */ +- const ssize_t wrRet = write(pThis->fdErrFile, rendered, toWrite); +- if(wrRet != (ssize_t) toWrite) { +- LogError(errno, RS_RET_IO_ERROR, +- "action %s: error writing errorFile %s, write returned %lld", +- pThis->pszName, pThis->pszErrFile, (long long) wrRet); ++ size_t toWrite = strlen(rendered) + 1; ++ // Check if need to truncate the amount of bytes to write ++ if (pThis->maxErrFileSize > 0) { ++ if (pThis->errFileWritten + toWrite > pThis->maxErrFileSize) { ++ // Truncate to the pending available ++ toWrite = pThis->maxErrFileSize - pThis->errFileWritten; ++ } ++ pThis->errFileWritten += toWrite; ++ } ++ if(toWrite > 0) { ++ /* note: we use the '\0' inside the string to store a LF - we do not ++ * otherwise need it and it safes us a copy/realloc. ++ */ ++ rendered[toWrite-1] = '\n'; /* NO LONGER A STRING! */ ++ const ssize_t wrRet = write(pThis->fdErrFile, rendered, toWrite); ++ if(wrRet != (ssize_t) toWrite) { ++ LogError(errno, RS_RET_IO_ERROR, ++ "action %s: error writing errorFile %s, write returned %lld", ++ pThis->pszName, pThis->pszErrFile, (long long) wrRet); ++ } + } + free(rendered); + +@@ -2048,6 +2069,8 @@ + continue; /* this is handled seperately during module select! */ + } else if(!strcmp(pblk.descr[i].name, "action.errorfile")) { + pAction->pszErrFile = es_str2cstr(pvals[i].val.d.estr, NULL); ++ } else if(!strcmp(pblk.descr[i].name, "action.errorfile.maxsize")) { ++ pAction->maxErrFileSize = pvals[i].val.d.n; + } else if(!strcmp(pblk.descr[i].name, "action.externalstate.file")) { + pAction->pszExternalStateFile = es_str2cstr(pvals[i].val.d.estr, NULL); + } else if(!strcmp(pblk.descr[i].name, "action.writeallmarkmessages")) { +--- rsyslog-8.2102.0-ori/action.h 2020-10-03 19:06:47.000000000 +0200 ++++ rsyslog-8.2102.0-changes/action.h 2022-03-04 11:36:47.024588972 +0100 +@@ -77,6 +77,8 @@ + /* error file */ + const char *pszErrFile; + int fdErrFile; ++ size_t maxErrFileSize; ++ size_t errFileWritten; + pthread_mutex_t mutErrFile; + /* external stat file system */ + const char *pszExternalStateFile; +--- rsyslog-8.2102.0-ori/tests/Makefile.am 2021-02-15 12:06:16.000000000 +0100 ++++ rsyslog-8.2102.0-changes/tests/Makefile.am 2022-03-04 11:38:01.625095709 +0100 +@@ -695,7 +695,8 @@ + mysql-actq-mt.sh \ + mysql-actq-mt-withpause.sh \ + action-tx-single-processing.sh \ +- action-tx-errfile.sh ++ action-tx-errfile.sh \ ++ action-tx-errfile-maxsize.sh + + mysql-basic.log: mysqld-start.log + mysql-basic-cnf6.log: mysqld-start.log +@@ -2156,6 +2157,8 @@ + sndrcv_omudpspoof_nonstdpt.sh \ + sndrcv_gzip.sh \ + action-tx-single-processing.sh \ ++ omfwd-errfile-maxsize.sh \ ++ action-tx-errfile-maxsize.sh \ + action-tx-errfile.sh \ + testsuites/action-tx-errfile.result \ + pipeaction.sh \ +--- rsyslog-8.2102.0-ori/tests/omfwd-errfile-maxsize.sh 1970-01-01 01:00:00.000000000 +0100 ++++ rsyslog-8.2102.0-changes/tests/omfwd-errfile-maxsize.sh 2022-03-04 11:39:02.060506234 +0100 +@@ -0,0 +1,17 @@ ++#!/bin/bash ++# part of the rsyslog project, released under ASL 2.0 ++. ${srcdir:=.}/diag.sh init ++ ++export MAX_ERROR_SIZE=1999 ++ ++generate_conf ++add_conf ' ++action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist" ++ action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") ++' ++startup ++shutdown_when_empty ++wait_shutdown ++check_file_exists ${RSYSLOG2_OUT_LOG} ++file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE} ++exit_test +--- rsyslog-8.2102.0-ori/tests/action-tx-errfile-maxsize.sh 1970-01-01 01:00:00.000000000 +0100 ++++ rsyslog-8.2102.0-changes/tests/action-tx-errfile-maxsize.sh 2022-03-04 11:59:22.592796989 +0100 +@@ -0,0 +1,35 @@ ++#!/bin/bash ++# part of the rsyslog project, released under ASL 2.0 ++ ++. ${srcdir:=.}/diag.sh init ++ ++export NUMMESSAGES=50 # enough to generate big file ++export MAX_ERROR_SIZE=100 ++ ++generate_conf ++add_conf ' ++$ModLoad ../plugins/ommysql/.libs/ommysql ++global(errormessagestostderr.maxnumber="5") ++ ++template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on") ++ ++if((not($msg contains "error")) and ($msg contains "msgnum:")) then { ++ set $.num = field($msg, 58, 2); ++ if $.num % 2 == 0 then { ++ set $!facility = $syslogfacility; ++ } else { ++ set $/cntr = 0; ++ } ++ action(type="ommysql" name="mysql_action_errfile_maxsize" server="127.0.0.1" template="tpl" ++ db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") ++} ++' ++mysql_prep_for_test ++startup ++injectmsg ++shutdown_when_empty ++wait_shutdown ++mysql_get_data ++check_file_exists ${RSYSLOG2_OUT_LOG} ++file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE} ++exit_test +--- rsyslog-8.2102.0/tests/omfwd-errfile-maxsize-filled.sh 1970-01-01 01:00:00.000000000 +0100 ++++ rsyslog-8.2102.0-changes/tests/omfwd-errfile-maxsize-filled.sh 2022-03-08 16:24:01.174365289 +0100 +@@ -0,0 +1,19 @@ ++#!/bin/bash ++# part of the rsyslog project, released under ASL 2.0 ++. ${srcdir:=.}/diag.sh init ++ERRFILE=$(mktemp) ++export MAX_ERROR_SIZE=1999 ++export INITIAL_FILE_SIZE=$((MAX_ERROR_SIZE - 100)) ++dd if=/dev/urandom of=${ERRFILE} bs=1 count=${INITIAL_FILE_SIZE} ++generate_conf ++add_conf ' ++action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist" ++ action.errorfile="'$ERRFILE'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") ++' ++startup ++shutdown_when_empty ++wait_shutdown ++check_file_exists ${ERRFILE} ++file_size_check ${ERRFILE} ${MAX_ERROR_SIZE} ++exit_test ++rm ${ERRFILE} diff --git a/SOURCES/rsyslog-8.37.0-rhbz2081396-CVE-2022-24903.patch b/SOURCES/rsyslog-8.37.0-rhbz2081396-CVE-2022-24903.patch new file mode 100644 index 0000000..e3b1453 --- /dev/null +++ b/SOURCES/rsyslog-8.37.0-rhbz2081396-CVE-2022-24903.patch @@ -0,0 +1,30 @@ +diff -up rsyslog-8.37.0/plugins/imptcp/imptcp.c.orig rsyslog-8.37.0/plugins/imptcp/imptcp.c +--- rsyslog-8.37.0/plugins/imptcp/imptcp.c.orig 2022-05-09 12:22:59.050623119 +0200 ++++ rsyslog-8.37.0/plugins/imptcp/imptcp.c 2022-05-09 12:34:39.979854853 +0200 +@@ -1032,7 +1032,10 @@ processDataRcvd(ptcpsess_t *const __rest + if(pThis->iOctetsRemain <= 200000000) { + pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0'; + } +- *(pThis->pMsg + pThis->iMsg++) = c; ++ // *(pThis->pMsg + pThis->iMsg++) = c; ++ if(pThis->iMsg < iMaxLine) { ++ *(pThis->pMsg + pThis->iMsg++) = c; ++ } + } else { /* done with the octet count, so this must be the SP terminator */ + DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain); + prop.GetString(pThis->peerName, &propPeerName, &lenPeerName); +diff -up rsyslog-8.37.0/runtime/tcps_sess.c.orig rsyslog-8.37.0/runtime/tcps_sess.c +--- rsyslog-8.37.0/runtime/tcps_sess.c.orig 2022-05-09 12:23:12.789627661 +0200 ++++ rsyslog-8.37.0/runtime/tcps_sess.c 2022-05-09 12:36:51.426898549 +0200 +@@ -389,7 +389,10 @@ processDataRcvd(tcps_sess_t *pThis, + if(pThis->iOctetsRemain <= 200000000) { + pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0'; + } +- *(pThis->pMsg + pThis->iMsg++) = c; ++ // *(pThis->pMsg + pThis->iMsg++) = c; ++ if(pThis->iMsg < iMaxLine) { ++ *(pThis->pMsg + pThis->iMsg++) = c; ++ } + } else { /* done with the octet count, so this must be the SP terminator */ + DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain); + prop.GetString(pThis->fromHost, &propPeerName, &lenPeerName); diff --git a/SPECS/rsyslog.spec b/SPECS/rsyslog.spec index 2834bd5..d5988f2 100644 --- a/SPECS/rsyslog.spec +++ b/SPECS/rsyslog.spec @@ -5,7 +5,7 @@ Summary: Enhanced system logging and kernel message trapping daemon Name: rsyslog Version: 8.2102.0 -Release: 101%{?dist} +Release: 105%{?dist} License: (GPLv3+ and ASL 2.0) URL: http://www.rsyslog.com/ Source0: http://www.rsyslog.com/files/download/rsyslog/%{name}-%{version}.tar.gz @@ -18,14 +18,20 @@ Source5: rsyslog.service # separatae sub-package with it statically linked(see rhbz#1713427) Source6: qpid-proton-0.34.0.tar.gz -Patch0: openssl3-compatibility.patch -Patch1: rsyslog-8.1911.0-rhbz1659898-imjournal-default-tag.patch -Patch2: rsyslog-8.2102.0-rhbz1960536-fdleak-on-fsync.patch -Patch3: rsyslog-8.2102.0-rhbz1886400-reduce-default-timeout.patch -Patch4: rsyslog-8.2102.0-rhbz1984616-imuxsock-ratelimit.patch -Patch5: rsyslog-8.2102.0-rhbz1984489-remove-abort-on-id-resolution-fail.patch -Patch6: rsyslog-8.2102.0-rhbz1938863-covscan.patch -Patch7: rsyslog-8.2102.0-rhbz2021076-prioritize-SAN.patch +Patch0: rsyslog-8.2102.0-rhbz2064318-errfile-maxsize-doc.patch +Patch1: rsyslog-8.1911.0-rhbz1659898-imjournal-default-tag.patch +Patch2: rsyslog-8.2102.0-rhbz1960536-fdleak-on-fsync.patch +Patch3: rsyslog-8.2102.0-rhbz1886400-reduce-default-timeout.patch +Patch4: rsyslog-8.2102.0-rhbz1984616-imuxsock-ratelimit.patch +Patch5: rsyslog-8.2102.0-rhbz1984489-remove-abort-on-id-resolution-fail.patch +Patch6: rsyslog-8.2102.0-rhbz1938863-covscan.patch +Patch7: rsyslog-8.2102.0-rhbz2021076-prioritize-SAN.patch +Patch8: rsyslog-8.2102.0-rhbz2064318-errfile-maxsize.patch +Patch9: openssl3-compatibility.patch +Patch10: rsyslog-8.2102.0-rhbz1909639-statefiles-fix.patch +Patch11: rsyslog-8.2102.0-rhbz1909639-statefiles-doc.patch +Patch12: rsyslog-8.2102.0-rhbz2046158-gnutls-broken-connection.patch +Patch13: rsyslog-8.37.0-rhbz2081396-CVE-2022-24903.patch BuildRequires: make BuildRequires: gcc @@ -250,6 +256,8 @@ container metadata. %prep # set up rsyslog-doc sources %setup -q -a 1 -T -c +%patch0 -p1 + rm -r LICENSE README.md source build/objects.inv mv build doc # set up rsyslog sources @@ -257,16 +265,21 @@ mv build doc # Unpack qpid-proton for rhel %setup -q -D -T -b 6 -%patch1 -p1 -b .default-tag -%patch2 -p1 -b .fd-leak-on-fsync -%patch3 -p1 -b .timeout -%patch4 -p1 -b .imuxsock-rate-limit -%patch5 -p1 -b .abort-on-id-resolution-fail -%patch6 -p1 -b .covscan -%patch7 -p1 -b .prioritize-SAN +%patch1 -p1 -b .default-tag +%patch2 -p1 -b .fd-leak-on-fsync +%patch3 -p1 -b .timeout +%patch4 -p1 -b .imuxsock-rate-limit +%patch5 -p1 -b .abort-on-id-resolution-fail +%patch6 -p1 -b .covscan +%patch7 -p1 -b .prioritize-SAN +%patch8 -p1 -b .errfile-maxsize +%patch10 -p1 -b .statefile-fix +%patch11 -p1 +%patch12 -p1 -b .gnutls-broken-connection +%patch13 -p1 -b .CVE pushd .. -%patch0 -p1 -b .openssl-compatibility +%patch9 -p1 -b .openssl-compatibility popd %build @@ -528,6 +541,25 @@ done %changelog +* Mon May 09 2022 Attila Lakatos - 8.2102.0-105 +- Address CVE-2022-24903, Heap-based overflow in TCP syslog server + resolves: rhbz#2081403 + +* Tue Apr 19 2022 Attila Lakatos - 8.2102.0-104 +- Do not save patched doc files + resolves: rhbz#2069664 + +* Tue Apr 05 2022 Attila Lakatos - 8.2102.0-103 +- Add deleteStateOnFileMove imfile module option + resolves: rhbz#2069664 +- Add inotify_rm_watch() inotify API call when object needs to be destroyed + resolves: rhbz#2070528 +- Fix error handling in gtlsRecordRecv, which can cause full CPU usage + +* Fri Mar 11 2022 Sergio Arroutbi - 8.2102.0-102 +- Add action.errorfile.maxsize parameter + resolves: rhbz#2064318 + * Wed Jan 19 2022 Sergio Arroutbi - 8.2102.0-101 - Prioritize SAN resolves: rhbz#2021076