Rebase to 8.2604.0

Drop ossl-free-cert.patch and gtls-unused-certificates.patch (upstream).
Backport imfile inotify FD release fix from upstream PR #6753.
Add impstats_push bcond (disabled on RHEL) to avoid unnecessary deps.

Resolves: RHEL-140910
Resolves: RHEL-149118
Resolves: RHEL-150376
Resolves: RHEL-151324
Resolves: RHEL-164768
This commit is contained in:
Cropi 2026-04-29 13:41:28 +02:00
parent f8133c6b0b
commit 5fd3e89167
6 changed files with 210 additions and 174 deletions

1
.gitignore vendored
View File

@ -102,3 +102,4 @@ rsyslog-4.6.3.tar.gz
/rsyslog-doc-8.2506.0.tar.gz
/rsyslog-8.2510.0.tar.gz
/qpid-proton-0.40.0.tar.gz
/rsyslog-8.2604.0.tar.gz

View File

@ -1,127 +0,0 @@
From e3f131d561a1df7dd07631345662ab678614bba7 Mon Sep 17 00:00:00 2001
From: Cropi <alakatos@redhat.com>
Date: Mon, 3 Nov 2025 14:13:19 +0100
Subject: [PATCH 2/2] nsd_gtls: fix repeated warnings on connection retry +
test
Move the `loggedWarnings` bitfield from per-instance to module-level
static storage in `runtime/nsd_gtls.c` so that missing cert/key/CA
warnings are emitted only once per rsyslogd process, not on every
connection retry. Otherwise, a broken connection can spam dosens of
logs.
---
runtime/nsd_gtls.c | 26 ++++++++++++++-----------
runtime/nsd_gtls.h | 1 -
tests/omfwd-gtls-missing-cert-key.sh | 29 ++++++++++++++++++++++++++++
3 files changed, 44 insertions(+), 12 deletions(-)
create mode 100755 tests/omfwd-gtls-missing-cert-key.sh
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index 7721c1bd1..9a7939fba 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -77,6 +77,9 @@ static pthread_mutex_t mutGtlsStrerror;
static gnutls_dh_params_t dh_params; /**< server DH parameters for anon mode */
+/* Module-level bitfield for warnings that have been logged (shared across all instances) */
+static unsigned loggedWarnings = 0;
+
/* bitfield for warnings that have been logged */
enum {
GTLS_LOGGED_WARN_CERT_MISSING = 1 << 0,
@@ -674,13 +677,14 @@ static rsRetVal gtlsAddOurCert(nsd_gtls_t *const pThis) {
keyFile = (pThis->pszKeyFile == NULL) ? glbl.GetDfltNetstrmDrvrKeyFile(runConf) : pThis->pszKeyFile;
dbgprintf("GTLS certificate file: '%s'\n", certFile);
dbgprintf("GTLS key file: '%s'\n", keyFile);
- if (certFile == NULL && !(pThis->loggedWarnings & GTLS_LOGGED_WARN_CERT_MISSING)) {
- LogMsg(0, RS_RET_CERT_MISSING, LOG_WARNING, "warning: certificate file is not set");
- pThis->loggedWarnings |= GTLS_LOGGED_WARN_CERT_MISSING;
+
+ if (certFile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_CERT_MISSING)) {
+ LogError(0, RS_RET_CERT_MISSING, "warning: certificate file is not set");
+ loggedWarnings |= GTLS_LOGGED_WARN_CERT_MISSING;
}
- if (keyFile == NULL && !(pThis->loggedWarnings & GTLS_LOGGED_WARN_KEY_MISSING)) {
- LogMsg(0, RS_RET_CERTKEY_MISSING, LOG_WARNING, "warning: key file is not set");
- pThis->loggedWarnings |= GTLS_LOGGED_WARN_KEY_MISSING;
+ if (keyFile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_KEY_MISSING)) {
+ LogError(0, RS_RET_CERTKEY_MISSING, "warning: key file is not set");
+ loggedWarnings |= GTLS_LOGGED_WARN_KEY_MISSING;
}
/* set certificate in gnutls */
@@ -757,10 +761,11 @@ static rsRetVal gtlsInitCred(nsd_gtls_t *const pThis) {
/* sets the trusted cas file */
cafile = (pThis->pszCAFile == NULL) ? glbl.GetDfltNetstrmDrvrCAF(runConf) : pThis->pszCAFile;
- if (cafile == NULL && !(pThis->loggedWarnings & GTLS_LOGGED_WARN_CA_MISSING)) {
- LogMsg(0, RS_RET_CA_CERT_MISSING, LOG_WARNING, "Warning: CA certificate is not set");
- pThis->loggedWarnings |= GTLS_LOGGED_WARN_CA_MISSING;
- } else {
+ if (cafile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_CA_MISSING)) {
+ LogError(0, RS_RET_CA_CERT_MISSING, "Warning: CA certificate is not set");
+ loggedWarnings |= GTLS_LOGGED_WARN_CA_MISSING;
+ }
+ if (cafile != NULL) {
dbgprintf("GTLS CA file: '%s'\n", cafile);
gnuRet = gnutls_certificate_set_x509_trust_file(pThis->xcred, (char *)cafile, GNUTLS_X509_FMT_PEM);
if (gnuRet == GNUTLS_E_FILE_ERROR) {
@@ -1432,7 +1437,6 @@ static inline void gtlsSetTransportPtr(nsd_gtls_t *pThis, int sock) {
BEGINobjConstruct(nsd_gtls) /* be sure to specify the object type also in END macro! */
iRet = nsd_ptcp.Construct(&pThis->pTcp);
pThis->bReportAuthErr = 1;
- pThis->loggedWarnings = 0;
ENDobjConstruct(nsd_gtls)
diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h
index 685f65a49..f40ab3f13 100644
--- a/runtime/nsd_gtls.h
+++ b/runtime/nsd_gtls.h
@@ -83,7 +83,6 @@ struct nsd_gtls_s {
gnutls_x509_privkey_t ourKey; /**< our private key, if in client mode (unused in server mode) */
short bOurCertIsInit; /**< 1 if our certificate is initialized and must be deinit on destruction */
short bOurKeyIsInit; /**< 1 if our private key is initialized and must be deinit on destruction */
- unsigned short loggedWarnings; /**< bitfield of logged warnings */
char *pszRcvBuf;
int lenRcvBuf;
/**< -1: empty, 0: connection closed, 1..NSD_GTLS_MAX_RCVBUF-1: data of that size present */
diff --git a/tests/omfwd-gtls-missing-cert-key.sh b/tests/omfwd-gtls-missing-cert-key.sh
new file mode 100755
index 000000000..36cb2f3f5
--- /dev/null
+++ b/tests/omfwd-gtls-missing-cert-key.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Test for gnutls loggedWarnings functionality with omfwd
+# This test verifies that warnings for missing cert/key files are logged only once
+# even when the action retries multiple times (loggedWarnings mechanism)
+. ${srcdir:=.}/diag.sh init
+
+export PORT_RCVR="$(get_free_port)"
+export RS_REDIR=">${RSYSLOG_DYNNAME}.rsyslog.log 2>&1"
+
+generate_conf
+add_conf '
+global(defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'")
+
+action(type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'"
+ StreamDriver="gtls"
+ StreamDriverMode="1"
+ StreamDriverAuthMode="x509/name"
+ action.resumeRetryCount="-1"
+ action.resumeInterval="10")
+'
+startup
+sleep 30
+shutdown_immediate
+wait_shutdown
+
+content_count_check "warning: certificate file is not set" 1 ${RSYSLOG_DYNNAME}.rsyslog.log
+content_count_check "warning: key file is not set" 1 ${RSYSLOG_DYNNAME}.rsyslog.log
+
+exit_test
--
2.51.0

View File

@ -0,0 +1,172 @@
From 600553721413e8981383b73138b8a086ad7dfba7 Mon Sep 17 00:00:00 2001
From: Cropi <alakatos@redhat.com>
Date: Thu, 23 Apr 2026 10:35:22 +0200
Subject: [PATCH] imfile: release deleted-file FDs after FILE_DELETE_DELAY in
inotify mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In inotify mode, when a monitored file is deleted and no further
inotify events arrive, poll() blocks indefinitely and the deleted
file's FD is never closed — the disk space is never reclaimed.
Cap poll() timeout to FILE_DELETE_DELAY+1 s whenever deletions are
pending, and run a tree walk on that timeout to clean up stale FDs.
---
plugins/imfile/imfile.c | 30 +++++++++++
tests/Makefile.am | 1 +
tests/imfile-inotify-fd-release-on-delete.sh | 56 ++++++++++++++++++++
3 files changed, 87 insertions(+)
create mode 100755 tests/imfile-inotify-fd-release-on-delete.sh
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
index d9c754811e..a60813a2ab 100644
--- a/plugins/imfile/imfile.c
+++ b/plugins/imfile/imfile.c
@@ -106,6 +106,7 @@ DEF_IMOD_STATIC_DATA /* must be present, starts static data */
const size_t outlen); /* see siphash.c */
static int bLegacyCnfModGlobalsPermitted; /* are legacy module-global config parameters permitted? */
+static sbool havePendingDeletes = 0; /* set when files await deferred deletion after FILE_DELETE_DELAY */
#define NUM_MULTISUB 1024 /* default max number of submits */
#define DFLT_PollInterval 10
@@ -970,6 +971,7 @@ static void detect_updates(fs_edge_t *const edge) {
"detect_updates obj gone away, keep '%s' "
"open: %" PRId64 "/%" PRId64 "/%" PRId64 "s!\n",
act_name, (int64_t)act->time_to_delete, (int64_t)ttNow, (int64_t)ttNow - act->time_to_delete);
+ havePendingDeletes = 1;
pollFile(act);
}
break;
@@ -2649,6 +2651,7 @@ static rsRetVal do_inotify(void) {
int currev;
static int last_timeout = 0;
time_t last_fallback = 0;
+ time_t last_delete_check = 0;
struct pollfd pollfd;
DEFiRet;
@@ -2684,6 +2687,14 @@ static rsRetVal do_inotify(void) {
poll_timeout = fallback_timeout;
}
}
+ /* Cap poll() so we wake up to clean up deleted-file FDs even
+ * when no inotify events arrive. */
+ if (havePendingDeletes) {
+ const int delete_timeout = (FILE_DELETE_DELAY + 1) * 1000;
+ if (poll_timeout == -1 || delete_timeout < poll_timeout) {
+ poll_timeout = delete_timeout;
+ }
+ }
r = poll(&pollfd, 1, poll_timeout);
if (r == -1 && errno == EINTR) {
@@ -2703,6 +2714,14 @@ static rsRetVal do_inotify(void) {
last_fallback = now;
}
}
+ /* poll() timed out — re-check deleted files whose
+ * FILE_DELETE_DELAY has now elapsed. */
+ if (havePendingDeletes) {
+ DBGPRINTF("pending deletes exist, running tree walk to re-check\n");
+ havePendingDeletes = 0;
+ fs_node_walk(runModConf->conf_tree, poll_tree);
+ last_delete_check = time(NULL);
+ }
continue;
} else if (r == -1) {
LogError(errno, RS_RET_INTERNAL_ERROR, "%s:%d: unexpected error during poll timeout wait", __FILE__,
@@ -2730,6 +2749,17 @@ static rsRetVal do_inotify(void) {
last_fallback = now;
}
}
+ /* Under sustained event load poll() never times out, so
+ * also check here, rate-limited to once per FILE_DELETE_DELAY. */
+ if (havePendingDeletes) {
+ time_t now = time(NULL);
+ if (last_delete_check == 0 || last_delete_check + FILE_DELETE_DELAY + 1 <= now) {
+ DBGPRINTF("pending deletes exist (event path), running tree walk to re-check\n");
+ havePendingDeletes = 0;
+ fs_node_walk(runModConf->conf_tree, poll_tree);
+ last_delete_check = now;
+ }
+ }
rd = read(ino_fd, iobuf, sizeof(iobuf));
if (rd == -1 && errno == EINTR) {
/* This might have been our termination signal! */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 63fb091703..3302c614ef 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1681,6 +1681,7 @@ TESTS_IMFILE = \
imfile-rename.sh \
imfile-symlink.sh \
imfile-symlink-multi.sh \
+ imfile-inotify-fd-release-on-delete.sh \
imfile-symlink-ext-tmp-dir-tree.sh \
imfile-logrotate.sh \
imfile-logrotate-async.sh \
diff --git a/tests/imfile-inotify-fd-release-on-delete.sh b/tests/imfile-inotify-fd-release-on-delete.sh
new file mode 100755
index 0000000000..d71905724f
--- /dev/null
+++ b/tests/imfile-inotify-fd-release-on-delete.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Test that imfile in inotify mode releases FDs of deleted files
+# after FILE_DELETE_DELAY without requiring any additional inotify
+# events. When no new events arrive after a file is deleted, poll()
+# blocks indefinitely and the FD is never closed, leaking disk space.
+# This is part of the rsyslog testbench, licensed under ASL 2.0
+. "${srcdir:=.}"/diag.sh init
+. "$srcdir"/diag.sh check-inotify-only
+
+export TESTMESSAGES=100
+export RETRIES=50
+
+generate_conf
+add_conf '
+global(workDirectory="'${RSYSLOG_DYNNAME}'.spool")
+module(load="../plugins/imfile/.libs/imfile" mode="inotify")
+input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input")
+
+template(name="outfmt" type="string" string="%msg:F,58:2%\n")
+if $msg contains "msgnum:" then
+ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
+'
+
+./inputfilegen -m $TESTMESSAGES > "$RSYSLOG_DYNNAME".input
+startup
+wait_file_lines "$RSYSLOG_OUT_LOG" $TESTMESSAGES $RETRIES
+
+PID=$(cat "$RSYSLOG_PIDBASE".pid)
+if [ -z "$PID" ]; then
+ printf 'FAIL: could not read rsyslog PID\n'
+ error_exit 1
+fi
+check_fd_for_pid "$PID" exists ".input"
+
+rm "$RSYSLOG_DYNNAME".input
+
+# Wait for rsyslog to release the FD on its own — no new files, no
+# trigger events. FILE_DELETE_DELAY is 5 s, the fix caps poll() at
+# FILE_DELETE_DELAY+1 s, so 20 s is more than enough.
+max_wait=20
+i=0
+while ! check_fd_for_pid "$PID" absent ".input (deleted)"; do
+ if [ "$i" -ge "$max_wait" ]; then
+ printf 'FAIL: rsyslog did not release FD for deleted file after %d s\n' "$max_wait"
+ find /proc/"$PID"/fd/ -lname '*deleted*' -ls 2>/dev/null
+ error_exit 1
+ fi
+ ./msleep 1000
+ ((i++))
+done
+printf 'PASS: FD released after %d s\n' "$i"
+
+shutdown_when_empty
+wait_shutdown
+seq_check 0 $(( TESTMESSAGES - 1 ))
+exit_test

View File

@ -1,38 +0,0 @@
From e21ea186a88d2750c97092c016811d1378cbe24c Mon Sep 17 00:00:00 2001
From: Cropi <alakatos@redhat.com>
Date: Thu, 9 Oct 2025 11:39:46 +0200
Subject: [PATCH] ossl bugfix: ensure peer cert is freed in osslChkPeerAuth
Ensure osslChkPeerAuth starts with a null peer-certificate pointer and
frees any retrieved X509 certificate so OpenSSL allocations from
SSL_get_peer_certificate do not leak after TLS handshakes.
---
runtime/nsd_ossl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/runtime/nsd_ossl.c b/runtime/nsd_ossl.c
index 30300156b..954277fef 100644
--- a/runtime/nsd_ossl.c
+++ b/runtime/nsd_ossl.c
@@ -353,7 +353,7 @@ finalize_it:
*/
rsRetVal osslChkPeerAuth(nsd_ossl_t *pThis) {
DEFiRet;
- X509 *certpeer;
+ X509 *certpeer = NULL;
ISOBJ_TYPE_assert(pThis, nsd_ossl);
uchar *fromHostIP = NULL;
@@ -388,6 +388,9 @@ rsRetVal osslChkPeerAuth(nsd_ossl_t *pThis) {
break;
}
finalize_it:
+ if (certpeer != NULL) {
+ X509_free(certpeer);
+ }
if (fromHostIP != NULL) {
free(fromHostIP);
}
--
2.51.0

View File

@ -3,7 +3,7 @@
%define rsyslog_docdir %{_docdir}/rsyslog
%define qpid_proton_v 0.40.0
# The following packages are not enabled on rhel:
# hiredis, libdbi, mongodb, rabbitmq
# hiredis, libdbi, mongodb, rabbitmq, impstats_push
# The omamqp1 plugin is built differently as qpid-proton is not available on rhel
%if 0%{?rhel}
%bcond_with hiredis
@ -11,11 +11,13 @@
%bcond_with mongodb
%bcond_with rabbitmq
%bcond_with mmtaghostname
%bcond_with impstats_push
%else
%bcond_without hiredis
%bcond_without libdbi
%bcond_without mongodb
%bcond_without rabbitmq
%bcond_without impstats_push
%endif
# Add options to not build with features listed below,
@ -36,8 +38,8 @@
Summary: Enhanced system logging and kernel message trapping daemon
Name: rsyslog
Version: 8.2510.0
Release: 5%{?dist}
Version: 8.2604.0
Release: 2%{?dist}
License: GPL-3.0-or-later AND Apache-2.0
URL: http://www.rsyslog.com/
Source0: http://www.rsyslog.com/files/download/rsyslog/%{name}-%{version}.tar.gz
@ -50,6 +52,8 @@ Source4: rsyslog.service
Source5: https://archive.apache.org/dist/qpid/proton/%{qpid_proton_v}/qpid-proton-%{qpid_proton_v}.tar.gz
Source7: rsyslog-tmpfiles.conf
Patch0: imfile-inotify-fd-release-on-delete.patch
BuildRequires: make
BuildRequires: gcc
BuildRequires: autoconf
@ -69,8 +73,11 @@ BuildRequires: systemd-rpm-macros
BuildRequires: zlib-devel
BuildRequires: libcap-ng-devel
Patch0: ossl-free-cert.patch
Patch1: gtls-unused-certificates.patch
%if %{with impstats_push}
BuildRequires: protobuf-c-compiler
BuildRequires: protobuf-c-devel
BuildRequires: snappy-devel
%endif
Recommends: logrotate
Obsoletes: rsyslog-logrotate < 8.2310.0-2
@ -380,9 +387,8 @@ This module allows rsyslog to send messages to a RabbitMQ server.
%prep
# set up rsyslog sources
%setup -q -D
%patch -P0 -p1
%patch -P 0 -p1
%patch -P 1 -p1
%if %{with omamqp1}
# Unpack qpid-proton
@ -413,7 +419,8 @@ export CFLAGS="$RPM_OPT_FLAGS -fpic"
-DPython_FIND_STRATEGY=LOCATION \
-DPython_ROOT_DIR=/usr \
-DCMAKE_AR="/usr/bin/gcc-ar" -DCMAKE_NM="/usr/bin/gcc-nm" -DCMAKE_RANLIB="/usr/bin/gcc-ranlib"
make -j8
make generated_c_files
make %{?_smp_mflags}
)
%endif
@ -481,6 +488,11 @@ autoreconf -if
--enable-omkafka \
%endif
--enable-impstats \
%if %{with impstats_push}
--enable-impstats-push \
%else
--disable-impstats-push \
%endif
--enable-imptcp \
--enable-mail \
--enable-mmanon \
@ -567,6 +579,8 @@ rm -f %{buildroot}%{_libdir}/rsyslog/*.la
# imdiag and liboverride is only used for testing
rm -f %{buildroot}%{_libdir}/rsyslog/imdiag.so
rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_gethostname.so
rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_getaddrinfo.so
rm -f %{buildroot}%{_libdir}/rsyslog/liboverride_gethostname_nonfqdn.so
%post
for n in /var/log/{messages,secure,maillog,spooler}
@ -769,6 +783,20 @@ done
%changelog
* Wed Apr 29 2026 Attila Lakatos <alakatos@redhat.com> - 8.2604.0-2
- Rebase to 8.2604.0
Resolves: RHEL-140910
- Drop ossl-free-cert.patch (upstream)
- Drop gtls-unused-certificates.patch (upstream)
- Add SAN:IP validation support
Resolves: RHEL-150376
- Add TlsRevocationCheck support
Resolves: RHEL-151324
- Fix omelasticsearch IPv6 handling
Resolves: RHEL-164768
- Fix imfile not releasing deleted file FDs in inotify mode
Resolves: RHEL-149118
* Mon Oct 20 2025 Attila Lakatos <alakatos@redhat.com> - 8.2510.0-5
- Rebase to 8.2510.0
- gnutls netstream driver: improve doc

View File

@ -1,2 +1,2 @@
SHA512 (rsyslog-8.2510.0.tar.gz) = d2e693fd8c7112e4ccc36ea6fbb19909df885e7cb2778e95c04b7c5e9db8240224decfee52308a46865b7deffcf1e31ade0104c90d84b768a4dece15e5ea190e
SHA512 (rsyslog-8.2604.0.tar.gz) = 99743293858f36f728370a1d52a9484ad4bc9dea04b79b893bff7fddccf7c558ce425e117881975ab03e199a7f49c451df7a7937a93993943047a0515c3423b9
SHA512 (qpid-proton-0.40.0.tar.gz) = 3e7fe56ca1423f45f71d81f5e1d6ec5f21c073cc580628e12a8dbd545a86805b7312834e0d1234dde43797633d575ed639f21a96239b217500cc0a824482aae3