David Bidner, le ven. 18 sept. 2026 18:14:05 +0200, a ecrit:
> trivfs_S_io_write() set skb->len without advancing skb->tail, so an IPv6
> packet reached ip6_input() with skb->tail == skb->data.  ip6_input()
> derives its payload length from skb->tail - skb->h.raw, so icmpv6_rcv()
> got a negative length; its unsigned check passed it to csum_partial(),
> crashing pfinet.
> 
> The function also hardcoded ETH_P_IP, sending IPv6 to ip_rcv().  Classify
> by the version nibble.
> 
> * pfinet/tunnel.c (trivfs_S_io_write): Use skb_put() so skb->tail and
> skb->len advance together, and set skb->protocol from the version nibble.

Applied, thanks!

> ---
>  pfinet/tunnel.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/pfinet/tunnel.c b/pfinet/tunnel.c
> index 6732ac5..8147f2d 100644
> --- a/pfinet/tunnel.c
> +++ b/pfinet/tunnel.c
> @@ -393,14 +393,14 @@ trivfs_S_io_write (struct trivfs_protid *cred,
>  
>    skb = alloc_skb (NET_IP_ALIGN + datalen, GFP_ATOMIC);
>    skb_reserve(skb, NET_IP_ALIGN);
> -  skb->len = datalen;
>    skb->dev = &tdev->dev;
>  
> -  memcpy (skb->data, data, datalen);
> +  memcpy (skb_put (skb, datalen), data, datalen);
>  
>    /* Drop it on the queue. */
>    skb->mac.raw = skb->data;
> -  skb->protocol = htons (ETH_P_IP);
> +  skb->protocol = htons (datalen > 0 && (data[0] >> 4) == 6
> +                      ? ETH_P_IPV6 : ETH_P_IP);
>    netif_rx (skb);
>  
>    pthread_mutex_unlock (&tdev->lock);
> -- 
> 2.47.3

Reply via email to