Visitar URL original
pgtype: bound hstore binary decode against malicious server input · jackc/pgx@ff27b5b · GitHub
Skip to content

Commit ff27b5b

Browse files
sean-jackc
authored andcommitted
pgtype: bound hstore binary decode against malicious server input
Two issues in scanPlanBinaryHstoreToHstoreScanner.Scan: pairCount was read as int32 from the wire, checked only for < 0, then passed directly to make(Hstore, pairCount) and make([]string, pairCount), allowing a server-claimed 0x3FFFFFFF count to allocate ~16+ GiB from a 4-byte payload; and the per-value branch sliced src[rp:rp+valueLen] without the remaining-bytes check that keys already had, allowing a crafted body to trigger an index-out-of-range panic. Bound pairCount by len(src[rp:]) / 8 (each pair needs at minimum two int32 length headers) and check remaining bytes before slicing the value. Reported by CrowdStrike (F05).
1 parent a6002e1 commit ff27b5b

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

‎pgtype/hstore.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(src []byte, dst any) error {
198198
if pairCount < 0 {
199199
return fmt.Errorf("hstore invalid pair count: %d", pairCount)
200200
}
201+
// Each pair carries at minimum two int32 length headers (key, value), so pairCount cannot
202+
// exceed the remaining bytes / 8. This bounds the up-front make() against a malicious server
203+
// claiming a huge pair count in a small message.
204+
if maxPairs := len(src[rp:]) / (2 * uint32Len); pairCount > maxPairs {
205+
return fmt.Errorf("hstore invalid pair count %d for %d remaining bytes", pairCount, len(src[rp:]))
206+
}
201207

202208
hstore := make(Hstore, pairCount)
203209
// one allocation for all *string, rather than one per string, just like text parsing
@@ -226,6 +232,9 @@ func (scanPlanBinaryHstoreToHstoreScanner) Scan(src []byte, dst any) error {
226232
rp += 4
227233

228234
if valueLen >= 0 {
235+
if len(src[rp:]) < valueLen {
236+
return fmt.Errorf("hstore incomplete %v", src)
237+
}
229238
valueStrings[i] = string(src[rp : rp+valueLen])
230239
rp += valueLen
231240

0 commit comments

Comments
 (0)