Acknowledgement
Description
DataRow.Decode in github.com/jackc/pgproto3/v2 panics with
slice bounds out of range when a server sends a DataRow message
containing a field length that is a negative int32 value (any uint32
in the range 0x80000000–0xFFFFFFFE).
The field length is read correctly as a signed int32:
msgSize := int(int32(binary.BigEndian.Uint32(src[rp:])))
However, the subsequent bounds check:
if len(src[rp:]) < msgSize { ... }
is vacuously false when msgSize is negative, because len() always
returns a non-negative integer. The check is bypassed entirely, and the
slice expression:
dst.Values[i] = src[rp : rp+msgSize : rp+msgSize]
panics at runtime. The null sentinel -1 is handled correctly, but the
remaining ~2 billion negative values (−2 through −2,147,483,648) are not
guarded.
A malicious or compromised PostgreSQL server can crash any Go application
using this library by sending a single crafted DataRow message.
Affected Modules, Packages, Versions and Symbols
Module: github.com/jackc/pgproto3/v2
Package: github.com/jackc/pgproto3/v2
Versions:
- Introduced: 2.0.0
- Fixed: not yet fixed
Symbols:
- DataRow.Decode
CVE/GHSA ID
No response
Fix Commit or Pull Request
No response
References
Additional information
The same pattern was previously identified and correctly patched in a downstream consumer of this library - the fix there uses the guard
|| valueLen < 0 alongside the existing bounds check. That fix was
never backported to the upstream pgproto3/v2 library.
CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H — 7.5 High
CWE-129: Improper Validation of Array Index