From 8fa9fae99ebbb700abf8e74c40d0f9a9085d9674 Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Mon, 23 Mar 2026 23:42:10 +0530 Subject: [PATCH 1/4] fixed .net test issue for opensuse 16 and sles 16 --- .github/workflows/validate-linux-packages-reuse.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate-linux-packages-reuse.yml b/.github/workflows/validate-linux-packages-reuse.yml index 3eea817524..e62503b9de 100644 --- a/.github/workflows/validate-linux-packages-reuse.yml +++ b/.github/workflows/validate-linux-packages-reuse.yml @@ -609,7 +609,8 @@ jobs: run: | docker exec ${{ steps.container.outputs.name }} sh -c ' # Find and run the self-contained QuicHello executable - EXE=$(find /dotnet -maxdepth 1 -name "QuicHello*" -type f ! -name "*.dll" ! -name "*.pdb" ! -name "*.json" 2>/dev/null | head -1) + # Use ls+grep instead of find negation, which is unreliable on BusyBox (OpenSUSE/SLES) + EXE=$(ls /dotnet/QuicHello* 2>/dev/null | grep -v -e "\.dll$" -e "\.pdb$" -e "\.json$" | head -1) if [ -z "$EXE" ]; then echo "ERROR: QuicHello executable not found" ls -la /dotnet/ From ad97fa2f0a2f4886ae395f5c278c6465b9c959d7 Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Thu, 13 Aug 2026 18:46:00 +0530 Subject: [PATCH 2/4] Modified recvbuffer and virtual buffer autotuning logic --- src/core/recv_buffer.c | 5 +++-- src/core/stream_recv.c | 9 +++++++-- src/core/unittest/RecvBufferTest.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/core/recv_buffer.c b/src/core/recv_buffer.c index 659d20978b..1b5c5fd1e9 100644 --- a/src/core/recv_buffer.c +++ b/src/core/recv_buffer.c @@ -762,11 +762,12 @@ QuicRecvBufferWrite( // QUIC_RECV_CHUNK* LastChunk = CXPLAT_CONTAINING_RECORD(RecvBuffer->Chunks.Blink, QUIC_RECV_CHUNK, Link); - uint32_t NewBufferLength = LastChunk->AllocLength << 1; + uint64_t NewBufferLength = (uint64_t)LastChunk->AllocLength << 1; while (AbsoluteLength > RecvBuffer->BaseOffset + NewBufferLength) { NewBufferLength <<= 1; } - if (!QuicRecvBufferResize(RecvBuffer, NewBufferLength)) { + if (NewBufferLength > UINT32_MAX || + !QuicRecvBufferResize(RecvBuffer, (uint32_t)NewBufferLength)) { *BufferSizeNeeded = AbsoluteLength - (RecvBuffer->BaseOffset + AllocLength); return QUIC_STATUS_OUT_OF_MEMORY; } diff --git a/src/core/stream_recv.c b/src/core/stream_recv.c index 80814a4830..d13317d7a9 100644 --- a/src/core/stream_recv.c +++ b/src/core/stream_recv.c @@ -804,8 +804,13 @@ QuicStreamOnBytesDelivered( // // Limit stream FC window growth by the connection FC window size. // + const uint32_t MaxVirtualBufferLength = + Stream->RecvBuffer.RecvMode == QUIC_RECV_BUF_MODE_APP_OWNED ? + UINT32_MAX : + 0x80000000U; if (Stream->RecvBuffer.VirtualBufferLength != 0 && - Stream->RecvBuffer.VirtualBufferLength < Stream->Connection->Settings.ConnFlowControlWindow) { + Stream->RecvBuffer.VirtualBufferLength < Stream->Connection->Settings.ConnFlowControlWindow && + Stream->RecvBuffer.VirtualBufferLength < MaxVirtualBufferLength) { uint64_t TimeThreshold = ((Stream->RecvWindowBytesDelivered * Stream->Connection->Paths[0].SmoothedRtt) / RecvBufferDrainThreshold); if (CxPlatTimeDiff64(Stream->RecvWindowLastUpdate, TimeNow) <= TimeThreshold) { @@ -830,7 +835,7 @@ QuicStreamOnBytesDelivered( // uint64_t NewLength = (uint64_t)Stream->RecvBuffer.VirtualBufferLength * 2; - NewLength = CXPLAT_MIN(NewLength, UINT32_MAX); + NewLength = CXPLAT_MIN(NewLength, MaxVirtualBufferLength); QuicRecvBufferIncreaseVirtualBufferLength( &Stream->RecvBuffer, diff --git a/src/core/unittest/RecvBufferTest.cpp b/src/core/unittest/RecvBufferTest.cpp index 90ecfc8e9c..3d96fb2413 100644 --- a/src/core/unittest/RecvBufferTest.cpp +++ b/src/core/unittest/RecvBufferTest.cpp @@ -547,6 +547,30 @@ TEST_P(WithMode, WriteTooMuch2) ASSERT_FALSE(RecvBuf.HasUnreadData()); } +TEST(RecvBufferGrowthTest, WriteGrowthOverflow) +{ + RecvBuffer RecvBuf; + ASSERT_EQ(QUIC_STATUS_SUCCESS, RecvBuf.Initialize(QUIC_RECV_BUF_MODE_SINGLE)); + + RecvBuf.IncreaseVirtualBufferLength(UINT32_MAX); + + uint8_t WriteBuffer = 0; + uint64_t QuotaConsumed = 0; + uint64_t BufferSizeNeeded = 0; + BOOLEAN NewDataReady = FALSE; + ASSERT_EQ( + QUIC_STATUS_OUT_OF_MEMORY, + QuicRecvBufferWrite( + &RecvBuf.RecvBuf, + 0x80000000U, + sizeof(WriteBuffer), + &WriteBuffer, + UINT32_MAX, + &QuotaConsumed, + &NewDataReady, + &BufferSizeNeeded)); +} + TEST_P(WithMode, WriteWhilePendingRead) { RecvBuffer RecvBuf; From 3acb4fc873a1e12675d9a002e4cdb77e86d284a4 Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Thu, 13 Aug 2026 18:59:10 +0530 Subject: [PATCH 3/4] Recv Buffer max Vritual length named constant --- src/core/recv_buffer.h | 7 +++++++ src/core/stream_recv.c | 2 +- src/core/unittest/RecvBufferTest.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/recv_buffer.h b/src/core/recv_buffer.h index 091474c9d6..51610e591c 100644 --- a/src/core/recv_buffer.h +++ b/src/core/recv_buffer.h @@ -17,6 +17,13 @@ typedef enum QUIC_RECV_BUF_MODE { // that may indicate up to the number of provided buffers. } QUIC_RECV_BUF_MODE; +// +// The maximum virtual buffer length for an internally-managed receive buffer. +// This is the largest power of two that fits in a uint32_t, ensuring the buffer +// doubling logic never overflows. +// +#define QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH 0x80000000U + // // Represents a single contiguous range of bytes. // diff --git a/src/core/stream_recv.c b/src/core/stream_recv.c index d13317d7a9..b1a6c47d72 100644 --- a/src/core/stream_recv.c +++ b/src/core/stream_recv.c @@ -807,7 +807,7 @@ QuicStreamOnBytesDelivered( const uint32_t MaxVirtualBufferLength = Stream->RecvBuffer.RecvMode == QUIC_RECV_BUF_MODE_APP_OWNED ? UINT32_MAX : - 0x80000000U; + QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH; if (Stream->RecvBuffer.VirtualBufferLength != 0 && Stream->RecvBuffer.VirtualBufferLength < Stream->Connection->Settings.ConnFlowControlWindow && Stream->RecvBuffer.VirtualBufferLength < MaxVirtualBufferLength) { diff --git a/src/core/unittest/RecvBufferTest.cpp b/src/core/unittest/RecvBufferTest.cpp index 3d96fb2413..af24050a8d 100644 --- a/src/core/unittest/RecvBufferTest.cpp +++ b/src/core/unittest/RecvBufferTest.cpp @@ -562,7 +562,7 @@ TEST(RecvBufferGrowthTest, WriteGrowthOverflow) QUIC_STATUS_OUT_OF_MEMORY, QuicRecvBufferWrite( &RecvBuf.RecvBuf, - 0x80000000U, + QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH, sizeof(WriteBuffer), &WriteBuffer, UINT32_MAX, From 070a7c9b7aa5a2d941a8e90b9b5e54b665af6dc7 Mon Sep 17 00:00:00 2001 From: Gaurav Singh Date: Fri, 14 Aug 2026 00:07:15 +0530 Subject: [PATCH 4/4] removed constant --- src/core/recv_buffer.h | 7 ------- src/core/stream_recv.c | 2 +- src/core/unittest/RecvBufferTest.cpp | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/core/recv_buffer.h b/src/core/recv_buffer.h index 51610e591c..091474c9d6 100644 --- a/src/core/recv_buffer.h +++ b/src/core/recv_buffer.h @@ -17,13 +17,6 @@ typedef enum QUIC_RECV_BUF_MODE { // that may indicate up to the number of provided buffers. } QUIC_RECV_BUF_MODE; -// -// The maximum virtual buffer length for an internally-managed receive buffer. -// This is the largest power of two that fits in a uint32_t, ensuring the buffer -// doubling logic never overflows. -// -#define QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH 0x80000000U - // // Represents a single contiguous range of bytes. // diff --git a/src/core/stream_recv.c b/src/core/stream_recv.c index b1a6c47d72..d13317d7a9 100644 --- a/src/core/stream_recv.c +++ b/src/core/stream_recv.c @@ -807,7 +807,7 @@ QuicStreamOnBytesDelivered( const uint32_t MaxVirtualBufferLength = Stream->RecvBuffer.RecvMode == QUIC_RECV_BUF_MODE_APP_OWNED ? UINT32_MAX : - QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH; + 0x80000000U; if (Stream->RecvBuffer.VirtualBufferLength != 0 && Stream->RecvBuffer.VirtualBufferLength < Stream->Connection->Settings.ConnFlowControlWindow && Stream->RecvBuffer.VirtualBufferLength < MaxVirtualBufferLength) { diff --git a/src/core/unittest/RecvBufferTest.cpp b/src/core/unittest/RecvBufferTest.cpp index af24050a8d..3d96fb2413 100644 --- a/src/core/unittest/RecvBufferTest.cpp +++ b/src/core/unittest/RecvBufferTest.cpp @@ -562,7 +562,7 @@ TEST(RecvBufferGrowthTest, WriteGrowthOverflow) QUIC_STATUS_OUT_OF_MEMORY, QuicRecvBufferWrite( &RecvBuf.RecvBuf, - QUIC_RECV_BUFFER_MAX_VIRTUAL_LENGTH, + 0x80000000U, sizeof(WriteBuffer), &WriteBuffer, UINT32_MAX,