From 0eca93bcf73e5939053a94f7c48f8d6fe6199e00 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 14 Apr 2009 02:09:43 -0700
Subject: [PATCH] tun: Fix crash with non-GSO users

When I made the tun driver use non-linear packets as the preferred
option, it broke non-GSO users because they would end up allocating
a completely non-linear packet, which triggers a crash when we call
eth_type_trans.

This patch reverts non-GSO users to using linear packets and adds
a check to ensure that GSO users can't cause crashes in the same
way.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/tun.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a1b0697340ba..16716aef184c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -518,7 +518,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 	int err;
 
 	/* Under a page?  Don't bother with paged skb. */
-	if (prepad + len < PAGE_SIZE)
+	if (prepad + len < PAGE_SIZE || !linear)
 		linear = len;
 
 	skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
@@ -565,7 +565,8 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 
 	if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
 		align = NET_IP_ALIGN;
-		if (unlikely(len < ETH_HLEN))
+		if (unlikely(len < ETH_HLEN ||
+			     (gso.hdr_len && gso.hdr_len < ETH_HLEN)))
 			return -EINVAL;
 	}
 
-- 
GitLab