+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);
+ }
+