On Sat, Sep 26, 2026 at 8:23 PM Ren Wei <[email protected]> wrote:
>
> From: Zixuan Chai <[email protected]>
>
> i40e_atr() uses ipv6_find_hdr() to locate the TCP header. A successful
> protocol match does not verify that the complete TCP header is present in
> the skb, so dereferencing the result can access data beyond the packet.
>
> Check that the complete TCP header is available before inspecting it.
>
> Fixes: fd0a05ce74ef ("i40e: transmit, receive, and NAPI")
> Cc: [email protected]
> Reported-by: Florian Westphal <[email protected]>
> Closes: https://lore.kernel.org/netfilter-devel/[email protected]/
> Assisted-by: LLM
> Signed-off-by: Zixuan Chai <[email protected]>
> Signed-off-by: Ren Wei <[email protected]>
> ---
>  drivers/net/ethernet/intel/i40e/i40e_txrx.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c 
> b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> index ef5e657816f0..cdac279b8aed 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> @@ -2911,6 +2911,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct 
> sk_buff *skb,
>
>         if (l4_proto != IPPROTO_TCP)
>                 return;
> +       if (unlikely(skb_tail_pointer(skb) < hdr.network + hlen +
> +                            sizeof(struct tcphdr)))
> +               return;
>
>         th = (struct tcphdr *)(hdr.network + hlen);
>

pw-bot: cr

1) Please do not add bogus Reported-by: / Closes: tags. Florian never
reported an issue in i40e, unless this was not public?

2) How can this code be reached with a truncated or non-linear TCP header?
Unlike ixgbe_atr(), i40e_atr() returns immediately unless
tx_flags & (I40E_TX_FLAGS_IPV4 | I40E_TX_FLAGS_IPV6) is set.
Those flags are only set in i40e_tx_enable_csum(), which only acts on
CHECKSUM_PARTIAL packets and runs right before i40e_atr().

Furthermore, i40e_tx_enable_csum() (and i40e_tso()) already assumes the
network and transport headers are present in the linear skb head and
already dereferences ip.v4->version, ip.v6->nexthdr, and l4.tcp->doff
before i40e_atr() is ever called. Even within i40e_atr(), hdr.network
is already dereferenced prior to your check in the IPv4 branch.

Reply via email to