From 82eab5c5b76e452f963209c8fe88f79a4fd6e561 Mon Sep 17 00:00:00 2001 From: Max Kotliar Date: Wed, 11 Mar 2026 12:42:49 +0200 Subject: [PATCH] lib/encoding: fix integer overflow in UnmarshalBytes (#10629) Poison varint: MaxUint64 encoded as varint (0xFFFFFFFFFFFFFFFF). The bounds check uint64(nSize)+n overflows to 9, bypassing the guard. Then int(MaxUint64)=-1 makes src[10:9] which panics. --- lib/encoding/int.go | 2 +- lib/encoding/int_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/encoding/int.go b/lib/encoding/int.go index 794d177609..7a745d1075 100644 --- a/lib/encoding/int.go +++ b/lib/encoding/int.go @@ -517,7 +517,7 @@ func UnmarshalBytes(src []byte) ([]byte, int) { if nSize <= 0 { return nil, 0 } - if uint64(nSize)+n > uint64(len(src)) { + if n > uint64(len(src)-nSize) { return nil, 0 } start := nSize diff --git a/lib/encoding/int_test.go b/lib/encoding/int_test.go index a3c30120b3..4bc73979c9 100644 --- a/lib/encoding/int_test.go +++ b/lib/encoding/int_test.go @@ -295,6 +295,14 @@ func testMarshalUnmarshalVarUint64(t *testing.T, u uint64) { } } +func TestUnmarshalBytesOverflow(t *testing.T) { + poisonVarint := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01} + result, nSize := UnmarshalBytes(poisonVarint) + if nSize > 0 || result != nil { + t.Fatalf("expected error from overflow input, got nSize=%d result=%x", nSize, result) + } +} + func TestMarshalUnmarshalBytes(t *testing.T) { testMarshalUnmarshalBytes(t, "") testMarshalUnmarshalBytes(t, "x")