Re: [ELIN-upstream] [meta-oe][wrynose][PATCH] thrift: fix CVE-2026-55969
"Adarsh Jagadish Kamini" <[email protected]>
| Newsgroups | org.openembedded.lists.openembedded-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/6/26 13:04, Adarsh Jagadish Kamini wrote: > Backport patch to fix CVE-2026-55969. > > References: > https://nvd.nist.gov/vuln/detail/CVE-2026-55969 > > Upstream fix: > https://github.com/apache/thrift/commit/983c813c9a1a2302d9a3ae23d7368beceaac2d0a > > Signed-off-by: Adarsh Jagadish Kamini <[email protected]> > --- > .../thrift/thrift/CVE-2026-55969.patch | 307 ++++++++++++++++++ > .../thrift/thrift_0.22.0.bb | 1 + > 2 files changed, 308 insertions(+) > create mode 100644 meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-55969.patch > > diff --git a/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-55969.patch b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-55969.patch > new file mode 100644 > index 0000000000..736984d077 > --- /dev/null > +++ b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-55969.patch > @@ -0,0 +1,307 @@ > +From 09f72e9ba64c551602f69abb6ea161b7020948be Mon Sep 17 00:00:00 2001 > +From: dxbjavid <[email protected]> > +Date: Tue, 9 Jun 2026 16:35:58 +0530 > +Subject: [PATCH] Widen multiplication operands in container size prechecks to > + prevent arithmetic overflow on LLP64 platforms Client: cpp,c_glib Patch: > + Javid Khan > + > +This closes #3590 > + > +Backport notes: applied only the container-size widening (gint64/int64_t > +casts on the multiplication operands) onto thrift 0.22.0. Dropped the > +unrelated string_limit/container_limit changes from thrift_binary_protocol.c, > +which depend on infrastructure not present in 0.22.0. > + > +Assisted-by: kiro:claude-sonnet-5 > + > +Changes from upstream commit 983c813c9a1a: > + - lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c: adapted from upstream > + - lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c: adapted from upstream > + - lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c: adapted from upstream > + - lib/cpp/src/thrift/protocol/TProtocol.h: adapted from upstream > + - lib/cpp/src/thrift/transport/TTransport.h: adapted from upstream > + - lib/cpp/test/ThrifttReadCheckTests.cpp: adapted from upstream > + > +CVE: CVE-2026-55969 > +Upstream-Status: Backport [https://github.com/apache/thrift/commit/983c813c9a1a2302d9a3ae23d7368beceaac2d0a] > + > +Signed-off-by: Adarsh Jagadish Kamini <[email protected]> > +--- > + .../c_glib/protocol/thrift_binary_protocol.c | 10 ++-- > + .../c_glib/protocol/thrift_compact_protocol.c | 10 ++-- > + .../c_glib/transport/thrift_transport.c | 2 +- > + .../c_glib/transport/thrift_transport.h | 2 +- > + lib/cpp/src/thrift/protocol/TBinaryProtocol.h | 6 +-- > + .../src/thrift/protocol/TCompactProtocol.h | 6 +-- > + lib/cpp/src/thrift/protocol/TJSONProtocol.h | 6 +-- > + lib/cpp/src/thrift/protocol/TProtocol.h | 6 +-- > + lib/cpp/src/thrift/transport/TTransport.h | 3 +- > + lib/cpp/test/ThrifttReadCheckTests.cpp | 48 +++++++++++++++++++ > + 10 files changed, 74 insertions(+), 25 deletions(-) > + > +diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c > +index 9e80e107c..c3b00b028 100644 > +--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c > ++++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_binary_protocol.c > +@@ -561,9 +561,9 @@ thrift_binary_protocol_read_map_begin (ThriftProtocol *protocol, > + return -1; > + } > + > +- if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), > +- sizei * thrift_binary_protocol_get_min_serialized_size(protocol, k, error) + > +- sizei * thrift_binary_protocol_get_min_serialized_size(protocol, v, error), > ++ if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), > ++ (gint64) sizei * thrift_binary_protocol_get_min_serialized_size(protocol, k, error) + > ++ (gint64) sizei * thrift_binary_protocol_get_min_serialized_size(protocol, v, error), > + error)) > + { > + return -1; > +@@ -618,8 +618,8 @@ thrift_binary_protocol_read_list_begin (ThriftProtocol *protocol, > + return -1; > + } > + > +- if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), > +- (sizei * thrift_binary_protocol_get_min_serialized_size(protocol, e, error)), > ++ if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT(tp->transport), > ++ ((gint64) sizei * thrift_binary_protocol_get_min_serialized_size(protocol, e, error)), > + error)) > + { > + return -1; > +diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c > +index 0aa9a6fe6..f6ad36b36 100644 > +--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c > ++++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_compact_protocol.c > +@@ -1108,9 +1108,9 @@ thrift_compact_protocol_read_map_begin (ThriftProtocol *protocol, > + return -1; > + } > + > +- if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), > +- msize * thrift_protocol_get_min_serialized_size (protocol, *key_type, error) + > +- msize * thrift_protocol_get_min_serialized_size (protocol, *value_type, error), > ++ if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), > ++ (gint64) msize * thrift_protocol_get_min_serialized_size (protocol, *key_type, error) + > ++ (gint64) msize * thrift_protocol_get_min_serialized_size (protocol, *value_type, error), > + error)) > + { > + return -1; > +@@ -1183,8 +1183,8 @@ thrift_compact_protocol_read_list_begin (ThriftProtocol *protocol, > + *element_type = ret; > + *size = (guint32) lsize; > + > +- if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), > +- (lsize * thrift_protocol_get_min_serialized_size (protocol, *element_type, error)), > ++ if(!ttc->checkReadBytesAvailable (THRIFT_TRANSPORT (tp->transport), > ++ ((gint64) lsize * thrift_protocol_get_min_serialized_size (protocol, *element_type, error)), > + error)) > + { > + return -1; > +diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c > +index 9d3f25e75..7e18f712a 100644 > +--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c > ++++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.c > +@@ -160,7 +160,7 @@ thrift_transport_updateKnownMessageSize(ThriftTransport *transport, glong size, > + } > + > + gboolean > +-thrift_transport_checkReadBytesAvailable(ThriftTransport *transport, glong numBytes, GError **error) > ++thrift_transport_checkReadBytesAvailable(ThriftTransport *transport, gint64 numBytes, GError **error) > + { > + gboolean boolean = TRUE; > + ThriftTransport *tt = THRIFT_TRANSPORT (transport); > +diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h > +index 83fb5da19..01365ba7f 100644 > +--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h > ++++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_transport.h > +@@ -83,7 +83,7 @@ struct _ThriftTransportClass > + gint32 (*read_all) (ThriftTransport *transport, gpointer buf, > + guint32 len, GError **error); > + gboolean (*updateKnownMessageSize) (ThriftTransport *transport, glong size, GError **error); > +- gboolean (*checkReadBytesAvailable) (ThriftTransport *transport, glong numBytes, GError **error); > ++ gboolean (*checkReadBytesAvailable) (ThriftTransport *transport, gint64 numBytes, GError **error); > + gboolean (*resetConsumedMessageSize) (ThriftTransport *transport, glong newSize, GError **error); > + gboolean (*countConsumedMessageBytes) (ThriftTransport *transport, glong numBytes, GError **error); > + }; > +diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h > +index cba6e6948..1a7410c86 100644 > +--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h > ++++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h > +@@ -174,18 +174,18 @@ public: > + > + void checkReadBytesAvailable(TSet& set) override > + { > +- trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(set.size_) * getMinSerializedSize(set.elemType_)); > + } > + > + void checkReadBytesAvailable(TList& list) override > + { > +- trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(list.size_) * getMinSerializedSize(list.elemType_)); > + } > + > + void checkReadBytesAvailable(TMap& map) override > + { > + int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); > +- trans_->checkReadBytesAvailable(map.size_ * elmSize); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(map.size_) * elmSize); > + } > + > + protected: > +diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h > +index c7d81eea6..97ca460a7 100644 > +--- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h > ++++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h > +@@ -146,18 +146,18 @@ public: > + > + void checkReadBytesAvailable(TSet& set) override > + { > +- trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(set.size_) * getMinSerializedSize(set.elemType_)); > + } > + > + void checkReadBytesAvailable(TList& list) override > + { > +- trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(list.size_) * getMinSerializedSize(list.elemType_)); > + } > + > + void checkReadBytesAvailable(TMap& map) override > + { > + int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); > +- trans_->checkReadBytesAvailable(map.size_ * elmSize); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(map.size_) * elmSize); > + } > + > + /** > +diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.h b/lib/cpp/src/thrift/protocol/TJSONProtocol.h > +index 09eb6eab1..265b33922 100644 > +--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.h > ++++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.h > +@@ -253,18 +253,18 @@ public: > + > + void checkReadBytesAvailable(TSet& set) override > + { > +- trans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(set.size_) * getMinSerializedSize(set.elemType_)); > + } > + > + void checkReadBytesAvailable(TList& list) override > + { > +- trans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(list.size_) * getMinSerializedSize(list.elemType_)); > + } > + > + void checkReadBytesAvailable(TMap& map) override > + { > + int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); > +- trans_->checkReadBytesAvailable(map.size_ * elmSize); > ++ trans_->checkReadBytesAvailable(static_cast<int64_t>(map.size_) * elmSize); > + } > + > + class LookaheadReader { > +diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h > +index 37b0db711..4eedc5e82 100644 > +--- a/lib/cpp/src/thrift/protocol/TProtocol.h > ++++ b/lib/cpp/src/thrift/protocol/TProtocol.h > +@@ -604,18 +604,18 @@ protected: > + > + virtual void checkReadBytesAvailable(TSet& set) > + { > +- ptrans_->checkReadBytesAvailable(set.size_ * getMinSerializedSize(set.elemType_)); > ++ ptrans_->checkReadBytesAvailable(static_cast<int64_t>(set.size_) * getMinSerializedSize(set.elemType_)); > + } > + > + virtual void checkReadBytesAvailable(TList& list) > + { > +- ptrans_->checkReadBytesAvailable(list.size_ * getMinSerializedSize(list.elemType_)); > ++ ptrans_->checkReadBytesAvailable(static_cast<int64_t>(list.size_) * getMinSerializedSize(list.elemType_)); > + } > + > + virtual void checkReadBytesAvailable(TMap& map) > + { > + int elmSize = getMinSerializedSize(map.keyType_) + getMinSerializedSize(map.valueType_); > +- ptrans_->checkReadBytesAvailable(map.size_ * elmSize); > ++ ptrans_->checkReadBytesAvailable(static_cast<int64_t>(map.size_) * elmSize); > + } > + > + std::shared_ptr<TTransport> ptrans_; > +diff --git a/lib/cpp/src/thrift/transport/TTransport.h b/lib/cpp/src/thrift/transport/TTransport.h > +index 52b3a0a4d..1269593ac 100644 > +--- a/lib/cpp/src/thrift/transport/TTransport.h > ++++ b/lib/cpp/src/thrift/transport/TTransport.h > +@@ -23,6 +23,7 @@ > + #include <thrift/Thrift.h> > + #include <thrift/TConfiguration.h> > + #include <thrift/transport/TTransportException.h> > ++#include <cstdint> > + #include <memory> > + #include <string> > + > +@@ -272,7 +273,7 @@ public: > + * > + * @param numBytes numBytes bytes of data > + */ > +- void checkReadBytesAvailable(long int numBytes) > ++ void checkReadBytesAvailable(int64_t numBytes) > + { > + if (remainingMessageSize_ < numBytes) > + throw TTransportException(TTransportException::END_OF_FILE, "MaxMessageSize reached"); > +diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp > +index 963286100..72e798bc1 100644 > +--- a/lib/cpp/test/ThrifttReadCheckTests.cpp > ++++ b/lib/cpp/test/ThrifttReadCheckTests.cpp > +@@ -243,6 +243,54 @@ BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_read_check_pass) { > + BOOST_CHECK_NO_THROW(protocol->readString(eleven)); > + } > + > ++BOOST_AUTO_TEST_CASE(test_tthriftbinaryprotocol_container_size_overflow) { > ++ std::shared_ptr<TConfiguration> config (new TConfiguration(1024)); > ++ std::shared_ptr<TMemoryBuffer> transport(new TMemoryBuffer(config)); > ++ std::shared_ptr<TBinaryProtocol> protocol(new TBinaryProtocol(transport)); > ++ > ++ uint32_t val = 0; > ++ TType elemType = apache::thrift::protocol::T_STOP; > ++ // 0x40000000 elements of min size 4 require 4 GiB; the product wraps to 0 in > ++ // 32-bit math and used to slip past the MaxMessageSize check. > ++ TList list(T_I32, 0x40000000); > ++ protocol->writeListBegin(list.elemType_, list.size_); > ++ protocol->writeListEnd(); > ++ BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); > ++ protocol->readListEnd(); > ++} > ++ > ++BOOST_AUTO_TEST_CASE(test_tthriftcompactprotocol_container_size_overflow) { > ++ std::shared_ptr<TConfiguration> config (new TConfiguration(1024)); > ++ std::shared_ptr<TMemoryBuffer> transport(new TMemoryBuffer(config)); > ++ std::shared_ptr<TCompactProtocol> protocol(new TCompactProtocol(transport)); > ++ > ++ uint32_t val = 0; > ++ TType elemType = apache::thrift::protocol::T_STOP; > ++ // 0x10000000 elements of min size 16 (UUID) require 4 GiB; the product wraps > ++ // to 0 in 32-bit math and used to slip past the MaxMessageSize check. > ++ TList list(T_UUID, 0x10000000); > ++ protocol->writeListBegin(list.elemType_, list.size_); > ++ protocol->writeListEnd(); > ++ BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); > ++ protocol->readListEnd(); > ++} > ++ > ++BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_container_size_overflow) { > ++ std::shared_ptr<TConfiguration> config (new TConfiguration(1024)); > ++ std::shared_ptr<TMemoryBuffer> transport(new TMemoryBuffer(config)); > ++ std::shared_ptr<TJSONProtocol> protocol(new TJSONProtocol(transport)); > ++ > ++ uint32_t val = 0; > ++ TType elemType = apache::thrift::protocol::T_STOP; > ++ // 0x10000000 elements of min size 16 (UUID) require 4 GiB; the product wraps > ++ // to 0 in 32-bit math and used to slip past the MaxMessageSize check. > ++ TList list(T_UUID, 0x10000000); > ++ protocol->writeListBegin(list.elemType_, list.size_); > ++ protocol->writeListEnd(); > ++ BOOST_CHECK_THROW(protocol->readListBegin(elemType, val), TTransportException); > ++ protocol->readListEnd(); > ++} > ++ > + BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) { > + std::shared_ptr<TConfiguration> config (new TConfiguration(MAX_MESSAGE_SIZE)); > + std::shared_ptr<TMemoryBuffer> transport(new TMemoryBuffer(config)); > 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 0128de8519..3717302086 100644 > --- a/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb > +++ b/meta-oe/recipes-connectivity/thrift/thrift_0.22.0.bb > @@ -17,6 +17,7 @@ SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \ > file://CVE-2026-58023.patch \ > file://CVE-2026-48144.patch \ > file://CVE-2026-58389.patch \ > + file://CVE-2026-55969.patch \ > " > SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5" > Ignore this, I will send a v2 removing the bloated changes section : )