diff --git a/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-48145.patch b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-48145.patch new file mode 100644 index 0000000000..34be3bb6cc --- /dev/null +++ b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-48145.patch @@ -0,0 +1,137 @@ +From c1457c69fbd49c6d554dafe91f1004049537322b Mon Sep 17 00:00:00 2001 +From: Jens Geyer +Date: Thu, 21 May 2026 00:16:49 +0200 +Subject: [PATCH] Enforce RFC 6125 wildcard placement in TSSLSocket hostname + matching Client: cpp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Wildcards in certificate names must appear only in the leftmost +label per RFC 6125 §6.4.3. Add the check to matchName() and +cover it with a dedicated Boost.Test suite. + +CVE: CVE-2026-48145 +Upstream-Status: Backport [https://github.com/apache/thrift/commit/c1457c69fbd49c6d554dafe91f1004049537322b] + +Co-Authored-By: Claude Sonnet 4.6 +Signed-off-by: Abhishek Bachiphale +--- + lib/cpp/src/thrift/transport/TSSLSocket.cpp | 6 ++ + lib/cpp/test/Makefile.am | 10 ++++ + lib/cpp/test/TSSLSocketMatchNameTest.cpp | 61 +++++++++++++++++++++ + 3 files changed, 77 insertions(+) + create mode 100644 lib/cpp/test/TSSLSocketMatchNameTest.cpp + +diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp +index db426c85ebe..f97962ea5b7 100644 +--- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp ++++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp +@@ -1215,6 +1215,12 @@ Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa, + * @return True, if "host" matches "pattern". False otherwise. + */ + bool matchName(const char* host, const char* pattern, int size) { ++ // RFC 6125 §6.4.3: wildcard must not appear outside the leftmost label. ++ bool past_first_dot = false; ++ for (int k = 0; k < size; k++) { ++ if (pattern[k] == '.') { past_first_dot = true; continue; } ++ if (pattern[k] == '*' && past_first_dot) return false; ++ } + bool match = false; + int i = 0, j = 0; + while (i < size && host[j] != '\0') { +diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am +index 7c4153b49e4..234dd0b9964 100644 +--- a/lib/cpp/test/Makefile.am ++++ b/lib/cpp/test/Makefile.am +@@ -108,6 +108,7 @@ check_PROGRAMS = \ + TFileTransportTest \ + link_test \ + OpenSSLManualInitTest \ ++ TSSLSocketMatchNameTest \ + EnumTest \ + RenderedDoubleConstantsTest \ + AnnotationTest +@@ -413,6 +414,15 @@ OpenSSLManualInitTest_LDADD = \ + $(OPENSSL_LDFLAGS) \ + $(OPENSSL_LIBS) + ++TSSLSocketMatchNameTest_SOURCES = \ ++ TSSLSocketMatchNameTest.cpp ++ ++TSSLSocketMatchNameTest_LDADD = \ ++ $(top_builddir)/lib/cpp/libthrift.la \ ++ $(BOOST_TEST_LDADD) \ ++ $(OPENSSL_LDFLAGS) \ ++ $(OPENSSL_LIBS) ++ + # + # Common thrift code generation rules + # +diff --git a/lib/cpp/test/TSSLSocketMatchNameTest.cpp b/lib/cpp/test/TSSLSocketMatchNameTest.cpp +new file mode 100644 +index 00000000000..dabfa59b9f8 +--- /dev/null ++++ b/lib/cpp/test/TSSLSocketMatchNameTest.cpp +@@ -0,0 +1,61 @@ ++/* ++ * Licensed to the Apache Software Foundation (ASF) under one ++ * or more contributor license agreements. See the NOTICE file ++ * distributed with this work for additional information ++ * regarding copyright ownership. The ASF licenses this file ++ * to you under the Apache License, Version 2.0 (the ++ * "License"); you may not use this file except in compliance ++ * with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, ++ * software distributed under the License is distributed on an ++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ * specific language governing permissions and limitations ++ * under the License. ++ */ ++ ++#define BOOST_TEST_MODULE TSSLSocketMatchNameTest ++#include ++#include ++ ++using apache::thrift::transport::AccessManager; ++using apache::thrift::transport::DefaultClientAccessManager; ++ ++BOOST_AUTO_TEST_SUITE(TSSLSocketMatchNameTest) ++ ++// Helper: ALLOW means match, SKIP means no match. ++static bool allows(const std::string& host, const std::string& pattern) { ++ DefaultClientAccessManager mgr; ++ return mgr.verify(host, pattern.c_str(), static_cast(pattern.size())) ++ == AccessManager::ALLOW; ++} ++ ++BOOST_AUTO_TEST_CASE(standard_wildcard_matches) { ++ BOOST_CHECK(allows("foo.example.com", "*.example.com")); ++ BOOST_CHECK(allows("FOO.EXAMPLE.COM", "*.example.com")); // case-insensitive ++ BOOST_CHECK(allows("a.b.c.example.com", "*.b.c.example.com")); // leftmost wildcard ++} ++ ++BOOST_AUTO_TEST_CASE(exact_match) { ++ BOOST_CHECK(allows("example.com", "example.com")); ++ BOOST_CHECK(allows("foo.example.com", "foo.example.com")); ++} ++ ++BOOST_AUTO_TEST_CASE(wildcard_must_not_span_labels) { ++ BOOST_CHECK(!allows("foo.bar.example.com", "*.example.com")); ++} ++ ++BOOST_AUTO_TEST_CASE(wildcard_must_be_in_leftmost_label) { ++ // RFC 6125 §6.4.3: wildcard must not appear outside the leftmost label. ++ BOOST_CHECK(!allows("example.foo.com", "example.*.com")); ++ BOOST_CHECK(!allows("a.evil.com", "a.ev*.com")); ++} ++ ++BOOST_AUTO_TEST_CASE(no_suffix_bypass) { ++ BOOST_CHECK(!allows("evil.com.attacker.com", "evil.com")); ++} ++ ++BOOST_AUTO_TEST_SUITE_END() diff --git a/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb b/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb index 49e9b20c03..a08bea58d6 100644 --- a/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb +++ b/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb @@ -24,6 +24,7 @@ SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \ file://CVE-2026-55970.patch \ file://CVE-2026-48586-01.patch \ file://CVE-2026-48586-02.patch \ + file://CVE-2026-48145.patch \ " SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"