From 5297eed8f4898e7a29898c70d6450d2daebecd17 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 13 Dec 2021 22:09:15 +0300 Subject: fix: check IP/UDP header size before trying to access it This should fix the panic we've seen with the malformed packets on the wire. Remaining buffer size should be checked before trying to access the data, otherwise Go might panic on out of bounds slice operation. Signed-off-by: Andrey Smirnov --- dhcpv4/nclient4/conn_linux.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'dhcpv4') diff --git a/dhcpv4/nclient4/conn_linux.go b/dhcpv4/nclient4/conn_linux.go index 2fe69ce..6cdb071 100644 --- a/dhcpv4/nclient4/conn_linux.go +++ b/dhcpv4/nclient4/conn_linux.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build go1.12 // +build go1.12 package nclient4 @@ -98,12 +99,26 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { buf := uio.NewBigEndianBuffer(pkt) // To read the header length, access data directly. + if !buf.Has(ipv4MinimumSize) { + continue + } + ipHdr := ipv4(buf.Data()) + + if !buf.Has(int(ipHdr.headerLength())) { + continue + } + ipHdr = ipv4(buf.Consume(int(ipHdr.headerLength()))) if ipHdr.transportProtocol() != udpProtocolNumber { continue } + + if !buf.Has(udpHdrLen) { + continue + } + udpHdr := udp(buf.Consume(udpHdrLen)) addr := &net.UDPAddr{ -- cgit v1.2.3