mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2026-05-21 21:36:30 +03:00
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:
@@ -26,14 +26,18 @@ func (m *multicastAdvertisement) MarshalBinary() ([]byte, error) {
|
||||
}
|
||||
|
||||
func (m *multicastAdvertisement) UnmarshalBinary(b []byte) error {
|
||||
if len(b) < ed25519.PublicKeySize+8 {
|
||||
const headerLen = ed25519.PublicKeySize + 8
|
||||
if len(b) < headerLen {
|
||||
return fmt.Errorf("invalid multicast beacon")
|
||||
}
|
||||
m.MajorVersion = binary.BigEndian.Uint16(b[0:2])
|
||||
m.MinorVersion = binary.BigEndian.Uint16(b[2:4])
|
||||
m.PublicKey = append(m.PublicKey[:0], b[4:4+ed25519.PublicKeySize]...)
|
||||
m.Port = binary.BigEndian.Uint16(b[4+ed25519.PublicKeySize : 6+ed25519.PublicKeySize])
|
||||
dl := binary.BigEndian.Uint16(b[6+ed25519.PublicKeySize : 8+ed25519.PublicKeySize])
|
||||
m.Hash = append(m.Hash[:0], b[8+ed25519.PublicKeySize:8+ed25519.PublicKeySize+dl]...)
|
||||
dl := int(binary.BigEndian.Uint16(b[6+ed25519.PublicKeySize : 8+ed25519.PublicKeySize]))
|
||||
if len(b) < headerLen+dl {
|
||||
return fmt.Errorf("invalid multicast beacon")
|
||||
}
|
||||
m.Hash = append(m.Hash[:0], b[headerLen:headerLen+dl]...)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package multicast
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@@ -36,3 +37,20 @@ func TestMulticastAdvertisementRoundTrip(t *testing.T) {
|
||||
t.Fatalf("differences found after round-trip")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulticastAdvertisementRejectsTruncatedHash(t *testing.T) {
|
||||
pk, _, err := ed25519.GenerateKey(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b := make([]byte, ed25519.PublicKeySize+8)
|
||||
copy(b[4:], pk)
|
||||
binary.BigEndian.PutUint16(b[4+ed25519.PublicKeySize:6+ed25519.PublicKeySize], 9001)
|
||||
binary.BigEndian.PutUint16(b[6+ed25519.PublicKeySize:8+ed25519.PublicKeySize], 32)
|
||||
|
||||
var adv multicastAdvertisement
|
||||
if err := adv.UnmarshalBinary(b); err == nil {
|
||||
t.Fatal("expected truncated beacon to be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user