Patchwork tun: Fix crash with non-GSO users

login
register
mail settings
Submitter Herbert Xu
Date April 14, 2009, 4:22 a.m.
Message ID <20090414042258.GA27159@gondor.apana.org.au>
Download mbox | patch
Permalink /patch/25919/
State Accepted
Delegated to: David Miller
Headers show

Comments

Herbert Xu - April 14, 2009, 4:22 a.m.
Hi:

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>

 Cheers,
David Miller - April 14, 2009, 9:09 a.m.
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 14 Apr 2009 12:22:58 +0800

> 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>

Applied, thanks a lot Herbert.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a1b0697..16716ae 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;
 	}