You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pkg/packet/mrt: fix parser to check the input length
1 func (m *BGP4MPHeader) decodeFromBytes(data []byte) ([]byte, error) {
2 if m.isAS4 && len(data) < 8 {
3 return nil, errors.New("not all BGP4MPMessageAS4 bytes available")
4 } else if !m.isAS4 && len(data) < 4 {
5 return nil, errors.New("not all BGP4MPMessageAS bytes available")
6 }
7
8 if m.isAS4 {
9 m.PeerAS = binary.BigEndian.Uint32(data[:4])
10 m.LocalAS = binary.BigEndian.Uint32(data[4:8])
11 data = data[8:]
12 } else {
13 m.PeerAS = uint32(binary.BigEndian.Uint16(data[:2]))
14 m.LocalAS = uint32(binary.BigEndian.Uint16(data[2:4]))
15 data = data[4:]
16 }
17 m.InterfaceIndex = binary.BigEndian.Uint16(data[:2])
18 m.AddressFamily = binary.BigEndian.Uint16(data[2:4])
19 switch m.AddressFamily {
20 case bgp.AFI_IP:
21 m.PeerIpAddress = net.IP(data[4:8]).To4()
22 m.LocalIpAddress = net.IP(data[8:12]).To4()
23 data = data[12:]
24 case bgp.AFI_IP6:
25 m.PeerIpAddress = net.IP(data[4:20])
26 m.LocalIpAddress = net.IP(data[20:36])
27 data = data[36:]
28 default:
29 return nil, fmt.Errorf("unsupported address family: %d",
m.AddressFamily)
30 }
31 return data, nil
32 }
The check at lines 2-6 is sufficient only to safely extract `PeerAS`
and `LocalAS`, after that slice is rebound to the leftover bytes,
i.e., the length of the slice is not 8 or 4 bytes less, depending on
the it is AS4 or not. That means that it could be empty, therefore any
line beyond 16 is vulnerable. E.g., we need to check for at least 4
bytes for lines 17 and 18, and then depending on the address family,
for 12 or 36 bytes.
0 commit comments