From 761cafecbafb449bb2f83edff4a93623e23d3e59 Mon Sep 17 00:00:00 2001 From: neha khan Date: Thu, 22 Oct 2026 21:59:45 +0530 Subject: [PATCH 1/2] NO-JIRA: Fix 32-bit length overflow in AMQP consumer bounds checks --- c/src/core/consumers.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/core/consumers.h b/c/src/core/consumers.h index a4fffa4f1..f8340505d 100644 --- a/c/src/core/consumers.h +++ b/c/src/core/consumers.h @@ -129,7 +129,7 @@ static inline bool pni_consumer_readv8(pni_consumer_t *consumer, pn_bytes_t* byt static inline bool pni_consumer_readv32(pni_consumer_t *consumer, pn_bytes_t* bytes){ uint32_t size; if (!pni_consumer_readf32(consumer, &size)) return false; - if (consumer->position+size > consumer->size) { + if (size > consumer->size - consumer->position) { consumer->position = consumer->size; return false; } @@ -194,7 +194,7 @@ static inline bool pni_consumer_read_value_not_described(pni_consumer_t* consume case 0xF: { uint32_t size; if (!pni_consumer_readf32(consumer, &size)) return false; - if (consumer->position+size > consumer->size) break; + if (size > consumer->size - consumer->position) break; *value = (pn_bytes_t){.size=size,.start=(const char *)consumer->output_start+consumer->position}; consumer->position += size; return true; From 8c2eec2ee4a5ff52878d51923da0892b6bedebf1 Mon Sep 17 00:00:00 2001 From: neha khan Date: Fri, 23 Oct 2026 19:36:21 +0530 Subject: [PATCH 2/2] NO-JIRA: add regression test for oversized str32 length in open frame --- c/tests/connection_driver_test.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/c/tests/connection_driver_test.cpp b/c/tests/connection_driver_test.cpp index ff1b597c0..a98140c89 100644 --- a/c/tests/connection_driver_test.cpp +++ b/c/tests/connection_driver_test.cpp @@ -618,3 +618,30 @@ TEST_CASE("driver_empty_last_frame") { cond_empty()); CHECK_THAT(*pn_connection_condition(d.server.connection), cond_empty()); } + +/* A str32 length near UINT32_MAX must not pass the consumer bounds check. + position+size wrapped on a 32-bit size_t and the oversized string was accepted. +*/ +TEST_CASE("driver_open_oversized_str32") { + pn_connection_driver_t d; + pn_connection_driver_init(&d, NULL, NULL); + pn_transport_set_server(d.transport); + + const char frame[] = + "AMQP\x00\x01\x00\x00" + "\x00\x00\x00\x17\x02\x00\x00\x00" /* frame header: size 23, doff 2, AMQP, channel 0 */ + "\x00\x53\x10" /* open performative */ + "\xc0\x0a\x01" /* list8, size 10, count 1 */ + "\xb1\xff\xff\xff\xff" /* container-id: str32 claiming 0xFFFFFFFF bytes */ + "AAAA"; + size_t len = sizeof(frame) - 1; + pn_rwbytes_t buf = pn_connection_driver_read_buffer(&d); + REQUIRE(buf.size >= len); + memcpy(buf.start, frame, len); + pn_connection_driver_read_done(&d, len); + while (pn_connection_driver_next_event(&d)) + ; + + CHECK(pn_connection_remote_container(d.connection) == NULL); + pn_connection_driver_destroy(&d); +}