From 9b3c8c1e255d87ebf8214939b5f1a213d68b4e9d Mon Sep 17 00:00:00 2001 From: jinzhimin369 Date: Wed, 13 Jan 2021 18:54:01 +0800 Subject: [PATCH] round community patches up to 8.2010.0 --- ...ions-for-imptcp.c-similar-to-imtcp.c.patch | 311 ++++++++++++++++++ ...pty-objects-when-accessing-non-exist.patch | 75 +++++ ...MUDP-add-missing-free-during-freeCnf.patch | 24 ++ ...HUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch | 44 +++ ...rPositiveInt-with-eCmdHdlrNonNegInt-.patch | 133 ++++++++ ...ix-intended-warning-emitted-as-error.patch | 30 ++ ...ntial-segfault-on-querey-of-PROGRAMN.patch | 57 ++++ ...ault-if-disk-queue-file-cannot-be-cr.patch | 133 ++++++++ ...y-net.enableDNS-off-when-querying-lo.patch | 26 ++ ...dshake-error-handling-into-doRetry-h.patch | 47 +++ ...-CheckExtendedKeyPurpose-when-accept.patch | 29 ++ ...ken-connection-not-necessariy-detect.patch | 30 ++ ...in-msgAddJSON-if-jsonPathFindParent-.patch | 32 ++ ...jsonPathFindNext-when-root-is-not-an.patch | 40 +++ ...Fix-reply-buffer-reset-after-health-.patch | 42 +++ ...g-size-to-64kb-for-sndrcv_omudpspoof.patch | 26 ++ ...ueue-info-to-journal-when-queue-full.patch | 80 +++++ ...-to-journal-when-receive-USR1-signal.patch | 80 +++++ ...r-rsyslog.service.in-create-PID-file.patch | 30 ++ ...ize-variables-and-check-return-value.patch | 13 - rsyslog.spec | 28 +- timezone_update.sh | 4 + 22 files changed, 1299 insertions(+), 15 deletions(-) create mode 100644 backport-Add-max-sessions-for-imptcp.c-similar-to-imtcp.c.patch create mode 100644 backport-Do-not-create-empty-objects-when-accessing-non-exist.patch create mode 100644 backport-FIX-IMUDP-add-missing-free-during-freeCnf.patch create mode 100644 backport-Replace-GNUTLS_SHUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch create mode 100644 backport-Replaced-eCmdHdlrPositiveInt-with-eCmdHdlrNonNegInt-.patch create mode 100644 backport-config-bugfix-intended-warning-emitted-as-error.patch create mode 100644 backport-core-bugfix-potential-segfault-on-querey-of-PROGRAMN.patch create mode 100644 backport-core-bugfix-segfault-if-disk-queue-file-cannot-be-cr.patch create mode 100644 backport-core-network-obey-net.enableDNS-off-when-querying-lo.patch create mode 100644 backport-gnutls-Added-handshake-error-handling-into-doRetry-h.patch create mode 100644 backport-gnutls-Propagate-CheckExtendedKeyPurpose-when-accept.patch create mode 100644 backport-imtcp-bugfix-broken-connection-not-necessariy-detect.patch create mode 100644 backport-msg-memory-leak-in-msgAddJSON-if-jsonPathFindParent-.patch create mode 100644 backport-msg-segfault-in-jsonPathFindNext-when-root-is-not-an.patch create mode 100644 backport-omelasticsearch-Fix-reply-buffer-reset-after-health-.patch create mode 100644 backport-testbench-set-msg-size-to-64kb-for-sndrcv_omudpspoof.patch create mode 100644 openEuler-print-main-queue-info-to-journal-when-queue-full.patch create mode 100644 openEuler-print-main-queue-info-to-journal-when-receive-USR1-signal.patch create mode 100644 openEuler-rsyslog.service.in-create-PID-file.patch create mode 100644 timezone_update.sh diff --git a/backport-Add-max-sessions-for-imptcp.c-similar-to-imtcp.c.patch b/backport-Add-max-sessions-for-imptcp.c-similar-to-imtcp.c.patch new file mode 100644 index 0000000..c9407ec --- /dev/null +++ b/backport-Add-max-sessions-for-imptcp.c-similar-to-imtcp.c.patch @@ -0,0 +1,311 @@ +From 6c50426dbfd309c03916918541095e9500ea98c6 Mon Sep 17 00:00:00 2001 +From: Alfred Perlstein +Date: Sun, 9 Aug 2020 16:45:56 -0700 +Subject: [PATCH 22/73] Add max sessions for imptcp.c similar to imtcp.c + +The max is per-instance, not global across all instances. + +There is also a bugfix where if epoll failed I think we could leave a +session linked in the list of sessions, this code unlinks it. +--- + plugins/imptcp/imptcp.c | 72 ++++++++++++++++++++++++++++--------- + tests/Makefile.am | 2 ++ + tests/imptcp_maxsessions.sh | 46 ++++++++++++++++++++++++ + 3 files changed, 104 insertions(+), 16 deletions(-) + create mode 100755 tests/imptcp_maxsessions.sh + +diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c +index 4d261a29f..e89971dbe 100644 +--- a/plugins/imptcp/imptcp.c ++++ b/plugins/imptcp/imptcp.c +@@ -128,6 +128,7 @@ typedef struct configSettings_s { + uchar *lstnIP; /* which IP we should listen on? */ + uchar *pszBindRuleset; + int wrkrMax; /* max number of workers (actually "helper workers") */ ++ int iTCPSessMax; /* max open connections per instance */ + } configSettings_t; + static configSettings_t cs; + +@@ -164,6 +165,7 @@ struct instanceConf_s { + unsigned int ratelimitBurst; + uchar *startRegex; + regex_t start_preg; /* compiled version of startRegex */ ++ int iTCPSessMax; /* max open connections */ + struct instanceConf_s *next; + }; + +@@ -173,6 +175,7 @@ struct modConfData_s { + instanceConf_t *root, *tail; + int wrkrMax; + int bProcessOnPoller; ++ int iTCPSessMax; + sbool configSetViaV2Method; + }; + +@@ -182,6 +185,7 @@ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current lo + /* module-global parameters */ + static struct cnfparamdescr modpdescr[] = { + { "threads", eCmdHdlrPositiveInt, 0 }, ++ { "maxsessions", eCmdHdlrInt, 0 }, + { "processOnPoller", eCmdHdlrBinary, 0 } + }; + static struct cnfparamblk modpblk = +@@ -211,6 +215,7 @@ static struct cnfparamdescr inppdescr[] = { + { "defaulttz", eCmdHdlrString, 0 }, + { "supportoctetcountedframing", eCmdHdlrBinary, 0 }, + { "framingfix.cisco.asa", eCmdHdlrBinary, 0 }, ++ { "maxsessions", eCmdHdlrInt, 0 }, + { "notifyonconnectionclose", eCmdHdlrBinary, 0 }, + { "notifyonconnectionopen", eCmdHdlrBinary, 0 }, + { "compression.mode", eCmdHdlrGetWord, 0 }, +@@ -269,6 +274,8 @@ struct ptcpsrv_s { + ruleset_t *pRuleset; + ptcplstn_t *pLstn; /* root of our listeners */ + ptcpsess_t *pSess; /* root of our sessions */ ++ int iTCPSessCnt; ++ int iTCPSessMax; + pthread_mutex_t mutSessLst; + sbool bKeepAlive; /* support keep-alive packets */ + sbool bEmitMsgOnClose; +@@ -401,6 +408,24 @@ destructSess(ptcpsess_t *pSess) + free(pSess); + } + ++/* remove session from server */ ++static void ++unlinkSess(ptcpsess_t *pSess) { ++ ptcpsrv_t *pSrv = pSess->pLstn->pSrv; ++ pthread_mutex_lock(&pSrv->mutSessLst); ++ pSrv->iTCPSessCnt--; ++ /* finally unlink session from structures */ ++ if(pSess->next != NULL) ++ pSess->next->prev = pSess->prev; ++ if(pSess->prev == NULL) { ++ /* need to update root! */ ++ pSrv->pSess = pSess->next; ++ } else { ++ pSess->prev->next = pSess->next; ++ } ++ pthread_mutex_unlock(&pSrv->mutSessLst); ++} ++ + static void + destructSrv(ptcpsrv_t *pSrv) + { +@@ -717,7 +742,7 @@ getPeerNames(prop_t **peerName, prop_t **peerIP, struct sockaddr *pAddr, sbool b + uchar szHname[NI_MAXHOST+1] = ""; + struct addrinfo hints, *res; + sbool bMaliciousHName = 0; +- ++ + DEFiRet; + + *peerName = NULL; +@@ -1470,6 +1495,7 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP) + int pmsg_size_factor; + + CHKmalloc(pSess = malloc(sizeof(ptcpsess_t))); ++ pSess->next = NULL; + if(pLstn->pSrv->inst->startRegex == NULL) { + pmsg_size_factor = 1; + pSess->pMsg_save = NULL; +@@ -1494,7 +1520,17 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP) + + /* add to start of server's listener list */ + pSess->prev = NULL; ++ + pthread_mutex_lock(&pSrv->mutSessLst); ++ int iTCPSessMax = pSrv->inst->iTCPSessMax; ++ if (iTCPSessMax > 0 && pSrv->iTCPSessCnt >= iTCPSessMax) { ++ pthread_mutex_unlock(&pSrv->mutSessLst); ++ LogError(0, RS_RET_MAX_SESS_REACHED, ++ "too many tcp sessions - dropping incoming request"); ++ ABORT_FINALIZE(RS_RET_MAX_SESS_REACHED); ++ } ++ ++ pSrv->iTCPSessCnt++; + pSess->next = pSrv->pSess; + if(pSrv->pSess != NULL) + pSrv->pSess->prev = pSess; +@@ -1506,6 +1542,9 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP) + finalize_it: + if(iRet != RS_RET_OK) { + if(pSess != NULL) { ++ if (pSess->next != NULL) { ++ unlinkSess(pSess); ++ } + free(pSess->pMsg_save); + free(pSess->pMsg); + free(pSess); +@@ -1566,24 +1605,14 @@ static rsRetVal + closeSess(ptcpsess_t *pSess) + { + DEFiRet; +- ++ + if(pSess->compressionMode >= COMPRESS_STREAM_ALWAYS) + doZipFinish(pSess); + + const int sock = pSess->sock; + close(sock); + +- pthread_mutex_lock(&pSess->pLstn->pSrv->mutSessLst); +- /* finally unlink session from structures */ +- if(pSess->next != NULL) +- pSess->next->prev = pSess->prev; +- if(pSess->prev == NULL) { +- /* need to update root! */ +- pSess->pLstn->pSrv->pSess = pSess->next; +- } else { +- pSess->prev->next = pSess->next; +- } +- pthread_mutex_unlock(&pSess->pLstn->pSrv->mutSessLst); ++ unlinkSess(pSess); + + if(pSess->pLstn->pSrv->bEmitMsgOnClose) { + LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "imptcp: session on socket %d closed " +@@ -1641,6 +1670,7 @@ createInstance(instanceConf_t **pinst) + inst->multiLine = 0; + inst->socketBacklog = 5; + inst->pszLstnPortFileName = NULL; ++ inst->iTCPSessMax = -1; + + /* node created, let's add to config */ + if(loadModConf->tail == NULL) { +@@ -1698,6 +1728,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *const pNe + inst->bEmitMsgOnOpen = cs.bEmitMsgOnOpen; + inst->iAddtlFrameDelim = cs.iAddtlFrameDelim; + inst->maxFrameSize = cs.maxFrameSize; ++ inst->iTCPSessMax = cs.iTCPSessMax; + + finalize_it: + free(pNewVal); +@@ -1756,6 +1787,7 @@ addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst) + pSrv->flowControl = inst->flowControl; + pSrv->pRuleset = inst->pBindRuleset; + pSrv->pszInputName = ustrdup((inst->pszInputName == NULL) ? UCHAR_CONSTANT("imptcp") : inst->pszInputName); ++ pSrv->iTCPSessMax = inst->iTCPSessMax; + CHKiRet(prop.Construct(&pSrv->pInputName)); + CHKiRet(prop.SetString(pSrv->pInputName, pSrv->pszInputName, ustrlen(pSrv->pszInputName))); + CHKiRet(prop.ConstructFinalize(pSrv->pInputName)); +@@ -2022,13 +2054,13 @@ enqueueIoWork(epolld_t *epd, int dispatchInlineIfQueueFull) { + int dispatchInline; + int inlineDispatchThreshold; + DEFiRet; +- ++ + CHKmalloc(n = malloc(sizeof(io_req_t))); + n->epd = epd; +- ++ + inlineDispatchThreshold = DFLT_inlineDispatchThreshold * runModConf->wrkrMax; + dispatchInline = 0; +- ++ + pthread_mutex_lock(&io_q.mut); + if (dispatchInlineIfQueueFull && io_q.sz > inlineDispatchThreshold) { + dispatchInline = 1; +@@ -2200,6 +2232,8 @@ CODESTARTnewInpInst + ABORT_FINALIZE(RS_RET_PARAM_ERROR); + } + free(cstr); ++ } else if(!strcmp(inppblk.descr[i].name, "maxsessions")) { ++ inst->iTCPSessMax = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "keepalive")) { + inst->bKeepAlive = (int) pvals[i].val.d.n; + } else if(!strcmp(inppblk.descr[i].name, "keepalive.probes")) { +@@ -2248,6 +2282,10 @@ CODESTARTnewInpInst + ABORT_FINALIZE(RS_RET_ERR); + } + } ++ ++ if (inst->iTCPSessMax == -1) { ++ inst->iTCPSessMax = loadModConf->iTCPSessMax; ++ } + finalize_it: + CODE_STD_FINALIZERnewInpInst + cnfparamvalsDestruct(pvals, &inppblk); +@@ -2289,6 +2327,8 @@ CODESTARTsetModCnf + continue; + if(!strcmp(modpblk.descr[i].name, "threads")) { + loadModConf->wrkrMax = (int) pvals[i].val.d.n; ++ } else if(!strcmp(modpblk.descr[i].name, "maxsessions")) { ++ loadModConf->iTCPSessMax = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "processOnPoller")) { + loadModConf->bProcessOnPoller = (int) pvals[i].val.d.n; + } else { +diff --git a/tests/Makefile.am b/tests/Makefile.am +index f982dad5d..0df67672c 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1000,6 +1000,7 @@ TESTS += \ + imptcp_no_octet_counted.sh \ + imptcp_multi_line.sh \ + imptcp_spframingfix.sh \ ++ imptcp_maxsessions.sh \ + imptcp_nonProcessingPoller.sh \ + imptcp_veryLargeOctateCountedMessages.sh \ + imptcp-basic-hup.sh \ +@@ -2472,6 +2473,7 @@ EXTRA_DIST= \ + testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl \ + testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl \ + json_var_cmpr.sh \ ++ imptcp_maxsessions.sh \ + imptcp_nonProcessingPoller.sh \ + imptcp_veryLargeOctateCountedMessages.sh \ + known_issues.supp \ +diff --git a/tests/imptcp_maxsessions.sh b/tests/imptcp_maxsessions.sh +new file mode 100755 +index 000000000..3162eb619 +--- /dev/null ++++ b/tests/imptcp_maxsessions.sh +@@ -0,0 +1,46 @@ ++#!/bin/bash ++# Test imtcp with many dropping connections ++# added 2010-08-10 by Rgerhards ++# ++# This file is part of the rsyslog project, released under GPLv3 ++. ${srcdir:=.}/diag.sh init ++skip_platform "FreeBSD" "This test currently does not work on FreeBSD" ++export NUMMESSAGES=500 ++ ++MAXSESSIONS=10 ++CONNECTIONS=20 ++EXPECTED_DROPS=$((CONNECTIONS - MAXSESSIONS)) ++ ++EXPECTED_STR='too many tcp sessions - dropping incoming request' ++wait_too_many_sessions() ++{ ++ test "$(grep "$EXPECTED_STR" "$RSYSLOG_OUT_LOG" | wc -l)" = "$EXPECTED_DROPS" ++} ++ ++export QUEUE_EMPTY_CHECK_FUNC=wait_too_many_sessions ++generate_conf ++add_conf ' ++$MaxMessageSize 10k ++ ++module(load="../plugins/imptcp/.libs/imptcp" maxsessions="'$MAXSESSIONS'") ++input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") ++action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ++ ++$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" ++$OMFileFlushInterval 2 ++$OMFileIOBufferSize 256k ++' ++startup ++ ++echo "INFO: RSYSLOG_OUT_LOG: $RSYSLOG_OUT_LOG" ++ ++echo "About to run tcpflood" ++tcpflood -c$CONNECTIONS -m$NUMMESSAGES -r -d100 -P129 ++echo "done run tcpflood" ++shutdown_when_empty ++wait_shutdown ++ ++content_count_check "$EXPECTED_STR" $EXPECTED_DROPS ++echo "Got expected drops: $EXPECTED_DROPS, looks good!" ++ ++exit_test +-- +2.23.0 + diff --git a/backport-Do-not-create-empty-objects-when-accessing-non-exist.patch b/backport-Do-not-create-empty-objects-when-accessing-non-exist.patch new file mode 100644 index 0000000..5635b71 --- /dev/null +++ b/backport-Do-not-create-empty-objects-when-accessing-non-exist.patch @@ -0,0 +1,75 @@ +From 1a1117c7359d1c9fc687fefdd56455f94f7fee10 Mon Sep 17 00:00:00 2001 +From: Julien Thomas +Date: Wed, 23 Sep 2020 20:33:55 +0200 +Subject: [PATCH 63/73] Do not create empty objects when accessing non-existent + keys + +This is a proposal for Github issue rsyslog/rsyslog#4430: +accessing a non-existing key creates an empty parent object +https://github.com/rsyslog/rsyslog/issues/4430 + +When looking up an object property, the tree of intermediate +object containers was ceated by get and del functions. The +patch is an attempt to fix that behavior by passing 0 to the +bCreate argument of jsonPathFindParent(). + +There is also one case where the return value of +jsonPathFindParent() was not checked, in the recurssive call +of jsonPathFindParent() itself. This was leading to infinite +loops if bCreate was 0. +--- + runtime/msg.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/runtime/msg.c b/runtime/msg.c +index 3acc4f212..b28cf84c5 100644 +--- a/runtime/msg.c ++++ b/runtime/msg.c +@@ -3142,7 +3142,7 @@ getJSONPropVal(smsg_t * const pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size + field = *jroot; + } else { + leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); +- CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 1)); ++ CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); + if(jsonVarExtract(parent, (char*)leaf, &field) == FALSE) + field = NULL; + } +@@ -3197,7 +3197,7 @@ msgGetJSONPropJSONorString(smsg_t * const pMsg, msgPropDescr_t *pProp, struct js + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } + leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); +- CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 1)); ++ CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); + if(jsonVarExtract(parent, (char*)leaf, pjson) == FALSE) { + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } +@@ -3242,7 +3242,7 @@ msgGetJSONPropJSON(smsg_t * const pMsg, msgPropDescr_t *pProp, struct json_objec + FINALIZE; + } + leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); +- CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 1)); ++ CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); + if(jsonVarExtract(parent, (char*)leaf, pjson) == FALSE) { + ABORT_FINALIZE(RS_RET_NOT_FOUND); + } +@@ -4845,7 +4845,7 @@ jsonPathFindParent(struct json_object *jroot, uchar *name, uchar *leaf, struct j + namestart = name; + *parent = jroot; + while(name < leaf-1) { +- jsonPathFindNext(*parent, namestart, &name, leaf, parent, bCreate); ++ CHKiRet(jsonPathFindNext(*parent, namestart, &name, leaf, parent, bCreate)); + } + if(*parent == NULL) + ABORT_FINALIZE(RS_RET_NOT_FOUND); +@@ -5006,7 +5006,7 @@ msgDelJSON(smsg_t * const pM, uchar *name) + *jroot = NULL; + } else { + leaf = jsonPathGetLeaf(name, ustrlen(name)); +- CHKiRet(jsonPathFindParent(*jroot, name, leaf, &parent, 1)); ++ CHKiRet(jsonPathFindParent(*jroot, name, leaf, &parent, 0)); + if(jsonVarExtract(parent, (char*)leaf, &leafnode) == FALSE) + leafnode = NULL; + if(leafnode == NULL) { +-- +2.23.0 + diff --git a/backport-FIX-IMUDP-add-missing-free-during-freeCnf.patch b/backport-FIX-IMUDP-add-missing-free-during-freeCnf.patch new file mode 100644 index 0000000..c3c4e23 --- /dev/null +++ b/backport-FIX-IMUDP-add-missing-free-during-freeCnf.patch @@ -0,0 +1,24 @@ +From 9df01d03027468d707320d48bd4c0724eaac6aa4 Mon Sep 17 00:00:00 2001 +From: frikilax +Date: Thu, 25 Jun 2020 15:56:06 +0200 +Subject: [PATCH 03/73] FIX::IMUDP: add missing free during freeCnf() + +--- + plugins/imudp/imudp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c +index bb6414d4d..4b49e9f12 100644 +--- a/plugins/imudp/imudp.c ++++ b/plugins/imudp/imudp.c +@@ -1195,6 +1195,7 @@ CODESTARTfreeCnf + free(inst->pszBindPort); + free(inst->pszBindAddr); + free(inst->pszBindDevice); ++ free(inst->pszBindRuleset); + free(inst->inputname); + free(inst->dfltTZ); + del = inst; +-- +2.23.0 + diff --git a/backport-Replace-GNUTLS_SHUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch b/backport-Replace-GNUTLS_SHUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch new file mode 100644 index 0000000..eb4f5e4 --- /dev/null +++ b/backport-Replace-GNUTLS_SHUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch @@ -0,0 +1,44 @@ +From 405457374661a81893cc3d9ad041e51ec996a7d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Fri, 18 Sep 2020 15:46:25 +0200 +Subject: [PATCH 59/73] Replace GNUTLS_SHUT_RDWR by GNUTLS_SHUT_WR when ending + TLS connections + +Some TLS servers don't reply to graceful shutdown requests "for +optimization". This results in rsyslog's omfwd+gtls client to wait +forever for a reply of the TLS server which never comes, due to shutting +down the connection with gnutls_bye(GNUTLS_SHUT_RDWR). + +On systemd systems, commands such as "systemctl restart rsyslog" just +hang for 1m30 and rsyslogd gets killed upon timeout by systemd. + +This patch replaces call to gnutls_bye(GNUTLS_SHUT_RDWR) by calls to +gnutls_bye(GNUTLS_SHUT_WR) which is sufficient and doesn't wait for a +server reply. + +A Red Hat customer reproduces the hang reliably when sending the logs to +his Kiwi Syslog server, which apparently doesn't send the TLS reply upon +connection termination request. +--- + runtime/nsd_gtls.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c +index ac2d9a41a..1cf73dadc 100644 +--- a/runtime/nsd_gtls.c ++++ b/runtime/nsd_gtls.c +@@ -1321,9 +1321,9 @@ gtlsEndSess(nsd_gtls_t *pThis) + + if(pThis->bHaveSess) { + if(pThis->bIsInitiator) { +- gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR); ++ gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_WR); + while(gnuRet == GNUTLS_E_INTERRUPTED || gnuRet == GNUTLS_E_AGAIN) { +- gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR); ++ gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_WR); + } + } + gnutls_deinit(pThis->sess); +-- +2.23.0 + diff --git a/backport-Replaced-eCmdHdlrPositiveInt-with-eCmdHdlrNonNegInt-.patch b/backport-Replaced-eCmdHdlrPositiveInt-with-eCmdHdlrNonNegInt-.patch new file mode 100644 index 0000000..097ae59 --- /dev/null +++ b/backport-Replaced-eCmdHdlrPositiveInt-with-eCmdHdlrNonNegInt-.patch @@ -0,0 +1,133 @@ +From 2e3b767d03f7ee9534a4d93c013a6bc35437ca13 Mon Sep 17 00:00:00 2001 +From: Aaron Levy +Date: Sat, 12 Sep 2020 17:29:44 -0700 +Subject: [PATCH 57/73] Replaced eCmdHdlrPositiveInt with eCmdHdlrNonNegInt + where default is 0 + +--- + contrib/mmdarwin/mmdarwin.c | 2 +- + contrib/omrabbitmq/omrabbitmq.c | 2 +- + plugins/imfile/imfile.c | 6 +++--- + plugins/imtcp/imtcp.c | 6 +++--- + runtime/glbl.c | 2 +- + tests/omrabbitmq_params_invalid3.sh | 4 ++-- + tools/omfwd.c | 6 +++--- + 7 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/contrib/mmdarwin/mmdarwin.c b/contrib/mmdarwin/mmdarwin.c +index ea6f4c3ee..e36dbde2c 100644 +--- a/contrib/mmdarwin/mmdarwin.c ++++ b/contrib/mmdarwin/mmdarwin.c +@@ -124,7 +124,7 @@ static struct cnfparamdescr actpdescr[] = { + {"filtercode", eCmdHdlrGetWord, 0}, /* optional parameter */ + {"response", eCmdHdlrGetWord, 0}, /* optional parameter */ + {"send_partial", eCmdHdlrBinary, 0}, /* optional parameter */ +- {"socket_max_use", eCmdHdlrPositiveInt, 0}, /* optional parameter - will disappear in future updates */ ++ {"socket_max_use", eCmdHdlrNonNegInt, 0}, /* optional parameter - will disappear in future updates */ + }; + static struct cnfparamblk actpblk = { + CNFPARAMBLK_VERSION, +diff --git a/contrib/omrabbitmq/omrabbitmq.c b/contrib/omrabbitmq/omrabbitmq.c +index 12b1ea18e..4d7696459 100644 +--- a/contrib/omrabbitmq/omrabbitmq.c ++++ b/contrib/omrabbitmq/omrabbitmq.c +@@ -179,7 +179,7 @@ static struct cnfparamdescr actpdescr[] = { + { "routing_key", eCmdHdlrGetWord, 0 }, + { "routing_key_template", eCmdHdlrGetWord, 0 }, + { "delivery_mode", eCmdHdlrGetWord, 0 }, +- { "expiration", eCmdHdlrPositiveInt, 0 }, ++ { "expiration", eCmdHdlrNonNegInt, 0 }, + { "populate_properties", eCmdHdlrBinary, 0 }, + { "body_template", eCmdHdlrGetWord, 0 }, + { "content_type", eCmdHdlrGetWord, 0 }, +diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c +index 21d654655..db161cc49 100644 +--- a/plugins/imfile/imfile.c ++++ b/plugins/imfile/imfile.c +@@ -300,7 +300,7 @@ static prop_t *pInputName = NULL; + /* module-global parameters */ + static struct cnfparamdescr modpdescr[] = { + { "pollinginterval", eCmdHdlrPositiveInt, 0 }, +- { "readtimeout", eCmdHdlrPositiveInt, 0 }, ++ { "readtimeout", eCmdHdlrNonNegInt, 0 }, + { "timeoutgranularity", eCmdHdlrPositiveInt, 0 }, + { "sortfiles", eCmdHdlrBinary, 0 }, + { "statefile.directory", eCmdHdlrString, 0 }, +@@ -335,11 +335,11 @@ static struct cnfparamdescr inppdescr[] = { + { "persiststateinterval", eCmdHdlrInt, 0 }, + { "persiststateaftersubmission", eCmdHdlrBinary, 0 }, + { "deletestateonfiledelete", eCmdHdlrBinary, 0 }, +- { "delay.message", eCmdHdlrPositiveInt, 0 }, ++ { "delay.message", eCmdHdlrNonNegInt, 0 }, + { "addmetadata", eCmdHdlrBinary, 0 }, + { "addceetag", eCmdHdlrBinary, 0 }, + { "statefile", eCmdHdlrString, CNFPARAM_DEPRECATED }, +- { "readtimeout", eCmdHdlrPositiveInt, 0 }, ++ { "readtimeout", eCmdHdlrNonNegInt, 0 }, + { "freshstarttail", eCmdHdlrBinary, 0}, + { "filenotfounderror", eCmdHdlrBinary, 0}, + { "needparse", eCmdHdlrBinary, 0}, +diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c +index a1955d979..f1478dc15 100644 +--- a/plugins/imtcp/imtcp.c ++++ b/plugins/imtcp/imtcp.c +@@ -180,9 +180,9 @@ static struct cnfparamdescr modpdescr[] = { + { "streamdriver.TlsVerifyDepth", eCmdHdlrPositiveInt, 0 }, + { "permittedpeer", eCmdHdlrArray, 0 }, + { "keepalive", eCmdHdlrBinary, 0 }, +- { "keepalive.probes", eCmdHdlrPositiveInt, 0 }, +- { "keepalive.time", eCmdHdlrPositiveInt, 0 }, +- { "keepalive.interval", eCmdHdlrPositiveInt, 0 }, ++ { "keepalive.probes", eCmdHdlrNonNegInt, 0 }, ++ { "keepalive.time", eCmdHdlrNonNegInt, 0 }, ++ { "keepalive.interval", eCmdHdlrNonNegInt, 0 }, + { "gnutlsprioritystring", eCmdHdlrString, 0 }, + { "preservecase", eCmdHdlrBinary, 0 } + }; +diff --git a/runtime/glbl.c b/runtime/glbl.c +index ce390da4e..714f6226d 100644 +--- a/runtime/glbl.c ++++ b/runtime/glbl.c +@@ -170,7 +170,7 @@ static struct cnfparamdescr cnfparamdescr[] = { + { "preservefqdn", eCmdHdlrBinary, 0 }, + { "debug.onshutdown", eCmdHdlrBinary, 0 }, + { "debug.logfile", eCmdHdlrString, 0 }, +- { "debug.gnutls", eCmdHdlrPositiveInt, 0 }, ++ { "debug.gnutls", eCmdHdlrNonNegInt, 0 }, + { "debug.unloadmodules", eCmdHdlrBinary, 0 }, + { "defaultnetstreamdrivercafile", eCmdHdlrString, 0 }, + { "defaultnetstreamdriverkeyfile", eCmdHdlrString, 0 }, +diff --git a/tests/omrabbitmq_params_invalid3.sh b/tests/omrabbitmq_params_invalid3.sh +index 991cb3bee..4274dd9d2 100755 +--- a/tests/omrabbitmq_params_invalid3.sh ++++ b/tests/omrabbitmq_params_invalid3.sh +@@ -11,6 +11,6 @@ action(type="omfile" file="'$RSYSLOG_OUT_LOG'") + startup + shutdown_when_empty + wait_shutdown +-content_check "parameter 'expiration' cannot be less than one" ++content_check "parameter 'expiration' cannot be less than zero" + +-exit_test +\ No newline at end of file ++exit_test +diff --git a/tools/omfwd.c b/tools/omfwd.c +index 74d0c8bed..1304f43f3 100644 +--- a/tools/omfwd.c ++++ b/tools/omfwd.c +@@ -184,9 +184,9 @@ static struct cnfparamdescr actpdescr[] = { + { "maxerrormessages", eCmdHdlrInt, CNFPARAM_DEPRECATED }, + { "rebindinterval", eCmdHdlrInt, 0 }, + { "keepalive", eCmdHdlrBinary, 0 }, +- { "keepalive.probes", eCmdHdlrPositiveInt, 0 }, +- { "keepalive.time", eCmdHdlrPositiveInt, 0 }, +- { "keepalive.interval", eCmdHdlrPositiveInt, 0 }, ++ { "keepalive.probes", eCmdHdlrNonNegInt, 0 }, ++ { "keepalive.time", eCmdHdlrNonNegInt, 0 }, ++ { "keepalive.interval", eCmdHdlrNonNegInt, 0 }, + { "gnutlsprioritystring", eCmdHdlrString, 0 }, + { "streamdriver", eCmdHdlrGetWord, 0 }, + { "streamdrivermode", eCmdHdlrInt, 0 }, +-- +2.23.0 + diff --git a/backport-config-bugfix-intended-warning-emitted-as-error.patch b/backport-config-bugfix-intended-warning-emitted-as-error.patch new file mode 100644 index 0000000..57a8a9d --- /dev/null +++ b/backport-config-bugfix-intended-warning-emitted-as-error.patch @@ -0,0 +1,30 @@ +From 24816cd9ddefacd60aa9d7023a71bb24314c5957 Mon Sep 17 00:00:00 2001 +From: Rainer Gerhards +Date: Wed, 26 Aug 2020 13:17:16 +0200 +Subject: [PATCH 37/73] config bugfix: intended warning emitted as error + +When there are actions configured after a STOP, a warning should be +emitted. In fact, an error message is generated. This prevents the +construct, which may have some legit uses in exotic settings. It +may also break older configs, but as the message is an error +for so long now, this should be no longer of concern. +--- + grammar/rainerscript.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c +index 2157451a0..34f4804f1 100644 +--- a/grammar/rainerscript.c ++++ b/grammar/rainerscript.c +@@ -5041,7 +5041,7 @@ cnfstmtOptimize(struct cnfstmt *root) + break; + case S_STOP: + if(stmt->next != NULL) +- parser_errmsg("STOP is followed by unreachable statements!\n"); ++ parser_warnmsg("STOP is followed by unreachable statements!\n"); + break; + case S_UNSET: /* nothing to do */ + break; +-- +2.23.0 + diff --git a/backport-core-bugfix-potential-segfault-on-querey-of-PROGRAMN.patch b/backport-core-bugfix-potential-segfault-on-querey-of-PROGRAMN.patch new file mode 100644 index 0000000..2c4c831 --- /dev/null +++ b/backport-core-bugfix-potential-segfault-on-querey-of-PROGRAMN.patch @@ -0,0 +1,57 @@ +From 6cffa83af3ca1368ab406324fb01d5e1c32af902 Mon Sep 17 00:00:00 2001 +From: Rainer Gerhards +Date: Fri, 11 Sep 2020 13:14:50 +0200 +Subject: [PATCH] core bugfix: potential segfault on querey of PROGRAMNAME + property + +A data race can happen on variable iLenProgram as it is not guarded +by the message mutex at time of query. This can lead to it being +non -1 while the buffer has not yet properly set up. + +Thanks to github user wsp1991 for alerting us and a related +patch proposal. + +replaces https://github.com/rsyslog/rsyslog/pull/4300 +--- + runtime/msg.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/runtime/msg.c b/runtime/msg.c +index 6468a0d55..3acc4f212 100644 +--- a/runtime/msg.c ++++ b/runtime/msg.c +@@ -2619,22 +2619,21 @@ MsgGetStructuredData(smsg_t * const pM, uchar **pBuf, rs_size_t *len) + uchar * ATTR_NONNULL(1) + getProgramName(smsg_t *const pM, const sbool bLockMutex) + { ++ if(bLockMutex == LOCK_MUTEX) { ++ MsgLock(pM); ++ } ++ + if(pM->iLenPROGNAME == -1) { + if(pM->iLenTAG == 0) { + uchar *pRes; + rs_size_t bufLen = -1; +- getTAG(pM, &pRes, &bufLen, bLockMutex); ++ getTAG(pM, &pRes, &bufLen, MUTEX_ALREADY_LOCKED); + } ++ aquireProgramName(pM); ++ } + +- if(bLockMutex == LOCK_MUTEX) { +- MsgLock(pM); +- /* need to re-check, things may have change in between! */ +- if(pM->iLenPROGNAME == -1) +- aquireProgramName(pM); +- MsgUnlock(pM); +- } else { +- aquireProgramName(pM); +- } ++ if(bLockMutex == LOCK_MUTEX) { ++ MsgUnlock(pM); + } + return (pM->iLenPROGNAME < CONF_PROGNAME_BUFSIZE) ? pM->PROGNAME.szBuf + : pM->PROGNAME.ptr; +-- +2.23.0 + diff --git a/backport-core-bugfix-segfault-if-disk-queue-file-cannot-be-cr.patch b/backport-core-bugfix-segfault-if-disk-queue-file-cannot-be-cr.patch new file mode 100644 index 0000000..c511fbb --- /dev/null +++ b/backport-core-bugfix-segfault-if-disk-queue-file-cannot-be-cr.patch @@ -0,0 +1,133 @@ +From 6763185783f78dc8947103f454a3ddb28c46d362 Mon Sep 17 00:00:00 2001 +From: Rainer Gerhards +Date: Wed, 26 Aug 2020 17:39:49 +0200 +Subject: [PATCH 43/73] core bugfix: segfault if disk-queue file cannot be + created + +When using Disk Queue and a queue.filename that can not be created +by rsyslog, the service does not switch to another queue type as +supposed to and crashes at a later step. + +closes: https://github.com/rsyslog/rsyslog/issues/4282 +--- + runtime/stream.c | 1 + + tests/Makefile.am | 2 ++ + tests/diag.sh | 2 +- + tests/diskqueue-fail.sh | 35 +++++++++++++++++++++++++++++++++++ + tools/rsyslogd.c | 9 +++++++-- + 5 files changed, 46 insertions(+), 3 deletions(-) + create mode 100755 tests/diskqueue-fail.sh + +diff --git a/runtime/stream.c b/runtime/stream.c +index 044a097ef..abe4ffb4b 100644 +--- a/runtime/stream.c ++++ b/runtime/stream.c +@@ -2079,6 +2079,7 @@ static rsRetVal strmWriteChar(strm_t *__restrict__ const pThis, const uchar c) + if(pThis->iBufPtr == pThis->sIOBufSize) { + CHKiRet(strmFlushInternal(pThis, 0)); + } ++ + /* we now always have space for one character, so we simply copy it */ + *(pThis->pIOBuf + pThis->iBufPtr) = c; + pThis->iBufPtr++; +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 0df67672c..3b296a106 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -289,6 +289,7 @@ TESTS += \ + diskqueue.sh \ + diskqueue-fsync.sh \ + diskqueue-full.sh \ ++ diskqueue-fail.sh \ + diskqueue-non-unique-prefix.sh \ + rulesetmultiqueue.sh \ + rulesetmultiqueue-v6.sh \ +@@ -1644,6 +1645,7 @@ EXTRA_DIST= \ + diskq-rfc5424.sh \ + rfc5424parser-sp_at_msg_start.sh \ + diskqueue-full.sh \ ++ diskqueue-fail.sh \ + diskqueue.sh \ + diskqueue-non-unique-prefix.sh \ + arrayqueue.sh \ +diff --git a/tests/diag.sh b/tests/diag.sh +index bc0e408ce..de12d05da 100755 +--- a/tests/diag.sh ++++ b/tests/diag.sh +@@ -710,7 +710,7 @@ content_count_check() { + grep_opt=-F + fi + file=${3:-$RSYSLOG_OUT_LOG} +- count=$(grep -c -F -- "$1" <${RSYSLOG_OUT_LOG}) ++ count=$(grep -c $grep_opt -- "$1" <${RSYSLOG_OUT_LOG}) + if [ ${count:=0} -ne "$2" ]; then + grep -c -F -- "$1" <${RSYSLOG_OUT_LOG} + printf '\n============================================================\n' +diff --git a/tests/diskqueue-fail.sh b/tests/diskqueue-fail.sh +new file mode 100755 +index 000000000..a8c63b26b +--- /dev/null ++++ b/tests/diskqueue-fail.sh +@@ -0,0 +1,35 @@ ++#!/bin/bash ++# checks that nothing bad happens if a DA (disk) queue runs out ++# of configured disk space ++# addd 2017-02-07 by RGerhards, released under ASL 2.0 ++. ${srcdir:=.}/diag.sh init ++export NUMMESSAGES=100 ++generate_conf ++add_conf ' ++module( load="../plugins/imtcp/.libs/imtcp") ++input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="queuefail") ++ ++template(name="outfmt" type="string" ++ string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") ++ ++ruleset( ++ name="queuefail" ++ queue.type="Disk" ++ queue.filename="fssailstocreate" ++ queue.maxDiskSpace="4m" ++ queue.maxfilesize="1m" ++ queue.timeoutenqueue="300000" ++ queue.lowwatermark="5000" ++) { ++ action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ++} ++' ++startup ++ ++tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES ++ ++shutdown_when_empty ++wait_shutdown ++seq_check ++ ++exit_test +diff --git a/tools/rsyslogd.c b/tools/rsyslogd.c +index d2e4833eb..d752bf7ad 100644 +--- a/tools/rsyslogd.c ++++ b/tools/rsyslogd.c +@@ -808,12 +808,17 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst * + } + + rsRetVal +-startMainQueue(qqueue_t *pQueue) ++startMainQueue(qqueue_t *const pQueue) + { + DEFiRet; + CHKiRet_Hdlr(qqueueStart(pQueue)) { + /* no queue is fatal, we need to give up in that case... */ +- LogError(0, iRet, "could not start (ruleset) main message queue"); \ ++ LogError(0, iRet, "could not start (ruleset) main message queue"); ++ pQueue->qType = QUEUETYPE_DIRECT; ++ CHKiRet_Hdlr(qqueueStart(pQueue)) { ++ /* no queue is fatal, we need to give up in that case... */ ++ LogError(0, iRet, "fatal error: could not even start queue in direct mode"); ++ } + } + RETiRet; + } +-- +2.23.0 + diff --git a/backport-core-network-obey-net.enableDNS-off-when-querying-lo.patch b/backport-core-network-obey-net.enableDNS-off-when-querying-lo.patch new file mode 100644 index 0000000..1d70df5 --- /dev/null +++ b/backport-core-network-obey-net.enableDNS-off-when-querying-lo.patch @@ -0,0 +1,26 @@ +From de0750c6c28b76be9573bc08386bc2fad54b80a1 Mon Sep 17 00:00:00 2001 +From: Kalle Kankare +Date: Mon, 11 Nov 2019 10:01:36 +0200 +Subject: [PATCH 60/73] core/network: obey net.enableDNS=off when querying + local hostname + +--- + runtime/net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/runtime/net.c b/runtime/net.c +index e503810c5..d98395a77 100644 +--- a/runtime/net.c ++++ b/runtime/net.c +@@ -1186,7 +1186,7 @@ getLocalHostname(uchar **ppName) + + char *dot = strstr(hnbuf, "."); + struct addrinfo *res = NULL; +- if(!empty_hostname && dot == NULL) { ++ if(!empty_hostname && dot == NULL && !glbl.GetDisableDNS()) { + /* we need to (try) to find the real name via resolver */ + struct addrinfo flags; + memset(&flags, 0, sizeof(flags)); +-- +2.23.0 + diff --git a/backport-gnutls-Added-handshake-error-handling-into-doRetry-h.patch b/backport-gnutls-Added-handshake-error-handling-into-doRetry-h.patch new file mode 100644 index 0000000..d432699 --- /dev/null +++ b/backport-gnutls-Added-handshake-error-handling-into-doRetry-h.patch @@ -0,0 +1,47 @@ +From 1cf08f0a268eacc345b6cc48921ee25748ded175 Mon Sep 17 00:00:00 2001 +From: Andre lorbach +Date: Tue, 6 Oct 2020 14:24:51 +0200 +Subject: [PATCH 68/73] gnutls: Added handshake error handling into doRetry + handler. + +If the tls handshake does not immediatelly finish, gnutls_handShake is called in +doRetry handler again. However the error handling was not +complete in the doRetry handler. A failed gnutls_handShake call +did not abort the connection and properly caused unexpected +problems like in issues: + +https://github.com/rsyslog/rsyslog/issues/4270 +https://github.com/rsyslog/rsyslog/issues/4288 +--- + runtime/nsdsel_gtls.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c +index 195431514..6ed7187e5 100644 +--- a/runtime/nsdsel_gtls.c ++++ b/runtime/nsdsel_gtls.c +@@ -150,10 +150,20 @@ doRetry(nsd_gtls_t *pNsd) + switch(pNsd->rtryCall) { + case gtlsRtry_handshake: + gnuRet = gnutls_handshake(pNsd->sess); +- if(gnuRet == 0) { ++ if(gnuRet == GNUTLS_E_AGAIN || gnuRet == GNUTLS_E_INTERRUPTED) { ++ dbgprintf("GnuTLS handshake retry did not finish - " ++ "setting to retry (this is OK and can happen)\n"); ++ FINALIZE; ++ } else if(gnuRet == 0) { + pNsd->rtryCall = gtlsRtry_None; /* we are done */ + /* we got a handshake, now check authorization */ + CHKiRet(gtlsChkPeerAuth(pNsd)); ++ } else { ++ uchar *pGnuErr = gtlsStrerror(gnuRet); ++ LogError(0, RS_RET_TLS_HANDSHAKE_ERR, ++ "GnuTLS handshake retry returned error: %s\n", pGnuErr); ++ free(pGnuErr); ++ ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR); + } + break; + case gtlsRtry_recv: +-- +2.23.0 + diff --git a/backport-gnutls-Propagate-CheckExtendedKeyPurpose-when-accept.patch b/backport-gnutls-Propagate-CheckExtendedKeyPurpose-when-accept.patch new file mode 100644 index 0000000..b67177c --- /dev/null +++ b/backport-gnutls-Propagate-CheckExtendedKeyPurpose-when-accept.patch @@ -0,0 +1,29 @@ +From 37a19fb8997b9b61a7d75852e37110330a07c0d2 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 10 Aug 2020 16:37:43 +0200 +Subject: [PATCH 17/73] gnutls: Propagate CheckExtendedKeyPurpose when + accepting connection + +Previously, when the server accepts a new connection, it doesn't +properly set the dataTypeCheck field based on the listening socket. +That results in skipping ExtendedKeyUsage (EKU) check on the client +certificates. +--- + runtime/nsd_gtls.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c +index 2eed4246d..ac2d9a41a 100644 +--- a/runtime/nsd_gtls.c ++++ b/runtime/nsd_gtls.c +@@ -1788,6 +1788,7 @@ AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew) + pNew->pPermPeers = pThis->pPermPeers; + pNew->gnutlsPriorityString = pThis->gnutlsPriorityString; + pNew->DrvrVerifyDepth = pThis->DrvrVerifyDepth; ++ pNew->dataTypeCheck = pThis->dataTypeCheck; + + /* if we reach this point, we are in TLS mode */ + iRet = gtlsInitSession(pNew); +-- +2.23.0 + diff --git a/backport-imtcp-bugfix-broken-connection-not-necessariy-detect.patch b/backport-imtcp-bugfix-broken-connection-not-necessariy-detect.patch new file mode 100644 index 0000000..c649a25 --- /dev/null +++ b/backport-imtcp-bugfix-broken-connection-not-necessariy-detect.patch @@ -0,0 +1,30 @@ +From 29afbafcd5950ed31a3831f9f4fbe1649a0ea49b Mon Sep 17 00:00:00 2001 +From: Leo Fang +Date: Wed, 27 May 2020 10:45:29 +0800 +Subject: [PATCH] imtcp bugfix: broken connection not necessariy detected + +Due to an invalid return code check, broken TCP sessions could not +necessarily be detected "right in time". This can result is the loss +of one message. + +closes https://github.com/rsyslog/rsyslog/issues/4227 +--- + runtime/nsd_ptcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c +index de3ab38f9..2b56efdb8 100644 +--- a/runtime/nsd_ptcp.c ++++ b/runtime/nsd_ptcp.c +@@ -952,7 +952,7 @@ CheckConnection(nsd_t *pNsd) + ISOBJ_TYPE_assert(pThis, nsd_ptcp); + + rc = recv(pThis->sock, msgbuf, 1, MSG_DONTWAIT | MSG_PEEK); +- if(rc == 0 && errno != EAGAIN) { ++ if(rc == 0) { + dbgprintf("CheckConnection detected broken connection - closing it (rc %d, errno %d)\n", rc, errno); + /* in this case, the remote peer had shut down the connection and we + * need to close our side, too. +-- +2.23.0 + diff --git a/backport-msg-memory-leak-in-msgAddJSON-if-jsonPathFindParent-.patch b/backport-msg-memory-leak-in-msgAddJSON-if-jsonPathFindParent-.patch new file mode 100644 index 0000000..ec521cf --- /dev/null +++ b/backport-msg-memory-leak-in-msgAddJSON-if-jsonPathFindParent-.patch @@ -0,0 +1,32 @@ +From c54d3d5e8cb45f2ad1b0166524f6407172df80c8 Mon Sep 17 00:00:00 2001 +From: Julien Thomas +Date: Fri, 9 Oct 2020 21:21:10 +0200 +Subject: [PATCH 70/73] msg: memory leak in msgAddJSON() if + jsonPathFindParent() failed + +There is a missing call to json_object_put(json) if the call to +jsonPathFindParent() failed. It's leaking memory. +--- + runtime/msg.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/runtime/msg.c b/runtime/msg.c +index 8e86d2944..0dc86c0ed 100644 +--- a/runtime/msg.c ++++ b/runtime/msg.c +@@ -4966,7 +4966,11 @@ msgAddJSON(smsg_t * const pM, uchar *name, struct json_object *json, int force_r + *jroot = json_object_new_object(); + } + leaf = jsonPathGetLeaf(name, ustrlen(name)); +- CHKiRet(jsonPathFindParent(*jroot, name, leaf, &parent, 1)); ++ iRet = jsonPathFindParent(*jroot, name, leaf, &parent, 1); ++ if (unlikely(iRet != RS_RET_OK)) { ++ json_object_put(json); ++ FINALIZE; ++ } + if (json_object_get_type(parent) != json_type_object) { + DBGPRINTF("msgAddJSON: not a container in json path," + "name is '%s'\n", name); +-- +2.23.0 + diff --git a/backport-msg-segfault-in-jsonPathFindNext-when-root-is-not-an.patch b/backport-msg-segfault-in-jsonPathFindNext-when-root-is-not-an.patch new file mode 100644 index 0000000..0680ad7 --- /dev/null +++ b/backport-msg-segfault-in-jsonPathFindNext-when-root-is-not-an.patch @@ -0,0 +1,40 @@ +From e5dc93e076f0c9ba9458b3c634bbf2b5d53201e2 Mon Sep 17 00:00:00 2001 +From: Julien Thomas +Date: Fri, 9 Oct 2020 21:18:01 +0200 +Subject: [PATCH 69/73] msg: segfault in jsonPathFindNext() when is not + an object + +The segfault gets happens when is 1 and when the +container where to insert the key is not an object. + +Here is simple reproducible test case: + +// ensure we start fresh +// unnecessary if there was no previous set +unset $!; + +set $! = ""; +set $!event!created = 123; +--- + runtime/msg.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/runtime/msg.c b/runtime/msg.c +index ebb9fdd6d..8e86d2944 100644 +--- a/runtime/msg.c ++++ b/runtime/msg.c +@@ -4826,6 +4826,11 @@ jsonPathFindNext(struct json_object *root, uchar *namestart, uchar **name, uchar + if(!bCreate) { + ABORT_FINALIZE(RS_RET_JNAME_INVALID); + } else { ++ if (json_object_get_type(root) != json_type_object) { ++ DBGPRINTF("jsonPathFindNext with bCreate: not a container in json path, " ++ "name is '%s'\n", namestart); ++ ABORT_FINALIZE(RS_RET_INVLD_SETOP); ++ } + json = json_object_new_object(); + json_object_object_add(root, (char*)namebuf, json); + } +-- +2.23.0 + diff --git a/backport-omelasticsearch-Fix-reply-buffer-reset-after-health-.patch b/backport-omelasticsearch-Fix-reply-buffer-reset-after-health-.patch new file mode 100644 index 0000000..ab452e0 --- /dev/null +++ b/backport-omelasticsearch-Fix-reply-buffer-reset-after-health-.patch @@ -0,0 +1,42 @@ +From 694c0cc1068a78f9aee80a69eccc98d1cde06c88 Mon Sep 17 00:00:00 2001 +From: Julien Thomas +Date: Mon, 20 Jul 2020 11:21:49 +0200 +Subject: [PATCH 26/73] omelasticsearch: Fix reply buffer reset after health + check + +This is a proposal to fix github issue #4127 "omelasticsearch +failure parsing elasticsearch reply in 8.2001.0". + +The issue happens when more than one server is defined on the +action. On that condition a health check is made through +checkConn() before sending the POST. The replyLen should be +set back to 0 after the health check, otherwise the response +data received from the POST gets appended to the end of the +last health check. +--- + plugins/omelasticsearch/omelasticsearch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c +index 5590a49e2..8fcf92c3f 100644 +--- a/plugins/omelasticsearch/omelasticsearch.c ++++ b/plugins/omelasticsearch/omelasticsearch.c +@@ -1567,7 +1567,6 @@ curlPost(wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls + + PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); + +- pWrkrData->replyLen = 0; + if ((pWrkrData->pData->rebindInterval > -1) && + (pWrkrData->nOperations > pWrkrData->pData->rebindInterval)) { + curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1); +@@ -1588,6 +1587,7 @@ curlPost(wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls + /* needs to be called to support ES HA feature */ + CHKiRet(checkConn(pWrkrData)); + } ++ pWrkrData->replyLen = 0; + CHKiRet(setPostURL(pWrkrData, tpls)); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char *)message); +-- +2.23.0 + diff --git a/backport-testbench-set-msg-size-to-64kb-for-sndrcv_omudpspoof.patch b/backport-testbench-set-msg-size-to-64kb-for-sndrcv_omudpspoof.patch new file mode 100644 index 0000000..a10c338 --- /dev/null +++ b/backport-testbench-set-msg-size-to-64kb-for-sndrcv_omudpspoof.patch @@ -0,0 +1,26 @@ +From 4e5741807e7d237ecfac647bd530fd5e5c970e5d Mon Sep 17 00:00:00 2001 +From: Andre lorbach +Date: Mon, 20 Jul 2020 08:35:57 +0200 +Subject: [PATCH] testbench: set msg size to 64kb for + sndrcv_omudpspoof-bigmsg.sh test + +--- + tests/sndrcv_omudpspoof-bigmsg.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/sndrcv_omudpspoof-bigmsg.sh b/tests/sndrcv_omudpspoof-bigmsg.sh +index ee11b0a..6d61793 100755 +--- a/tests/sndrcv_omudpspoof-bigmsg.sh ++++ b/tests/sndrcv_omudpspoof-bigmsg.sh +@@ -8,7 +8,7 @@ if [ "$EUID" -ne 0 ]; then + fi + export TCPFLOOD_EXTRA_OPTS="-b1 -W1" + export NUMMESSAGES=1 +-export MESSAGESIZE=16384 #65000 #32768 #16384 ++export MESSAGESIZE=65000 #65000 #32768 #16384 + #export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" + #export RSYSLOG_DEBUGLOG="log" + +-- +1.8.3.1 + diff --git a/openEuler-print-main-queue-info-to-journal-when-queue-full.patch b/openEuler-print-main-queue-info-to-journal-when-queue-full.patch new file mode 100644 index 0000000..2978b8f --- /dev/null +++ b/openEuler-print-main-queue-info-to-journal-when-queue-full.patch @@ -0,0 +1,80 @@ +From 27ee1b988a465e5f89e8a9234f4a01c34cab4387 Mon Sep 17 00:00:00 2001 +From: wangshouping +Date: Mon, 27 Apr 2020 08:53:18 -0400 +Subject: [PATCH] print main queue info to journal when queue full + +Signed-off-by: wangshouping +--- + runtime/queue.c | 27 +++++++++++++++++++++++++++ + 1 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/runtime/queue.c b/runtime/queue.c +index e988e44..9faf5aa 100644 +--- a/runtime/queue.c ++++ b/runtime/queue.c +@@ -47,6 +47,7 @@ + #include + #include + #include ++#include + + #include "rsyslog.h" + #include "queue.h" +@@ -116,6 +117,14 @@ rsRetVal qqueueSetSpoolDir(qqueue_t *pThis, uchar *pszSpoolDir, int lenSpoolDir) + /* some constants for queuePersist () */ + #define QUEUE_CHECKPOINT 1 + #define QUEUE_NO_CHECKPOINT 0 ++#define TIME_OUT 300 ++#define TIMEOUT_ENQUEUE_ZERO 1 ++#define TIMEOUT_ENQUEUE_NONZERO 2 ++ ++struct timespec g_lastTime = { ++ .tv_sec = 0, ++ .tv_nsec = 0, ++}; + + /* tables for interfacing with the v6 config system */ + static struct cnfparamdescr cnfpdescr[] = { +@@ -2985,6 +2992,24 @@ finalize_it: + RETiRet; + } + ++void PrintQueueFullLog(qqueue_t *pThis, int flag) ++{ ++ struct timespec timeNow; ++ ++ clock_gettime(CLOCK_MONOTONIC, &timeNow); ++ if (timeNow.tv_sec - g_lastTime.tv_sec > TIME_OUT) { ++ if (flag == TIMEOUT_ENQUEUE_ZERO) { ++ sd_journal_print(LOG_NOTICE, "doEnqSingleObject: queue FULL - configured for immediate " ++ "discarding QueueSize=%d MaxQueueSize=%d sizeOnDisk=%lld " ++ "sizeOnDiskMax=%lld\n", pThis->iQueueSize, pThis->iMaxQueueSize, ++ pThis->tVars.disk.sizeOnDisk, pThis->sizeOnDiskMax); ++ } else if (flag == TIMEOUT_ENQUEUE_NONZERO) { ++ sd_journal_print(LOG_NOTICE, "doEnqSingleObject: queue FULL, iQueueSize=%d MaxQueueSize=%d - waiting %dms to drain.\n", ++ pThis->iQueueSize, pThis->iMaxQueueSize, pThis->toEnq); ++ } ++ g_lastTime.tv_sec = timeNow.tv_sec; ++ } ++} + + /* enqueue a single data object. + * Note that the queue mutex MUST already be locked when this function is called. +@@ -3082,12 +3107,14 @@ doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, smsg_t *pMsg) + "discarding QueueSize=%d MaxQueueSize=%d sizeOnDisk=%lld " + "sizeOnDiskMax=%lld\n", pThis->iQueueSize, pThis->iMaxQueueSize, + pThis->tVars.disk.sizeOnDisk, pThis->sizeOnDiskMax); ++ PrintQueueFullLog(pThis, TIMEOUT_ENQUEUE_ZERO); + STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd); + msgDestruct(&pMsg); + ABORT_FINALIZE(RS_RET_QUEUE_FULL); + } else { + DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: queue FULL - waiting %dms to drain.\n", + pThis->toEnq); ++ PrintQueueFullLog(pThis, TIMEOUT_ENQUEUE_NONZERO); + if(glbl.GetGlobalInputTermState()) { + DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: queue FULL, discard due to " + "FORCE_TERM.\n"); +-- +2.19.1 + diff --git a/openEuler-print-main-queue-info-to-journal-when-receive-USR1-signal.patch b/openEuler-print-main-queue-info-to-journal-when-receive-USR1-signal.patch new file mode 100644 index 0000000..5f453ab --- /dev/null +++ b/openEuler-print-main-queue-info-to-journal-when-receive-USR1-signal.patch @@ -0,0 +1,80 @@ +From 27ee1b988a465e5f89e8a9234f4a01c34cab4387 Mon Sep 17 00:00:00 2001 +From: wangshouping +Date: Mon, 27 Apr 2020 08:53:18 -0400 +Subject: [PATCH] print main queue info to journal when receive USR1 signal + +Signed-off-by: wangshouping +--- + tools/rsyslogd.c | 19 ++++++++++++++++++- + 1 files changed, 45 insertions(+), 1 deletion(-) + +diff --git a/tools/rsyslogd.c b/tools/rsyslogd.c +index 7832693..ad92b20 100644 +--- a/tools/rsyslogd.c ++++ b/tools/rsyslogd.c +@@ -38,6 +38,7 @@ + #ifdef HAVE_LIBSYSTEMD + # include + #endif ++#include + + #include "rsyslog.h" + #include "wti.h" +@@ -181,6 +182,7 @@ void rsyslogdDoDie(int sig); + /* global data items */ + static int bChildDied; + static int bHadHUP; ++static int g_bRecordQueue; + static int doFork = 1; /* fork - run in daemon mode - read-only after startup */ + int bFinished = 0; /* used by termination signal handler, read-only except there + * is either 0 or the number of the signal that requested the +@@ -1267,8 +1269,13 @@ rsyslogdDebugSwitch(void) + dbgprintf("\n"); + debugging_on = 0; + } ++ + } + ++static void RsyslogdDebugQueue(void) ++{ ++ g_bRecordQueue = 1; ++} + + /* This is the main entry point into rsyslogd. Over time, we should try to + * modularize it a bit more... +@@ -1616,7 +1623,7 @@ initAll(int argc, char **argv) + hdlr_enable(SIGINT, rsyslogdDoDie); + hdlr_enable(SIGQUIT, rsyslogdDoDie); + } else { +- hdlr_enable(SIGUSR1, SIG_IGN); ++ hdlr_enable(SIGUSR1, RsyslogdDebugQueue); + hdlr_enable(SIGINT, SIG_IGN); + hdlr_enable(SIGQUIT, SIG_IGN); + } +@@ -1953,6 +1960,7 @@ mainloop(void) + sigaddset(&sigblockset, SIGTERM); + sigaddset(&sigblockset, SIGCHLD); + sigaddset(&sigblockset, SIGHUP); ++ sigaddset(&sigblockset, SIGUSR1); + + do { + processImInternal(); +@@ -1967,6 +1975,15 @@ mainloop(void) + doHUP(); + bHadHUP = 0; + } ++ if (g_bRecordQueue) { ++ if (pMsgQueue != NULL) { ++ sd_journal_print(LOG_NOTICE, "main queue size information: current QueueSize=%d MaxQueueSize=%d\n", ++ pMsgQueue->iQueueSize, pMsgQueue->iMaxQueueSize); ++ } else { ++ sd_journal_print(LOG_NOTICE, "main queue size information: pMsgQueue is NULL!\n"); ++ } ++ g_bRecordQueue = 0; ++ } + + if(bFinished) + break; /* exit as quickly as possible */ +-- +2.19.1 + diff --git a/openEuler-rsyslog.service.in-create-PID-file.patch b/openEuler-rsyslog.service.in-create-PID-file.patch new file mode 100644 index 0000000..bcdce2d --- /dev/null +++ b/openEuler-rsyslog.service.in-create-PID-file.patch @@ -0,0 +1,30 @@ +From 540fea48c4fb300b8ec5ebe9a37387460264efef Mon Sep 17 00:00:00 2001 +From: wangshouping +Date: Thu, 5 Mar 2020 21:55:21 -0500 +Subject: [PATCH] rsyslog.service.in: create PID file + +Signed-off-by: wangshouping +--- + rsyslog.service.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/rsyslog.service.in b/rsyslog.service.in +index b761ae5..2fd89b0 100644 +--- a/rsyslog.service.in ++++ b/rsyslog.service.in +@@ -6,7 +6,11 @@ Documentation=https://www.rsyslog.com/doc/ + + [Service] + Type=notify +-ExecStart=@sbindir@/rsyslogd -n -iNONE ++ExecStart=@sbindir@/rsyslogd -n -i/var/run/rsyslogd.pid ++ExecStartPost=/bin/bash /usr/bin/timezone_update.sh ++UMask=0066 ++StartLimitBurst=100 ++RestartSec=1s + StandardOutput=null + Restart=on-failure + +-- +2.19.1 + diff --git a/rsyslog-8.37.0-initialize-variables-and-check-return-value.patch b/rsyslog-8.37.0-initialize-variables-and-check-return-value.patch index 24e0928..c7c1a3b 100644 --- a/rsyslog-8.37.0-initialize-variables-and-check-return-value.patch +++ b/rsyslog-8.37.0-initialize-variables-and-check-return-value.patch @@ -57,19 +57,6 @@ index 3a93b37..1656de7 100644 }else /* submit message */ enqMsg((uchar *)message, (uchar *) sys_iden_help, facility, severity, &tv, json, 0); -diff --git a/tools/rsyslogd.c b/tools/rsyslogd.c -index 6b531b1..7832693 100644 ---- a/tools/rsyslogd.c -+++ b/tools/rsyslogd.c -@@ -266,7 +266,7 @@ static rsRetVal - writePidFile(void) - { - FILE *fp; -- int fd; -+ int fd = -1; - DEFiRet; - - const char *tmpPidFile; -- 2.19.1 diff --git a/rsyslog.spec b/rsyslog.spec index e02a284..a29e194 100644 --- a/rsyslog.spec +++ b/rsyslog.spec @@ -4,7 +4,7 @@ Name: rsyslog Version: 8.2006.0 -Release: 4 +Release: 5 Summary: The rocket-fast system for log processing License: (GPLv3+ and ASL 2.0) URL: http://www.rsyslog.com/ @@ -17,11 +17,28 @@ Source5: os_rotate_and_save_log.sh Source6: os_check_timezone_for_rsyslog.sh Source7: timezone.cron +Patch6000: backport-testbench-set-msg-size-to-64kb-for-sndrcv_omudpspoof.patch +Patch6001: backport-FIX-IMUDP-add-missing-free-during-freeCnf.patch +Patch6002: backport-gnutls-Propagate-CheckExtendedKeyPurpose-when-accept.patch +Patch6003: backport-Add-max-sessions-for-imptcp.c-similar-to-imtcp.c.patch +Patch6004: backport-omelasticsearch-Fix-reply-buffer-reset-after-health-.patch +Patch6005: backport-config-bugfix-intended-warning-emitted-as-error.patch +Patch6006: backport-core-bugfix-segfault-if-disk-queue-file-cannot-be-cr.patch +Patch6007: backport-imtcp-bugfix-broken-connection-not-necessariy-detect.patch +Patch6008: backport-core-bugfix-potential-segfault-on-querey-of-PROGRAMN.patch +Patch6009: backport-Replaced-eCmdHdlrPositiveInt-with-eCmdHdlrNonNegInt-.patch +Patch6010: backport-Replace-GNUTLS_SHUT_RDWR-by-GNUTLS_SHUT_WR-when-endi.patch +Patch6011: backport-core-network-obey-net.enableDNS-off-when-querying-lo.patch +Patch6012: backport-Do-not-create-empty-objects-when-accessing-non-exist.patch +Patch6013: backport-gnutls-Added-handshake-error-handling-into-doRetry-h.patch +Patch6014: backport-msg-segfault-in-jsonPathFindNext-when-root-is-not-an.patch +Patch6015: backport-msg-memory-leak-in-msgAddJSON-if-jsonPathFindParent-.patch + Patch9000: rsyslog-8.24.0-ensure-parent-dir-exists-when-writting-log-file.patch Patch9001: bugfix-rsyslog-7.4.7-imjournal-add-monotonic-timestamp.patch Patch9002: bugfix-rsyslog-7.4.7-add-configuration-to-avoid-memory-leak.patch -Patch9003: rsyslog-8.24.0-set-permission-of-syslogd-dot-pid-to-0644.patch Patch9004: rsyslog-8.37.0-initialize-variables-and-check-return-value.patch +Patch9005: openEuler-rsyslog.service.in-create-PID-file.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 @@ -242,6 +259,7 @@ do umask 066 && touch $n done %systemd_post rsyslog.service +systemctl daemon-reload >/dev/null 2>&1 %preun %systemd_preun rsyslog.service @@ -356,6 +374,12 @@ done %{_mandir}/man1/rscryutil.1.gz %changelog +* Fri Jan 15 2020 shangyibin - 8.2006.0-5 +- Type:NA +- ID:NA +- SUG:NA +- DESC:patch round repair. + * Fri Jan 8 2020 shangyibin - 8.2006.0-4 - Type:NA - ID:NA diff --git a/timezone_update.sh b/timezone_update.sh new file mode 100644 index 0000000..5173290 --- /dev/null +++ b/timezone_update.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +umask 0066 +/usr/bin/date +%Z%z > /etc/localtime_tmp -- Gitee