X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/f37f881a012494a31fd4ffa0576cc9d109371fc8..9d12c363e3651e37bfa295bcba69aeaf0c842f9e:/target/linux/generic-2.4/patches/230-tun_get_user_backport.patch diff --git a/target/linux/generic-2.4/patches/230-tun_get_user_backport.patch b/target/linux/generic-2.4/patches/230-tun_get_user_backport.patch index 636ffec11..acddc0182 100644 --- a/target/linux/generic-2.4/patches/230-tun_get_user_backport.patch +++ b/target/linux/generic-2.4/patches/230-tun_get_user_backport.patch @@ -1,56 +1,8 @@ ---- linux-2.4.32/drivers/net/tun.c 2006-10-28 18:21:45.000000000 +0100 -+++ new.linux-2.4.32/drivers/net/tun.c 2006-10-28 18:50:53.000000000 +0100 -@@ -185,22 +185,31 @@ - { - struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) }; - struct sk_buff *skb; -- size_t len = count; -+ size_t len = count, align = 0; - - if (!(tun->flags & TUN_NO_PI)) { - if ((len -= sizeof(pi)) > count) - return -EINVAL; - -- memcpy_fromiovec((void *)&pi, iv, sizeof(pi)); -+ if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) -+ return -EFAULT; - } -- -- if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) { -+ -+ if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) -+ align = NET_IP_ALIGN; -+ -+ if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { - tun->stats.rx_dropped++; - return -ENOMEM; - } - -- skb_reserve(skb, 2); -- memcpy_fromiovec(skb_put(skb, len), iv, len); -+ if (align) -+ skb_reserve(skb, align); -+ if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { -+ tun->stats.rx_dropped++; -+ kfree_skb(skb); -+ return -EFAULT; -+ } - - skb->dev = &tun->dev; - switch (tun->flags & TUN_TYPE_MASK) { -@@ -271,7 +271,8 @@ - pi.flags |= TUN_PKT_STRIP; - } - -- memcpy_toiovec(iv, (void *) &pi, sizeof(pi)); -+ if(memcpy_toiovec(iv, (void *) &pi, sizeof(pi))) -+ return -EFAULT; - total += sizeof(pi); - } - ---- linux-2.4.32/include/linux/skbuff.h 2006-10-28 19:31:31.000000000 +0100 -+++ new.linux-2.4.32/include/linux/skbuff.h 2006-10-28 19:29:27.000000000 +0100 -@@ -918,6 +918,49 @@ +Index: linux-2.4.35.4/include/linux/skbuff.h +=================================================================== +--- linux-2.4.35.4.orig/include/linux/skbuff.h ++++ linux-2.4.35.4/include/linux/skbuff.h +@@ -912,6 +912,49 @@ static inline void skb_reserve(struct sk skb->tail+=len; } @@ -100,3 +52,55 @@ extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); static inline void __skb_trim(struct sk_buff *skb, unsigned int len) +Index: linux-2.4.35.4/drivers/net/tun.c +=================================================================== +--- linux-2.4.35.4.orig/drivers/net/tun.c ++++ linux-2.4.35.4/drivers/net/tun.c +@@ -185,22 +185,31 @@ static __inline__ ssize_t tun_get_user(s + { + struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) }; + struct sk_buff *skb; +- size_t len = count; ++ size_t len = count, align = 0; + + if (!(tun->flags & TUN_NO_PI)) { + if ((len -= sizeof(pi)) > count) + return -EINVAL; + +- memcpy_fromiovec((void *)&pi, iv, sizeof(pi)); ++ if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) ++ return -EFAULT; + } +- +- if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) { ++ ++ if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) ++ align = NET_IP_ALIGN; ++ ++ if (!(skb = alloc_skb(len + align, GFP_KERNEL))) { + tun->stats.rx_dropped++; + return -ENOMEM; + } + +- skb_reserve(skb, 2); +- memcpy_fromiovec(skb_put(skb, len), iv, len); ++ if (align) ++ skb_reserve(skb, align); ++ if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { ++ tun->stats.rx_dropped++; ++ kfree_skb(skb); ++ return -EFAULT; ++ } + + skb->dev = &tun->dev; + switch (tun->flags & TUN_TYPE_MASK) { +@@ -271,7 +280,8 @@ static __inline__ ssize_t tun_put_user(s + pi.flags |= TUN_PKT_STRIP; + } + +- memcpy_toiovec(iv, (void *) &pi, sizeof(pi)); ++ if(memcpy_toiovec(iv, (void *) &pi, sizeof(pi))) ++ return -EFAULT; + total += sizeof(pi); + } +