From b116697fb51e36789339faf2ea19a9cb80e0f82b Mon Sep 17 00:00:00 2001 From: Tejaswi Tanikella Date: Fri, 5 Jan 2018 12:40:48 +0530 Subject: [PATCH] nf: xt_socket: Fix out-of-bounds in xt_socket_lookup_slow_v{4,6} skb_header_pointer will copy data into the buffer if data is spread across pages, else share pointer within skb->data. In xt_socket_lookup_slow_v4, data is copied into udphdr, and later th->doff is accessed, causing a out-of-bounds. This access will only work if the data is not split across pages. Copy data into tcphdr buffer for TCP packets instead. Change-Id: Ifd6e15ece27fcf5bd02ae17571ab43f6df3ceb21 Fixes: a583636a ("inet: refactor inet[6]_lookup functions to take skb") Signed-off-by: Tejaswi Tanikella --- net/netfilter/xt_socket.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index ede54061c554..939821821fcb 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -158,10 +158,13 @@ struct sock *xt_socket_lookup_slow_v4(struct net *net, #endif if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) { - struct udphdr _hdr, *hp; + struct udphdr *hp; + struct tcphdr _hdr; hp = skb_header_pointer(skb, ip_hdrlen(skb), - sizeof(_hdr), &_hdr); + iph->protocol == IPPROTO_UDP ? + sizeof(*hp) : sizeof(_hdr), + &_hdr); if (hp == NULL) return NULL; @@ -360,9 +363,11 @@ struct sock *xt_socket_lookup_slow_v6(struct net *net, } if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) { - struct udphdr _hdr, *hp; + struct udphdr *hp; + struct tcphdr _hdr; - hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + hp = skb_header_pointer(skb, thoff, tproto == IPPROTO_UDP ? + sizeof(*hp) : sizeof(_hdr), &_hdr); if (hp == NULL) return NULL;