mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-09-26 00:11:04 +00:00
thrift: fix CVE-2026-48145
Improper Validation of Certificate with Host Mismatch vulnerability in Apache Thrift C++ bindings. This issue affects Apache Thrift: before 0.24.0. Backport patch to fix CVE-2026-48145. Reference: [https://nvd.nist.gov/vuln/detail/cve-2026-48145] Upstream Patch: [https://github.com/apache/thrift/commit/c1457c69fbd49c6d554dafe91f1004049537322b] Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
From c1457c69fbd49c6d554dafe91f1004049537322b Mon Sep 17 00:00:00 2001
|
||||
From: Jens Geyer <jensg@apache.org>
|
||||
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 <noreply@anthropic.com>
|
||||
Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com>
|
||||
---
|
||||
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 <boost/test/unit_test.hpp>
|
||||
+#include <thrift/transport/TSSLSocket.h>
|
||||
+
|
||||
+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<int>(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()
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user