Skip to content

Commit 32c1733

Browse files
Subash Abhinov Kasiviswanathanummakynes
authored andcommitted
netfilter: nf_socket: Fix out of bounds access in nf_sk_lookup_slow_v{4,6}
skb_header_pointer will copy data into a buffer if data is non linear, otherwise it will return a pointer in the linear section of the data. nf_sk_lookup_slow_v{4,6} always copies data of size udphdr but later accesses memory within the size of tcphdr (th->doff) in case of TCP packets. This causes a crash when running with KASAN with the following call stack - BUG: KASAN: stack-out-of-bounds in xt_socket_lookup_slow_v4+0x524/0x718 net/netfilter/xt_socket.c:178 Read of size 2 at addr ffffffe3d417a87c by task syz-executor/28971 CPU: 2 PID: 28971 Comm: syz-executor Tainted: G B W O 4.9.65+ #1 Call trace: [<ffffff9467e8d390>] dump_backtrace+0x0/0x428 arch/arm64/kernel/traps.c:76 [<ffffff9467e8d7e0>] show_stack+0x28/0x38 arch/arm64/kernel/traps.c:226 [<ffffff946842d9b8>] __dump_stack lib/dump_stack.c:15 [inline] [<ffffff946842d9b8>] dump_stack+0xd4/0x124 lib/dump_stack.c:51 [<ffffff946811d4b0>] print_address_description+0x68/0x258 mm/kasan/report.c:248 [<ffffff946811d8c8>] kasan_report_error mm/kasan/report.c:347 [inline] [<ffffff946811d8c8>] kasan_report.part.2+0x228/0x2f0 mm/kasan/report.c:371 [<ffffff946811df44>] kasan_report+0x5c/0x70 mm/kasan/report.c:372 [<ffffff946811bebc>] check_memory_region_inline mm/kasan/kasan.c:308 [inline] [<ffffff946811bebc>] __asan_load2+0x84/0x98 mm/kasan/kasan.c:739 [<ffffff94694d6f04>] __tcp_hdrlen include/linux/tcp.h:35 [inline] [<ffffff94694d6f04>] xt_socket_lookup_slow_v4+0x524/0x718 net/netfilter/xt_socket.c:178 Fix this by copying data into appropriate size headers based on protocol. Fixes: a583636 ("inet: refactor inet[6]_lookup functions to take skb") Signed-off-by: Tejaswi Tanikella <[email protected]> Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 90d2723 commit 32c1733

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

net/ipv4/netfilter/nf_socket_ipv4.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,12 @@ struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb,
108108
int doff = 0;
109109

110110
if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
111-
struct udphdr _hdr, *hp;
111+
struct tcphdr _hdr;
112+
struct udphdr *hp;
112113

113114
hp = skb_header_pointer(skb, ip_hdrlen(skb),
114-
sizeof(_hdr), &_hdr);
115+
iph->protocol == IPPROTO_UDP ?
116+
sizeof(*hp) : sizeof(_hdr), &_hdr);
115117
if (hp == NULL)
116118
return NULL;
117119

net/ipv6/netfilter/nf_socket_ipv6.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
116116
}
117117

118118
if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) {
119-
struct udphdr _hdr, *hp;
119+
struct tcphdr _hdr;
120+
struct udphdr *hp;
120121

121-
hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr);
122+
hp = skb_header_pointer(skb, thoff, tproto == IPPROTO_UDP ?
123+
sizeof(*hp) : sizeof(_hdr), &_hdr);
122124
if (hp == NULL)
123125
return NULL;
124126

0 commit comments

Comments
 (0)