]>
Commit | Line | Data |
---|---|---|
3fefb5f6 GKH |
1 | From foo@baz Thu Mar 14 23:19:55 PDT 2019 |
2 | From: Christoph Paasch <cpaasch@apple.com> | |
3 | Date: Mon, 11 Mar 2019 11:41:05 -0700 | |
4 | Subject: tcp: Don't access TCP_SKB_CB before initializing it | |
5 | ||
6 | From: Christoph Paasch <cpaasch@apple.com> | |
7 | ||
8 | [ Upstream commit f2feaefdabb0a6253aa020f65e7388f07a9ed47c ] | |
9 | ||
10 | Since commit eeea10b83a13 ("tcp: add | |
11 | tcp_v4_fill_cb()/tcp_v4_restore_cb()"), tcp_vX_fill_cb is only called | |
12 | after tcp_filter(). That means, TCP_SKB_CB(skb)->end_seq still points to | |
13 | the IP-part of the cb. | |
14 | ||
15 | We thus should not mock with it, as this can trigger bugs (thanks | |
16 | syzkaller): | |
17 | [ 12.349396] ================================================================== | |
18 | [ 12.350188] BUG: KASAN: slab-out-of-bounds in ip6_datagram_recv_specific_ctl+0x19b3/0x1a20 | |
19 | [ 12.351035] Read of size 1 at addr ffff88006adbc208 by task test_ip6_datagr/1799 | |
20 | ||
21 | Setting end_seq is actually no more necessary in tcp_filter as it gets | |
22 | initialized later on in tcp_vX_fill_cb. | |
23 | ||
24 | Cc: Eric Dumazet <edumazet@google.com> | |
25 | Fixes: eeea10b83a13 ("tcp: add tcp_v4_fill_cb()/tcp_v4_restore_cb()") | |
26 | Signed-off-by: Christoph Paasch <cpaasch@apple.com> | |
27 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
28 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
29 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
30 | --- | |
31 | net/ipv4/tcp_ipv4.c | 9 +-------- | |
32 | 1 file changed, 1 insertion(+), 8 deletions(-) | |
33 | ||
34 | --- a/net/ipv4/tcp_ipv4.c | |
35 | +++ b/net/ipv4/tcp_ipv4.c | |
36 | @@ -1734,15 +1734,8 @@ EXPORT_SYMBOL(tcp_add_backlog); | |
37 | int tcp_filter(struct sock *sk, struct sk_buff *skb) | |
38 | { | |
39 | struct tcphdr *th = (struct tcphdr *)skb->data; | |
40 | - unsigned int eaten = skb->len; | |
41 | - int err; | |
42 | ||
43 | - err = sk_filter_trim_cap(sk, skb, th->doff * 4); | |
44 | - if (!err) { | |
45 | - eaten -= skb->len; | |
46 | - TCP_SKB_CB(skb)->end_seq -= eaten; | |
47 | - } | |
48 | - return err; | |
49 | + return sk_filter_trim_cap(sk, skb, th->doff * 4); | |
50 | } | |
51 | EXPORT_SYMBOL(tcp_filter); | |
52 |