From 2f12227690cf9a979a9a148109c96ab4f6ee6c0e Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 25 Jun 2017 16:24:23 +0200 Subject: global: cleanup IP header checking This way is more correct and ensures we're within the skb head. --- src/packets.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/packets.h') diff --git a/src/packets.h b/src/packets.h index 0e909d3..c956c7a 100644 --- a/src/packets.h +++ b/src/packets.h @@ -9,6 +9,9 @@ #include #include +#include +#include +#include struct wireguard_device; struct wireguard_peer; @@ -34,11 +37,20 @@ void packet_send_handshake_response(struct wireguard_peer *peer); void packet_send_handshake_cookie(struct wireguard_device *wg, struct sk_buff *initiating_skb, __le32 sender_index); void packet_create_data_done(struct sk_buff_head *queue, struct wireguard_peer *peer); - /* data.c */ int packet_create_data(struct sk_buff_head *queue, struct wireguard_peer *peer); void packet_consume_data(struct sk_buff *skb, struct wireguard_device *wg); +/* Returns either the correct skb->protocol value, or 0 if invalid. */ +static inline __be16 skb_examine_untrusted_ip_hdr(struct sk_buff *skb) +{ + if (skb_network_header(skb) >= skb->head && (skb_network_header(skb) + sizeof(struct iphdr)) <= skb_tail_pointer(skb) && ip_hdr(skb)->version == 4) + return htons(ETH_P_IP); + if (skb_network_header(skb) >= skb->head && (skb_network_header(skb) + sizeof(struct ipv6hdr)) <= skb_tail_pointer(skb) && ipv6_hdr(skb)->version == 6) + return htons(ETH_P_IPV6); + return 0; +} + #ifdef CONFIG_WIREGUARD_PARALLEL int packet_init_data_caches(void); void packet_deinit_data_caches(void); -- cgit v1.2.3-59-g8ed1b