* [meta-oe][wrynose][PATCH] thrift: fix CVE-2026-58662
@ 2026-09-01 9:07 Abhishek Bachiphale
2026-09-02 20:54 ` [oe] " Randy MacLeod
0 siblings, 1 reply; 3+ messages in thread
From: Abhishek Bachiphale @ 2026-09-01 9:07 UTC (permalink / raw)
To: openembedded-devel; +Cc: Abhishek.Bachiphale
Improper Validation of Specified Quantity in Input, Out-of-bounds Read
vulnerability in Apache Thrift C++ bindings. This issue affects Apache
Thrift: before 0.24.0.
Backport patch to fix CVE-2026-58662.
Reference:
[https://nvd.nist.gov/vuln/detail/cve-2026-58662]
Upstream Patch:
[https://github.com/apache/thrift/commit/f961cdb44249c293fcce6a840ffa1f7419fd88d0]
Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com>
---
.../thrift/thrift/CVE-2026-58662.patch | 120 ++++++++++++++++++
.../thrift/thrift_0.22.0.bb | 1 +
2 files changed, 121 insertions(+)
create mode 100644 meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
diff --git a/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
new file mode 100644
index 0000000000..03eaccb17a
--- /dev/null
+++ b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
@@ -0,0 +1,120 @@
+From b9fe622d3e3dd2e376fbb5ccf2acfbfaf498ddb1 Mon Sep 17 00:00:00 2001
+From: Javid Khan <dxbjavid@gmail.com>
+Date: Tue, 30 Jun 2026 16:34:47 +0200
+Subject: [PATCH] fix info-header string bound check in
+
+ THeaderTransport::readString Client: cpp Patch: Javid Khan
+ <dxbjavid@gmail.com>
+
+when reading the key/value info headers of a THeader frame, readString reads
+the length varint and then bounds it against the bytes left in the header
+section. the comparison uses ptr before it is moved past the varint, so the
+remaining count is overstated by the width of the length field, and a negative
+length (a varint with the high bit set) is not rejected at all. with a header
+section sized to fill the receive buffer, either case lets a wire-supplied
+length exceed the header bytes that are actually present.
+
+bound the length against the position that follows the varint, reject a
+negative length, and only advance ptr once those checks pass so the documented
+advance-on-success behaviour still holds. regression tests covering both the
+oversized and the negative length are added to ThrifttReadCheckTests.
+
+This closes #3610
+
+CVE: CVE-2026-58662
+Upstream-Status: Backport [https://github.com/apache/thrift/commit/f961cdb44249c293fcce6a840ffa1f7419fd88d0]
+Signed-off-by: Abhishek Bachiphale <Abhishek.Bachiphale@windriver.com>
+---
+ .../src/thrift/transport/THeaderTransport.cpp | 12 +++--
+ lib/cpp/test/ThrifttReadCheckTests.cpp | 52 +++++++++++++++++++
+ 2 files changed, 60 insertions(+), 4 deletions(-)
+
+diff --git a/lib/cpp/src/thrift/transport/THeaderTransport.cpp b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
+index 117c8ed..ba2fd5d 100644
+--- a/lib/cpp/src/thrift/transport/THeaderTransport.cpp
++++ b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
+@@ -183,13 +183,17 @@ void THeaderTransport::readString(uint8_t*& ptr,
+ int32_t strLen;
+
+ uint32_t bytes = readVarint32(ptr, &strLen, headerBoundary);
+- if (strLen > headerBoundary - ptr) {
++ // Bound the string against the header bytes that remain once the length varint
++ // itself is accounted for, and reject a negative length so the size_t
++ // conversion in assign() below stays within the buffer. ptr is only advanced
++ // once these checks pass, keeping the "advances on success" contract above.
++ uint8_t* strStart = ptr + bytes;
++ if (strLen < 0 || strLen > headerBoundary - strStart) {
+ throw TTransportException(TTransportException::CORRUPTED_DATA,
+ "Info header length exceeds header size");
+ }
+- ptr += bytes;
+- str.assign(reinterpret_cast<const char*>(ptr), strLen);
+- ptr += strLen;
++ str.assign(reinterpret_cast<const char*>(strStart), strLen);
++ ptr = strStart + strLen;
+ }
+
+ void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) {
+diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp
+index 9632861..2a92160 100644
+--- a/lib/cpp/test/ThrifttReadCheckTests.cpp
++++ b/lib/cpp/test/ThrifttReadCheckTests.cpp
+@@ -270,6 +270,58 @@ BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) {
+ protocol->readMapEnd();
+ }
+
++BOOST_AUTO_TEST_CASE(test_theadertransport_info_header_string_overrun) {
++ using apache::thrift::transport::THeaderTransport;
++ // Header-format frame whose info-header key length (4) does not fit within the
++ // header bytes that remain once the length varint itself is accounted for. The
++ // header section (8 bytes) exactly fills the frame, so the boundary sits at the
++ // buffer end; the key length has to be bounded against the remaining bytes and
++ // rejected.
++ uint8_t frame[] = {
++ 0x00, 0x00, 0x00, 0x12, // frame length = 18
++ 0x0F, 0xFF, 0x00, 0x00, // header magic
++ 0x00, 0x00, 0x00, 0x00, // seqId
++ 0x00, 0x02, // header size field (2 -> 8 bytes)
++ 0x02, // protocol id varint
++ 0x00, // num transforms = 0
++ 0x01, // info id = key/value
++ 0x01, // one key/value pair
++ 0x04, // key length = 4 (only 3 bytes remain)
++ 0xAA, 0xBB, 0xCC // key bytes
++ };
++ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(frame, sizeof(frame)));
++ std::shared_ptr<THeaderTransport> trans(new THeaderTransport(buffer));
++
++ uint8_t out[1];
++ BOOST_CHECK_THROW(trans->read(out, sizeof(out)), TTransportException);
++}
++
++BOOST_AUTO_TEST_CASE(test_theadertransport_info_header_string_negative_length) {
++ using apache::thrift::transport::THeaderTransport;
++ // Header-format frame whose info-header key length varint decodes to a
++ // negative int32 (top bit set). The length has to be treated as out of range
++ // rather than converted to a size_t, so the read is rejected instead of
++ // reaching the string assignment. The three trailing bytes only pad the
++ // header section out to its declared size and are never reached.
++ uint8_t frame[] = {
++ 0x00, 0x00, 0x00, 0x16, // frame length = 22
++ 0x0F, 0xFF, 0x00, 0x00, // header magic
++ 0x00, 0x00, 0x00, 0x00, // seqId
++ 0x00, 0x03, // header size field (3 -> 12 bytes)
++ 0x02, // protocol id varint
++ 0x00, // num transforms = 0
++ 0x01, // info id = key/value
++ 0x01, // one key/value pair
++ 0x80, 0x80, 0x80, 0x80, 0x08, // key length varint = INT32_MIN
++ 0x00, 0x00, 0x00 // padding to fill the header section
++ };
++ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(frame, sizeof(frame)));
++ std::shared_ptr<THeaderTransport> trans(new THeaderTransport(buffer));
++
++ uint8_t out[1];
++ BOOST_CHECK_THROW(trans->read(out, sizeof(out)), TTransportException);
++}
++
+ BOOST_AUTO_TEST_CASE(test_theadertransport_zlib_roundtrip) {
+ using apache::thrift::transport::THeaderTransport;
+ // A run of identical bytes compresses to far fewer bytes than it occupies
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..949ffc3e70 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-58662.patch \
"
SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"
--
2.40.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [oe] [meta-oe][wrynose][PATCH] thrift: fix CVE-2026-58662
2026-09-01 9:07 [meta-oe][wrynose][PATCH] thrift: fix CVE-2026-58662 Abhishek Bachiphale
@ 2026-09-02 20:54 ` Randy MacLeod
2026-09-02 21:01 ` Randy MacLeod
0 siblings, 1 reply; 3+ messages in thread
From: Randy MacLeod @ 2026-09-02 20:54 UTC (permalink / raw)
To: anuj.mittal; +Cc: openembedded-devel, abhishek.bachiphale
[-- Attachment #1: Type: text/plain, Size: 8694 bytes --]
Anuj,
It seems like you missed this one.
It still applies to wrynose HEAD for me and seems like a good backport.
../Randy
On 2026-09-01 05:07, Abhishek Bachiphale via lists.openembedded.org wrote:
> Improper Validation of Specified Quantity in Input, Out-of-bounds Read
> vulnerability in Apache Thrift C++ bindings. This issue affects Apache
> Thrift: before 0.24.0.
>
> Backport patch to fix CVE-2026-58662.
>
> Reference:
> [https://nvd.nist.gov/vuln/detail/cve-2026-58662]
>
> Upstream Patch:
> [https://github.com/apache/thrift/commit/f961cdb44249c293fcce6a840ffa1f7419fd88d0]
>
> Signed-off-by: Abhishek Bachiphale<Abhishek.Bachiphale@windriver.com>
> ---
> .../thrift/thrift/CVE-2026-58662.patch | 120 ++++++++++++++++++
> .../thrift/thrift_0.22.0.bb | 1 +
> 2 files changed, 121 insertions(+)
> create mode 100644 meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
>
> diff --git a/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
> new file mode 100644
> index 0000000000..03eaccb17a
> --- /dev/null
> +++ b/meta-oe/recipes-connectivity/thrift/thrift/CVE-2026-58662.patch
> @@ -0,0 +1,120 @@
> +From b9fe622d3e3dd2e376fbb5ccf2acfbfaf498ddb1 Mon Sep 17 00:00:00 2001
> +From: Javid Khan<dxbjavid@gmail.com>
> +Date: Tue, 30 Jun 2026 16:34:47 +0200
> +Subject: [PATCH] fix info-header string bound check in
> +
> + THeaderTransport::readString Client: cpp Patch: Javid Khan
> +<dxbjavid@gmail.com>
> +
> +when reading the key/value info headers of a THeader frame, readString reads
> +the length varint and then bounds it against the bytes left in the header
> +section. the comparison uses ptr before it is moved past the varint, so the
> +remaining count is overstated by the width of the length field, and a negative
> +length (a varint with the high bit set) is not rejected at all. with a header
> +section sized to fill the receive buffer, either case lets a wire-supplied
> +length exceed the header bytes that are actually present.
> +
> +bound the length against the position that follows the varint, reject a
> +negative length, and only advance ptr once those checks pass so the documented
> +advance-on-success behaviour still holds. regression tests covering both the
> +oversized and the negative length are added to ThrifttReadCheckTests.
> +
> +This closes #3610
> +
> +CVE: CVE-2026-58662
> +Upstream-Status: Backport [https://github.com/apache/thrift/commit/f961cdb44249c293fcce6a840ffa1f7419fd88d0]
> +Signed-off-by: Abhishek Bachiphale<Abhishek.Bachiphale@windriver.com>
> +---
> + .../src/thrift/transport/THeaderTransport.cpp | 12 +++--
> + lib/cpp/test/ThrifttReadCheckTests.cpp | 52 +++++++++++++++++++
> + 2 files changed, 60 insertions(+), 4 deletions(-)
> +
> +diff --git a/lib/cpp/src/thrift/transport/THeaderTransport.cpp b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
> +index 117c8ed..ba2fd5d 100644
> +--- a/lib/cpp/src/thrift/transport/THeaderTransport.cpp
> ++++ b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
> +@@ -183,13 +183,17 @@ void THeaderTransport::readString(uint8_t*& ptr,
> + int32_t strLen;
> +
> + uint32_t bytes = readVarint32(ptr, &strLen, headerBoundary);
> +- if (strLen > headerBoundary - ptr) {
> ++ // Bound the string against the header bytes that remain once the length varint
> ++ // itself is accounted for, and reject a negative length so the size_t
> ++ // conversion in assign() below stays within the buffer. ptr is only advanced
> ++ // once these checks pass, keeping the "advances on success" contract above.
> ++ uint8_t* strStart = ptr + bytes;
> ++ if (strLen < 0 || strLen > headerBoundary - strStart) {
> + throw TTransportException(TTransportException::CORRUPTED_DATA,
> + "Info header length exceeds header size");
> + }
> +- ptr += bytes;
> +- str.assign(reinterpret_cast<const char*>(ptr), strLen);
> +- ptr += strLen;
> ++ str.assign(reinterpret_cast<const char*>(strStart), strLen);
> ++ ptr = strStart + strLen;
> + }
> +
> + void THeaderTransport::readHeaderFormat(uint16_t headerSize, uint32_t sz) {
> +diff --git a/lib/cpp/test/ThrifttReadCheckTests.cpp b/lib/cpp/test/ThrifttReadCheckTests.cpp
> +index 9632861..2a92160 100644
> +--- a/lib/cpp/test/ThrifttReadCheckTests.cpp
> ++++ b/lib/cpp/test/ThrifttReadCheckTests.cpp
> +@@ -270,6 +270,58 @@ BOOST_AUTO_TEST_CASE(test_tthriftjsonprotocol_read_check_exception) {
> + protocol->readMapEnd();
> + }
> +
> ++BOOST_AUTO_TEST_CASE(test_theadertransport_info_header_string_overrun) {
> ++ using apache::thrift::transport::THeaderTransport;
> ++ // Header-format frame whose info-header key length (4) does not fit within the
> ++ // header bytes that remain once the length varint itself is accounted for. The
> ++ // header section (8 bytes) exactly fills the frame, so the boundary sits at the
> ++ // buffer end; the key length has to be bounded against the remaining bytes and
> ++ // rejected.
> ++ uint8_t frame[] = {
> ++ 0x00, 0x00, 0x00, 0x12, // frame length = 18
> ++ 0x0F, 0xFF, 0x00, 0x00, // header magic
> ++ 0x00, 0x00, 0x00, 0x00, // seqId
> ++ 0x00, 0x02, // header size field (2 -> 8 bytes)
> ++ 0x02, // protocol id varint
> ++ 0x00, // num transforms = 0
> ++ 0x01, // info id = key/value
> ++ 0x01, // one key/value pair
> ++ 0x04, // key length = 4 (only 3 bytes remain)
> ++ 0xAA, 0xBB, 0xCC // key bytes
> ++ };
> ++ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(frame, sizeof(frame)));
> ++ std::shared_ptr<THeaderTransport> trans(new THeaderTransport(buffer));
> ++
> ++ uint8_t out[1];
> ++ BOOST_CHECK_THROW(trans->read(out, sizeof(out)), TTransportException);
> ++}
> ++
> ++BOOST_AUTO_TEST_CASE(test_theadertransport_info_header_string_negative_length) {
> ++ using apache::thrift::transport::THeaderTransport;
> ++ // Header-format frame whose info-header key length varint decodes to a
> ++ // negative int32 (top bit set). The length has to be treated as out of range
> ++ // rather than converted to a size_t, so the read is rejected instead of
> ++ // reaching the string assignment. The three trailing bytes only pad the
> ++ // header section out to its declared size and are never reached.
> ++ uint8_t frame[] = {
> ++ 0x00, 0x00, 0x00, 0x16, // frame length = 22
> ++ 0x0F, 0xFF, 0x00, 0x00, // header magic
> ++ 0x00, 0x00, 0x00, 0x00, // seqId
> ++ 0x00, 0x03, // header size field (3 -> 12 bytes)
> ++ 0x02, // protocol id varint
> ++ 0x00, // num transforms = 0
> ++ 0x01, // info id = key/value
> ++ 0x01, // one key/value pair
> ++ 0x80, 0x80, 0x80, 0x80, 0x08, // key length varint = INT32_MIN
> ++ 0x00, 0x00, 0x00 // padding to fill the header section
> ++ };
> ++ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(frame, sizeof(frame)));
> ++ std::shared_ptr<THeaderTransport> trans(new THeaderTransport(buffer));
> ++
> ++ uint8_t out[1];
> ++ BOOST_CHECK_THROW(trans->read(out, sizeof(out)), TTransportException);
> ++}
> ++
> + BOOST_AUTO_TEST_CASE(test_theadertransport_zlib_roundtrip) {
> + using apache::thrift::transport::THeaderTransport;
> + // A run of identical bytes compresses to far fewer bytes than it occupies
> 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..949ffc3e70 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-58662.patch \ "
> SRC_URI[sha256sum] = "794a0e455787960d9f27ab92c38e34da27e8deeda7a5db0e59dc64a00df8a1e5"
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#129627):https://lists.openembedded.org/g/openembedded-devel/message/129627
> Mute This Topic:https://lists.openembedded.org/mt/121028875/3616765
> Group Owner:openembedded-devel+owner@lists.openembedded.org
> Unsubscribe:https://lists.openembedded.org/g/openembedded-devel/unsub [randy.macleod@windriver.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
--
# Randy MacLeod
# Wind River Linux
[-- Attachment #2: Type: text/html, Size: 10762 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-02 21:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 9:07 [meta-oe][wrynose][PATCH] thrift: fix CVE-2026-58662 Abhishek Bachiphale
2026-09-02 20:54 ` [oe] " Randy MacLeod
2026-09-02 21:01 ` Randy MacLeod
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.