[PATCH] net: cdp: reject CDP TLVs with a length below the 4-byte header

Jerome Forissier jerome.forissier at arm.com
Tue Jun 16 17:52:48 CEST 2026


On 12/06/2026 09:47, Piyush Paliwal wrote:
> cdp_receive() reads a 16-bit TLV length (tlen) from the packet and only
> checks that it does not exceed the remaining buffer (tlen > len). It then
> unconditionally does "tlen -= 4" to skip the TLV header. As tlen is a
> u16, a crafted TLV with a length of 0..3 underflows tlen to ~65532-65535.
> 
> For a CDP_APPLIANCE_VLAN_TLV the underflowed length then drives the inner
> "while (tlen > 0)" loop, which walks ~64KB past the receive buffer reading
> *ss each step -> out-of-bounds read (crash / info-influence). A length of
> 0 additionally fails to advance pkt/len, hanging the parse loop.
> 
> Reject any TLV whose declared length is smaller than its own 4-byte
> header. This is the same class of bug as the recent bootp/dhcpv6/sntp/nfs
> fixes (unchecked length field), in a sibling LAN parser that was missed.
> 
> Verified with a standalone AddressSanitizer harness using the verbatim
> cdp_receive()/cdp_compute_csum() routines: a 16-byte CDP frame with an
> appliance-VLAN TLV of length 3 triggers a heap-buffer-overflow READ that
> the check eliminates.
> 
> Fixes: f575ae1f7d39 ("net: Move CDP out of net.c")
> Cc: stable at vger.kernel.org
> Signed-off-by: Piyush Paliwal <piyushthepal at gmail.com>
> ---
>  net/cdp.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/net/cdp.c b/net/cdp.c
> index 6e404981d4a..300b3d5c409 100644
> --- a/net/cdp.c
> +++ b/net/cdp.c
> @@ -276,7 +276,13 @@ void cdp_receive(const uchar *pkt, unsigned len)
>  		ss = (const ushort *)pkt;
>  		type = ntohs(ss[0]);
>  		tlen = ntohs(ss[1]);
> -		if (tlen > len)
> +		/*
> +		 * tlen includes the 4-byte TLV header, so it must be at
> +		 * least 4.  Without this check a crafted tlen < 4 makes the
> +		 * "tlen -= 4" below underflow (tlen is a ushort), and a tlen
> +		 * of 0 also fails to advance pkt/len, hanging the loop.
> +		 */
> +		if (tlen < 4 || tlen > len)
>  			goto pkt_short;
>  
>  		pkt += tlen;

Reviewed-by: Jerome Forissier <jerome.forissier at arm.com>

Added to my net queue for master, thanks!

-- 
Jerome


More information about the U-Boot mailing list