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
