Bug 9888
Summary: | tun device without protocol info header fails under IPv6 | ||
---|---|---|---|
Product: | Networking | Reporter: | Steve Zabele (steve.zabele) |
Component: | IPV6 | Assignee: | Hideaki YOSHIFUJI (yoshfuji) |
Status: | REJECTED WILL_NOT_FIX | ||
Severity: | low | CC: | protasnb, steve.zabele |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | >=2.6.23 | Subsystem: | |
Regression: | --- | Bisected commit-id: | |
Attachments: |
TUN_NO_PI and IPv6 fix
TUN_NO_PI and IPv6 update |
Description
Steve Zabele
2008-02-04 13:46:12 UTC
Reply-To: akpm@linux-foundation.org On Mon, 4 Feb 2008 13:46:13 -0800 (PST) bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=9888 > > Summary: tun device without protocol info header fails under IPv6 > Product: Networking > Version: 2.5 > KernelVersion: >=2.6.23 > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: low > Priority: P1 > Component: IPV6 > AssignedTo: yoshfuji@linux-ipv6.org > ReportedBy: steve.zabele@baesystems.com > > > Latest working kernel version: None known -- appears to be a historic bug > Earliest failing kernel version: All > Distribution: > Hardware Environment: > Software Environment: > Problem Description: > > Steps to reproduce: > > Open a tun device as type TUN, set the TUN_NO_PI flag, and try sending an > IPv6 > packet. The packet appears at the interface under tcpdumps, but propagates no > further. This is because the default protocol info used for tun devices where > the TUN_NO_PI flag is set assumes IPv4 as can be seen by the initialization > at > the top of the tun_get_user function in drivers/net/tun.c file given by > > struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) }; > > This can easily be fixed by adding a quick check at the top of tun_get_user. > Basically the code that used to read > > if (!(tun->flags & TUN_NO_PI)) { > if ((len -= sizeof(pi)) > count) > return -EINVAL; > > if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) > return -EFAULT; > } > > when changed to read > > if (!(tun->flags & TUN_NO_PI)) { > if ((len -= sizeof(pi)) > count) > return -EINVAL; > > if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) > return -EFAULT; > } > else { > /* Fixup default pi if IPv6 rather than IPv4 */ > if (((tun->flags & TUN_TYPE_MASK) == TUN_TUN_DEV) && > (*(char *)(iv->iov_base) == 0x60)) { > pi.proto = __constant_htons(ETH_P_IPV6); > } > } > > fixes the problem. > > How do we get this in as part of the maintained codebase?? > Please email a tested patch prepared as described in Documentation/SubmittingPatches Documentation/SubmitChecklist http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt to Maxim Krasnyansky <maxk@qualcomm.com> "David S. Miller" <davem@davemloft.net> Andrew Morton <akpm@linux-foundation.org> netdev@vger.kernel.org thanks. Reply-To: maxk@qualcomm.com Andrew Morton wrote: > On Mon, 4 Feb 2008 13:46:13 -0800 (PST) > bugme-daemon@bugzilla.kernel.org wrote: >> >> Open a tun device as type TUN, set the TUN_NO_PI flag, and try sending an >> IPv6 >> packet. The packet appears at the interface under tcpdumps, but propagates >> no >> further. This is because the default protocol info used for tun devices >> where >> the TUN_NO_PI flag is set assumes IPv4 as can be seen by the initialization >> at >> the top of the tun_get_user function in drivers/net/tun.c file given by >> >> struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) }; >> >> This can easily be fixed by adding a quick check at the top of tun_get_user. >> Basically the code that used to read >> >> if (!(tun->flags & TUN_NO_PI)) { >> if ((len -= sizeof(pi)) > count) >> return -EINVAL; >> >> if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) >> return -EFAULT; >> } >> >> when changed to read >> >> if (!(tun->flags & TUN_NO_PI)) { >> if ((len -= sizeof(pi)) > count) >> return -EINVAL; >> >> if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) >> return -EFAULT; >> } >> else { >> /* Fixup default pi if IPv6 rather than IPv4 */ >> if (((tun->flags & TUN_TYPE_MASK) == TUN_TUN_DEV) && >> (*(char *)(iv->iov_base) == 0x60)) { >> pi.proto = __constant_htons(ETH_P_IPV6); >> } >> } >> >> fixes the problem. >> >> How do we get this in as part of the maintained codebase?? >> > > Please email a tested patch prepared as described in > > Documentation/SubmittingPatches > Documentation/SubmitChecklist > http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt > > to > > Maxim Krasnyansky <maxk@qualcomm.com> > "David S. Miller" <davem@davemloft.net> > Andrew Morton <akpm@linux-foundation.org> > netdev@vger.kernel.org btw I'd be ok with this fix. But I guess the questions is why not use struct tun_pi in the apps instead ? Max Created attachment 14747 [details]
TUN_NO_PI and IPv6 fix
Created attachment 15333 [details]
TUN_NO_PI and IPv6 update
The memcpy_fromiovec used in the previous patch advances the iovec internal pointer and decrements the packet length, such that subsequent attempts to pull the packet from the user space buffer finds that the buffer is now too short -- generating an -EFAULT. The enclosed patch instead users copy_from_user and correctly leaves the iovec unmodified
Steve, Can you please submit the patch to LKML and to Maxim (maxk@qualcomm.com) via email (if you haven't already)? |