fix: reject malformed network input in parsers (#1340)

## Summary
- validate handshake metadata field lengths before fixed-size reads
- reject truncated multicast advertisements before slicing the hash
payload
- add regression tests for malformed and truncated input

## Why
Both parsers currently trust length information from the incoming
payload a bit too much. Malformed network input can reach fixed-size
reads/slices and panic the process instead of being rejected cleanly.

## Testing
- go test ./...
This commit is contained in:
Alex Melan
2026-04-11 14:04:12 +03:00
committed by GitHub
parent 2527290bfd
commit bc72b106b7
4 changed files with 126 additions and 11 deletions

View File

@@ -118,26 +118,41 @@ func (m *version_metadata) decode(r io.Reader, password []byte) error {
for len(bs) >= 4 {
op := binary.BigEndian.Uint16(bs[:2])
oplen := binary.BigEndian.Uint16(bs[2:4])
if bs = bs[4:]; len(bs) < int(oplen) {
break
oplen := int(binary.BigEndian.Uint16(bs[2:4]))
if bs = bs[4:]; len(bs) < oplen {
return ErrHandshakeInvalidLength
}
field := bs[:oplen]
switch op {
case metaVersionMajor:
m.majorVer = binary.BigEndian.Uint16(bs[:2])
if len(field) != 2 {
return ErrHandshakeInvalidLength
}
m.majorVer = binary.BigEndian.Uint16(field)
case metaVersionMinor:
m.minorVer = binary.BigEndian.Uint16(bs[:2])
if len(field) != 2 {
return ErrHandshakeInvalidLength
}
m.minorVer = binary.BigEndian.Uint16(field)
case metaPublicKey:
m.publicKey = make(ed25519.PublicKey, ed25519.PublicKeySize)
copy(m.publicKey, bs[:ed25519.PublicKeySize])
if len(field) != ed25519.PublicKeySize {
return ErrHandshakeInvalidLength
}
m.publicKey = append(m.publicKey[:0], field...)
case metaPriority:
m.priority = bs[0]
if len(field) != 1 {
return ErrHandshakeInvalidLength
}
m.priority = field[0]
}
bs = bs[oplen:]
}
if len(bs) != 0 {
return ErrHandshakeInvalidLength
}
hasher, err := blake2b.New512(password)
if err != nil {