[Syslog-ng-maintainers] Bug#1120690: bookworm-pu: package syslog-ng/3.38.1-5+deb12u1

Jochen Sprickerhof jspricke at debian.org
Fri Nov 14 18:43:11 GMT 2025


Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: syslog-ng at packages.debian.org
Control: affects -1 + src:syslog-ng
User: release.debian.org at packages.debian.org
Usertags: pu

[ Reason ]
This fixes CVE-2024-47619 in bookworm. It was tagged no-dsa but would be
still good to have fixed as it was fixed in older and newer releases.

[ Impact ]
Wildcard hostnames are not correctly checked in TLS certificates. Also
This would be a regression for users upgrading from older releases.

[ Tests ]
There are a number of new unit tests from the upstream commit and I ran
autopkgtest and other tests.

[ Risks ]
Low, the same patch is already rolled out in older releases and only
modifies one specific function. Given that TLS certificates are
regularly rotated anyway I expect stricter checks to be useful.

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]
The hostname check is extended to catch more invalid cases and how
special characters are treated. Also a number of unit tests are added.
-------------- next part --------------
diff --git a/debian/changelog b/debian/changelog
index 016dea9d..ef878e2b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+syslog-ng (3.38.1-5+deb12u1) bookworm; urgency=medium
+
+  * Non-maintainer upload by the LTS Security Team.
+  * Add fix for CVE-2024-47619: `tls_wildcard_match()` matches on certificates
+    such as `foo.*.bar` although that is not allowed. It is also possible to
+    pass partial wildcards such as `foo.a*c.bar` which glib matches but should
+    be avoided / invalidated. This issue could have an impact on TLS
+    connections, such as in man-in-the-middle situations.
+
+ -- Jochen Sprickerhof <jspricke at debian.org>  Thu, 23 Oct 2025 12:31:38 +0200
+
 syslog-ng (3.38.1-5) unstable; urgency=medium
 
   * Build without Criterion support.
diff --git a/debian/patches/CVE-2024-47619.patch b/debian/patches/CVE-2024-47619.patch
new file mode 100644
index 00000000..61080403
--- /dev/null
+++ b/debian/patches/CVE-2024-47619.patch
@@ -0,0 +1,274 @@
+From: syslog-ng maintainers <syslog-ng-maintainers at alioth-lists.debian.net>
+Date: Thu, 23 Oct 2025 11:52:01 +0200
+Subject: CVE-2024-47619.
+
+Origin: http://deb.freexian.com/extended-lts/pool/main/s/syslog-ng/syslog-ng_3.28.1-2%2Bdeb11u2.dsc
+---
+ lib/tlscontext.c                              |  83 ++++++++++++++++++---
+ lib/tlscontext.h                              |   1 +
+ lib/transport/tests/CMakeLists.txt            |   1 +
+ lib/transport/tests/Makefile.am               |   9 ++-
+ lib/transport/tests/test_tls_wildcard_match.c | 102 ++++++++++++++++++++++++++
+ 5 files changed, 184 insertions(+), 12 deletions(-)
+ create mode 100644 lib/transport/tests/test_tls_wildcard_match.c
+
+diff --git a/lib/tlscontext.c b/lib/tlscontext.c
+index 6ff6755..d8b30b6 100644
+--- a/lib/tlscontext.c
++++ b/lib/tlscontext.c
+@@ -1181,7 +1181,7 @@ tls_log_certificate_validation_progress(int ok, X509_STORE_CTX *ctx)
+   g_string_free(issuer_name, TRUE);
+ }
+ 
+-static gboolean
++ gboolean
+ tls_wildcard_match(const gchar *host_name, const gchar *pattern)
+ {
+   gchar **pattern_parts, **hostname_parts;
+@@ -1192,22 +1192,83 @@ tls_wildcard_match(const gchar *host_name, const gchar *pattern)
+ 
+   pattern_parts = g_strsplit(pattern, ".", 0);
+   hostname_parts = g_strsplit(host_name, ".", 0);
+-  for (i = 0; pattern_parts[i]; i++)
++  if(g_strrstr(pattern, "\?"))
++    {
++      /* Glib would treat any question marks as jokers */
++      success = FALSE;
++    }
++  else if (g_hostname_is_ip_address(host_name))
++    {
++      /* no wildcards in IP */
++      if (g_strrstr(pattern, "*"))
++        {
++          success = FALSE;
++        }
++      else
++        {
++          struct in6_addr host_buffer, pattern_buffer;
++          gint INET_TYPE, INET_ADDRLEN;
++          if(strstr(host_name, ":"))
++            {
++              INET_TYPE = AF_INET6;
++              INET_ADDRLEN = INET6_ADDRSTRLEN;
++            }
++          else
++            {
++              INET_TYPE = AF_INET;
++              INET_ADDRLEN = INET_ADDRSTRLEN;
++            }
++          char host_ip[INET_ADDRLEN], pattern_ip[INET_ADDRLEN];
++          gint host_ip_ok = inet_pton(INET_TYPE, host_name, &host_buffer);
++          gint pattern_ip_ok = inet_pton(INET_TYPE, pattern, &pattern_buffer);
++          inet_ntop(INET_TYPE, &host_buffer, host_ip, INET_ADDRLEN);
++          inet_ntop(INET_TYPE, &pattern_buffer, pattern_ip, INET_ADDRLEN);
++          success = (host_ip_ok && pattern_ip_ok && strcmp(host_ip, pattern_ip) == 0);
++        }
++    }
++  else
+     {
+-      if (!hostname_parts[i])
++      if (pattern_parts[0] == NULL)
+         {
+-          /* number of dot separated entries is not the same in the hostname and the pattern spec */
+-          goto exit;
++          if (hostname_parts[0] == NULL)
++            success = TRUE;
++          else
++            success = FALSE;
+         }
++else
++        {
++          success = TRUE;
++          for (i = 0; pattern_parts[i]; i++)
++            {
++              if (hostname_parts[i] == NULL)
++                {
++                  /* number of dot separated entries is not the same in the hostname and the pattern spec */
++                  success = FALSE;
++                  break;
++                }
++              char *wildcard_matched = g_strrstr(pattern_parts[i], "*");
++              if (wildcard_matched && (i != 0 || wildcard_matched != strstr(pattern_parts[i], "*")))
++                {
++                  /* wildcard only on leftmost part and never as multiple wildcards as per both RFC 6125 and 9525 */
++                  success = FALSE;
++                  break;
++                }
+ 
+-      lower_pattern = g_ascii_strdown(pattern_parts[i], -1);
+-      lower_hostname = g_ascii_strdown(hostname_parts[i], -1);
++              lower_pattern = g_ascii_strdown(pattern_parts[i], -1);
++              lower_hostname = g_ascii_strdown(hostname_parts[i], -1);
+ 
+-      if (!g_pattern_match_simple(lower_pattern, lower_hostname))
+-        goto exit;
++              if (!g_pattern_match_simple(lower_pattern, lower_hostname))
++                {
++                  success = FALSE;
++                  break;
++                }
++            }
++          if (hostname_parts[i])
++            /* hostname has more parts than the pattern */
++            success = FALSE;
++        }
+     }
+-  success = TRUE;
+-exit:
++
+   g_free(lower_pattern);
+   g_free(lower_hostname);
+   g_strfreev(pattern_parts);
+diff --git a/lib/tlscontext.h b/lib/tlscontext.h
+index 0c834fd..fdaff8f 100644
+--- a/lib/tlscontext.h
++++ b/lib/tlscontext.h
+@@ -145,6 +145,7 @@ EVTTAG *tls_context_format_location_tag(TLSContext *self);
+ 
+ void tls_log_certificate_validation_progress(int ok, X509_STORE_CTX *ctx);
+ gboolean tls_verify_certificate_name(X509 *cert, const gchar *hostname);
++gboolean tls_wildcard_match(const gchar *host_name, const gchar *pattern);
+ 
+ void tls_x509_format_dn(X509_NAME *name, GString *dn);
+ 
+diff --git a/lib/transport/tests/CMakeLists.txt b/lib/transport/tests/CMakeLists.txt
+index 834f456..ce1d033 100644
+--- a/lib/transport/tests/CMakeLists.txt
++++ b/lib/transport/tests/CMakeLists.txt
+@@ -3,3 +3,4 @@ add_unit_test(CRITERION TARGET test_transport_factory_id)
+ add_unit_test(CRITERION TARGET test_transport_factory)
+ add_unit_test(CRITERION TARGET test_transport_factory_registry)
+ add_unit_test(CRITERION TARGET test_multitransport)
++add_unit_test(CRITERION TARGET test_tls_wildcard_match)
+diff --git a/lib/transport/tests/Makefile.am b/lib/transport/tests/Makefile.am
+index 7eac994..ae2426c 100644
+--- a/lib/transport/tests/Makefile.am
++++ b/lib/transport/tests/Makefile.am
+@@ -3,7 +3,8 @@ lib_transport_tests_TESTS		 = \
+ 	lib/transport/tests/test_transport_factory_id \
+ 	lib/transport/tests/test_transport_factory \
+ 	lib/transport/tests/test_transport_factory_registry \
+-	lib/transport/tests/test_multitransport
++	lib/transport/tests/test_multitransport \
++	lib/transport/tests/test_tls_wildcard_match
+ 
+ EXTRA_DIST += lib/transport/tests/CMakeLists.txt
+ 
+@@ -38,3 +39,9 @@ lib_transport_tests_test_multitransport_CFLAGS  = $(TEST_CFLAGS) \
+ lib_transport_tests_test_multitransport_LDADD	 = $(TEST_LDADD)
+ lib_transport_tests_test_multitransport_SOURCES = 			\
+ 	lib/transport/tests/test_multitransport.c
++
++lib_transport_tests_test_tls_wildcard_match_CFLAGS  = $(TEST_CFLAGS) \
++	-I${top_srcdir}/lib/transport/tests
++lib_transport_tests_test_tls_wildcard_match_LDADD	 = $(TEST_LDADD)
++lib_transport_tests_test_tls_wildcard_match_SOURCES = 			\
++	lib/transport/tests/test_tls_wildcard_match.c
+diff --git a/lib/transport/tests/test_tls_wildcard_match.c b/lib/transport/tests/test_tls_wildcard_match.c
+new file mode 100644
+index 0000000..779e6d8
+--- /dev/null
++++ b/lib/transport/tests/test_tls_wildcard_match.c
+@@ -0,0 +1,102 @@
++/*
++ * Copyright (c) 2024 One Identity LLC.
++ * Copyright (c) 2024 Franco Fichtner
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ *
++ * As an additional exemption you are allowed to compile & link against the
++ * OpenSSL libraries as published by the OpenSSL project. See the file
++ * COPYING for details.
++ *
++ */
++
++#include <criterion/criterion.h>
++#include "lib/tlscontext.h"
++
++TestSuite(tls_wildcard, .init = NULL, .fini = NULL);
++
++Test(tls_wildcard, test_wildcard_match_pattern_acceptance)
++{
++  cr_assert_eq(tls_wildcard_match("test", "test"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test", "*"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test", "t*t"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test", "t*"), TRUE);
++  cr_assert_eq(tls_wildcard_match("", ""), TRUE);
++  cr_assert_eq(tls_wildcard_match("test.one", "test.one"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.two"), TRUE);
++  cr_assert_eq(tls_wildcard_match("192.0.2.0", "192.0.2.0"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"),
++               TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0:130F:0:0:9C0:876A:130B"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0:130F:0:0:9C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F::09C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130F::09C0:876A:130B"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0:130F::9C0:876A:130B"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0:130F::9C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
++}
++
++Test(tls_wildcard, test_wildcard_match_wildcard_rejection)
++{
++  cr_assert_eq(tls_wildcard_match("test", "**"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test", "*es*"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test", "t*?"), FALSE);
++}
++
++Test(tls_wildcard, test_wildcard_match_pattern_rejection)
++{
++  cr_assert_eq(tls_wildcard_match("test", "tset"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test", "set"), FALSE);
++  cr_assert_eq(tls_wildcard_match("", "*"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test", ""), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.two", "test.one"), FALSE);
++}
++
++Test(tls_wildcard, test_wildcard_match_format_rejection)
++{
++  cr_assert_eq(tls_wildcard_match("test.two", "test.*"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.two", "test.t*o"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test", "test.two"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.two", "test"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.one.two", "test.one"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.one", "test.one.two"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.three", "three.test"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.*"), FALSE);
++}
++
++Test(tls_wildcard, test_wildcard_match_complex_rejection)
++{
++  cr_assert_eq(tls_wildcard_match("test.two", "test.???"), FALSE);
++  cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.?wo"), FALSE);
++}
++
++Test(tls_wildcard, test_ip_wildcard_rejection)
++{
++  cr_assert_eq(tls_wildcard_match("192.0.2.0", "*.0.2.0"), FALSE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "*:0000:130F:0000:0000:09C0:876A:130B"),
++               FALSE);
++  cr_assert_eq(tls_wildcard_match("2001:0:130F::9C0:876A:130B", "*:0000:130F:0000:0000:09C0:876A:130B"), FALSE);
++}
++
++Test(tls_wildcard, test_case_insensivity)
++{
++  cr_assert_eq(tls_wildcard_match("test", "TEST"), TRUE);
++  cr_assert_eq(tls_wildcard_match("TEST", "test"), TRUE);
++  cr_assert_eq(tls_wildcard_match("TeST", "TEst"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test.one", "test.ONE"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test.TWO", "test.two"), TRUE);
++  cr_assert_eq(tls_wildcard_match("test.three", "*T.three"), TRUE);
++  cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130f:0000:0000:09c0:876a:130b"),
++               TRUE);
++}
diff --git a/debian/patches/series b/debian/patches/series
index 70fa1231..ee3dd044 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
 0001-Replace-direct-md5sum-file-access-with-dpkg-verify-c.patch
 0002-Update-control-file-path.patch
+CVE-2024-47619.patch


More information about the Syslog-ng-maintainers mailing list