summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--quicktun.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/quicktun.c b/quicktun.c
index 6899a05..4c5c585 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -2,6 +2,7 @@
#include <linux/ethtool.h>
#include <linux/if_arp.h>
#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/netdevice.h>
#include <linux/udp.h>
#include <net/dst.h>
@@ -101,10 +102,15 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
switch (tun->flags & QUICKTUN_MODE_MASK) {
case QUICKTUN_MODE_ETHERNET:
+ if (len < ETH_HLEN)
+ goto drop;
skb->protocol = eth_type_trans(skb, tun->dev);
break;
case QUICKTUN_MODE_IP:
+ if (len < sizeof(struct iphdr))
+ goto drop;
+
__skb_tunnel_rx(skb, tun->dev);
skb_reset_network_header(skb);
@@ -113,6 +119,8 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
skb->protocol = htons(ETH_P_IP);
break;
case 0x60:
+ if (len < sizeof(struct ipv6hdr))
+ goto drop;
skb->protocol = htons(ETH_P_IPV6);
break;
default:
@@ -135,8 +143,7 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
kfree_skb(skb);
}
-static int
-quicktun_net_change_mtu(struct net_device *dev, int new_mtu)
+static int quicktun_net_change_mtu(struct net_device *dev, int new_mtu)
{
if (new_mtu < MIN_MTU || new_mtu + dev->hard_header_len > MAX_MTU)
return -EINVAL;