netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers
@ 2018-03-29 10:05 Toshiaki Makita
  2018-03-29 10:05 ` [PATCH net 1/2] net: Fix untag for vlan packets without ethernet header Toshiaki Makita
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Toshiaki Makita @ 2018-03-29 10:05 UTC (permalink / raw)
  To: David S. Miller; +Cc: Toshiaki Makita, netdev, Eric Dumazet

Eric Dumazet reported syzbot found a new bug which leads to underflow of
size argument of memmove(), causing crash[1]. This can be triggered by tun
devices.

The underflow happened because skb_vlan_untag() did not expect vlan packets
without ethernet headers, and tun can produce such packets.
I also checked vlan_insert_inner_tag() and found a similar bug.

This series fixes these problems.

[1] https://marc.info/?l=linux-netdev&m=152221753920510&w=2

Toshiaki Makita (2):
  net: Fix untag for vlan packets without ethernet header
  vlan: Fix vlan insertion for packets without ethernet header

 include/linux/if_vlan.h | 15 +++++++++++++--
 net/core/skbuff.c       |  6 ++++--
 2 files changed, 17 insertions(+), 4 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net 1/2] net: Fix untag for vlan packets without ethernet header
  2018-03-29 10:05 [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers Toshiaki Makita
@ 2018-03-29 10:05 ` Toshiaki Makita
  2018-03-29 10:05 ` [PATCH net 2/2] vlan: Fix vlan insertion for " Toshiaki Makita
  2018-03-30 16:49 ` [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Toshiaki Makita @ 2018-03-29 10:05 UTC (permalink / raw)
  To: David S. Miller; +Cc: Toshiaki Makita, netdev, Eric Dumazet

In some situation vlan packets do not have ethernet headers. One example
is packets from tun devices. Users can specify vlan protocol in tun_pi
field instead of IP protocol, and skb_vlan_untag() attempts to untag such
packets.

skb_vlan_untag() (more precisely, skb_reorder_vlan_header() called by it)
however did not expect packets without ethernet headers, so in such a case
size argument for memmove() underflowed and triggered crash.

====
BUG: unable to handle kernel paging request at ffff8801cccb8000
IP: __memmove+0x24/0x1a0 arch/x86/lib/memmove_64.S:43
PGD 9cee067 P4D 9cee067 PUD 1d9401063 PMD 1cccb7063 PTE 2810100028101
Oops: 000b [#1] SMP KASAN
Dumping ftrace buffer:
   (ftrace buffer empty)
Modules linked in:
CPU: 1 PID: 17663 Comm: syz-executor2 Not tainted 4.16.0-rc7+ #368
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
RIP: 0010:__memmove+0x24/0x1a0 arch/x86/lib/memmove_64.S:43
RSP: 0018:ffff8801cc046e28 EFLAGS: 00010287
RAX: ffff8801ccc244c4 RBX: fffffffffffffffe RCX: fffffffffff6c4c2
RDX: fffffffffffffffe RSI: ffff8801cccb7ffc RDI: ffff8801cccb8000
RBP: ffff8801cc046e48 R08: ffff8801ccc244be R09: ffffed0039984899
R10: 0000000000000001 R11: ffffed0039984898 R12: ffff8801ccc244c4
R13: ffff8801ccc244c0 R14: ffff8801d96b7c06 R15: ffff8801d96b7b40
FS:  00007febd562d700(0000) GS:ffff8801db300000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff8801cccb8000 CR3: 00000001ccb2f006 CR4: 00000000001606e0
DR0: 0000000020000000 DR1: 0000000020000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600
Call Trace:
 memmove include/linux/string.h:360 [inline]
 skb_reorder_vlan_header net/core/skbuff.c:5031 [inline]
 skb_vlan_untag+0x470/0xc40 net/core/skbuff.c:5061
 __netif_receive_skb_core+0x119c/0x3460 net/core/dev.c:4460
 __netif_receive_skb+0x2c/0x1b0 net/core/dev.c:4627
 netif_receive_skb_internal+0x10b/0x670 net/core/dev.c:4701
 netif_receive_skb+0xae/0x390 net/core/dev.c:4725
 tun_rx_batched.isra.50+0x5ee/0x870 drivers/net/tun.c:1555
 tun_get_user+0x299e/0x3c20 drivers/net/tun.c:1962
 tun_chr_write_iter+0xb9/0x160 drivers/net/tun.c:1990
 call_write_iter include/linux/fs.h:1782 [inline]
 new_sync_write fs/read_write.c:469 [inline]
 __vfs_write+0x684/0x970 fs/read_write.c:482
 vfs_write+0x189/0x510 fs/read_write.c:544
 SYSC_write fs/read_write.c:589 [inline]
 SyS_write+0xef/0x220 fs/read_write.c:581
 do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
 entry_SYSCALL_64_after_hwframe+0x42/0xb7
RIP: 0033:0x454879
RSP: 002b:00007febd562cc68 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007febd562d6d4 RCX: 0000000000454879
RDX: 0000000000000157 RSI: 0000000020000180 RDI: 0000000000000014
RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
R13: 00000000000006b0 R14: 00000000006fc120 R15: 0000000000000000
Code: 90 90 90 90 90 90 90 48 89 f8 48 83 fa 20 0f 82 03 01 00 00 48 39 fe 7d 0f 49 89 f0 49 01 d0 49 39 f8 0f 8f 9f 00 00 00 48 89 d1 <f3> a4 c3 48 81 fa a8 02 00 00 72 05 40 38 fe 74 3b 48 83 ea 20
RIP: __memmove+0x24/0x1a0 arch/x86/lib/memmove_64.S:43 RSP: ffff8801cc046e28
CR2: ffff8801cccb8000
====

We don't need to copy headers for packets which do not have preceding
headers of vlan headers, so skip memmove() in that case.

Fixes: 4bbb3e0e8239 ("net: Fix vlan untag for bridge and vlan_dev with reorder_hdr off")
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
---
 net/core/skbuff.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e7acdc..857e4e6 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5028,8 +5028,10 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
 	}
 
 	mac_len = skb->data - skb_mac_header(skb);
-	memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
-		mac_len - VLAN_HLEN - ETH_TLEN);
+	if (likely(mac_len > VLAN_HLEN + ETH_TLEN)) {
+		memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb),
+			mac_len - VLAN_HLEN - ETH_TLEN);
+	}
 	skb->mac_header += VLAN_HLEN;
 	return skb;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH net 2/2] vlan: Fix vlan insertion for packets without ethernet header
  2018-03-29 10:05 [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers Toshiaki Makita
  2018-03-29 10:05 ` [PATCH net 1/2] net: Fix untag for vlan packets without ethernet header Toshiaki Makita
@ 2018-03-29 10:05 ` Toshiaki Makita
  2018-03-30 16:49 ` [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Toshiaki Makita @ 2018-03-29 10:05 UTC (permalink / raw)
  To: David S. Miller; +Cc: Toshiaki Makita, netdev, Eric Dumazet

In some situation vlan packets do not have ethernet headers. One example
is packets from tun devices. Users can specify vlan protocol in tun_pi
field instead of IP protocol. When we have a vlan device with reorder_hdr
disabled on top of the tun device, such packets from tun devices are
untagged in skb_vlan_untag() and vlan headers will be inserted back in
vlan_insert_inner_tag().

vlan_insert_inner_tag() however did not expect packets without ethernet
headers, so in such a case size argument for memmove() underflowed.

We don't need to copy headers for packets which do not have preceding
headers of vlan headers, so skip memmove() in that case.
Also don't write vlan protocol in skb->data when it does not have enough
room for it.

Fixes: cbe7128c4b92 ("vlan: Fix out of order vlan headers with reorder header off")
Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
---
 include/linux/if_vlan.h | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index c4a1cff..7d30892 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -323,13 +323,24 @@ static inline int __vlan_insert_inner_tag(struct sk_buff *skb,
 	skb_push(skb, VLAN_HLEN);
 
 	/* Move the mac header sans proto to the beginning of the new header. */
-	memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
+	if (likely(mac_len > ETH_TLEN))
+		memmove(skb->data, skb->data + VLAN_HLEN, mac_len - ETH_TLEN);
 	skb->mac_header -= VLAN_HLEN;
 
 	veth = (struct vlan_ethhdr *)(skb->data + mac_len - ETH_HLEN);
 
 	/* first, the ethernet type */
-	veth->h_vlan_proto = vlan_proto;
+	if (likely(mac_len >= ETH_TLEN)) {
+		/* h_vlan_encapsulated_proto should already be populated, and
+		 * skb->data has space for h_vlan_proto
+		 */
+		veth->h_vlan_proto = vlan_proto;
+	} else {
+		/* h_vlan_encapsulated_proto should not be populated, and
+		 * skb->data has no space for h_vlan_proto
+		 */
+		veth->h_vlan_encapsulated_proto = skb->protocol;
+	}
 
 	/* now, the TCI */
 	veth->h_vlan_TCI = htons(vlan_tci);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers
  2018-03-29 10:05 [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers Toshiaki Makita
  2018-03-29 10:05 ` [PATCH net 1/2] net: Fix untag for vlan packets without ethernet header Toshiaki Makita
  2018-03-29 10:05 ` [PATCH net 2/2] vlan: Fix vlan insertion for " Toshiaki Makita
@ 2018-03-30 16:49 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2018-03-30 16:49 UTC (permalink / raw)
  To: makita.toshiaki; +Cc: netdev, eric.dumazet

From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Date: Thu, 29 Mar 2018 19:05:28 +0900

> Eric Dumazet reported syzbot found a new bug which leads to underflow of
> size argument of memmove(), causing crash[1]. This can be triggered by tun
> devices.
> 
> The underflow happened because skb_vlan_untag() did not expect vlan packets
> without ethernet headers, and tun can produce such packets.
> I also checked vlan_insert_inner_tag() and found a similar bug.
> 
> This series fixes these problems.
> 
> [1] https://marc.info/?l=linux-netdev&m=152221753920510&w=2

Series applied, thank you.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-03-30 16:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-29 10:05 [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers Toshiaki Makita
2018-03-29 10:05 ` [PATCH net 1/2] net: Fix untag for vlan packets without ethernet header Toshiaki Makita
2018-03-29 10:05 ` [PATCH net 2/2] vlan: Fix vlan insertion for " Toshiaki Makita
2018-03-30 16:49 ` [PATCH net 0/2] Fix vlan tag handling for vlan packets without ethernet headers David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).