OSDN Git Service

nf: xt_socket: Fix out-of-bounds in xt_socket_lookup_slow_v{4,6}
authorTejaswi Tanikella <tejaswit@codeaurora.org>
Fri, 5 Jan 2018 07:10:48 +0000 (12:40 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Wed, 28 Mar 2018 14:43:00 +0000 (07:43 -0700)
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 <tejaswit@codeaurora.org>
net/netfilter/xt_socket.c

index ede5406..9398218 100644 (file)
@@ -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;