net/packet: fix panic on invalid IHL field.

Signed-off-by: David Anderson <danderson@tailscale.com>
This commit is contained in:
David Anderson 2020-11-10 19:10:11 -08:00 committed by Dave Anderson
parent 22bf48f37c
commit 9ef39af2f2
2 changed files with 29 additions and 1 deletions

View File

@ -165,6 +165,11 @@ func (q *Parsed) decode4(b []byte) {
q.DstIP4 = IP4(binary.BigEndian.Uint32(b[16:20])) q.DstIP4 = IP4(binary.BigEndian.Uint32(b[16:20]))
q.subofs = int((b[0] & 0x0F) << 2) q.subofs = int((b[0] & 0x0F) << 2)
if q.subofs > q.length {
// next-proto starts beyond end of packet.
q.IPProto = Unknown
return
}
sub := b[q.subofs:] sub := b[q.subofs:]
// We don't care much about IP fragmentation, except insofar as it's // We don't care much about IP fragmentation, except insofar as it's

View File

@ -233,6 +233,28 @@ var udp4RequestDecode = Parsed{
DstPort: 567, DstPort: 567,
} }
var invalid4RequestBuffer = []byte{
// IP header up to checksum. IHL field points beyond end of packet.
0x4a, 0x00, 0x00, 0x14, 0xde, 0xad, 0x00, 0x00, 0x40, 0x11, 0x8c, 0x01,
// source ip
0x01, 0x02, 0x03, 0x04,
// destination ip
0x05, 0x06, 0x07, 0x08,
}
// Regression check for the IHL field pointing beyond the end of the
// packet.
var invalid4RequestDecode = Parsed{
b: invalid4RequestBuffer,
subofs: 40,
length: len(invalid4RequestBuffer),
IPVersion: 4,
IPProto: Unknown,
SrcIP4: mustIP4("1.2.3.4"),
DstIP4: mustIP4("5.6.7.8"),
}
var udp6RequestBuffer = []byte{ var udp6RequestBuffer = []byte{
// IPv6 header up to hop limit // IPv6 header up to hop limit
0x60, 0x0e, 0xc9, 0x67, 0x00, 0x29, 0x11, 0x40, 0x60, 0x0e, 0xc9, 0x67, 0x00, 0x29, 0x11, 0x40,
@ -328,11 +350,12 @@ func TestDecode(t *testing.T) {
}{ }{
{"icmp4", icmp4RequestBuffer, icmp4RequestDecode}, {"icmp4", icmp4RequestBuffer, icmp4RequestDecode},
{"icmp6", icmp6PacketBuffer, icmp6PacketDecode}, {"icmp6", icmp6PacketBuffer, icmp6PacketDecode},
{"unknown", unknownPacketBuffer, unknownPacketDecode},
{"tcp4", tcp4PacketBuffer, tcp4PacketDecode}, {"tcp4", tcp4PacketBuffer, tcp4PacketDecode},
{"tcp6", tcp6RequestBuffer, tcp6RequestDecode}, {"tcp6", tcp6RequestBuffer, tcp6RequestDecode},
{"udp4", udp4RequestBuffer, udp4RequestDecode}, {"udp4", udp4RequestBuffer, udp4RequestDecode},
{"udp6", udp6RequestBuffer, udp6RequestDecode}, {"udp6", udp6RequestBuffer, udp6RequestDecode},
{"unknown", unknownPacketBuffer, unknownPacketDecode},
{"invalid4", invalid4RequestBuffer, invalid4RequestDecode},
} }
for _, tt := range tests { for _, tt := range tests {