diff mbox series

[bionic/linux] tcp: make sure treq->af_specific is initialized

Message ID 20220802132703.20599-1-tim.gardner@canonical.com
State New
Headers show
Series [bionic/linux] tcp: make sure treq->af_specific is initialized | expand

Commit Message

Tim Gardner Aug. 2, 2022, 1:27 p.m. UTC
From: Eric Dumazet <edumazet@google.com>

BugLink: https://bugs.launchpad.net/bugs/1981658

commit ba5a4fdd63ae0c575707030db0b634b160baddd7 upstream.

syzbot complained about a recent change in TCP stack,
hitting a NULL pointer [1]

tcp request sockets have an af_specific pointer, which
was used before the blamed change only for SYNACK generation
in non SYNCOOKIE mode.

tcp requests sockets momentarily created when third packet
coming from client in SYNCOOKIE mode were not using
treq->af_specific.

Make sure this field is populated, in the same way normal
TCP requests sockets do in tcp_conn_request().

[1]
TCP: request_sock_TCPv6: Possible SYN flooding on port 20002. Sending cookies.  Check SNMP counters.
general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
CPU: 1 PID: 3695 Comm: syz-executor864 Not tainted 5.18.0-rc3-syzkaller-00224-g5fd1fe4807f9 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
RIP: 0010:tcp_create_openreq_child+0xe16/0x16b0 net/ipv4/tcp_minisocks.c:534
Code: 48 c1 ea 03 80 3c 02 00 0f 85 e5 07 00 00 4c 8b b3 28 01 00 00 48 b8 00 00 00 00 00 fc ff df 49 8d 7e 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 c9 07 00 00 48 8b 3c 24 48 89 de 41 ff 56 08 48
RSP: 0018:ffffc90000de0588 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: ffff888076490330 RCX: 0000000000000100
RDX: 0000000000000001 RSI: ffffffff87d67ff0 RDI: 0000000000000008
RBP: ffff88806ee1c7f8 R08: 0000000000000000 R09: 0000000000000000
R10: ffffffff87d67f00 R11: 0000000000000000 R12: ffff88806ee1bfc0
R13: ffff88801b0e0368 R14: 0000000000000000 R15: 0000000000000000
FS:  00007f517fe58700(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007ffcead76960 CR3: 000000006f97b000 CR4: 00000000003506e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
 <IRQ>
 tcp_v6_syn_recv_sock+0x199/0x23b0 net/ipv6/tcp_ipv6.c:1267
 tcp_get_cookie_sock+0xc9/0x850 net/ipv4/syncookies.c:207
 cookie_v6_check+0x15c3/0x2340 net/ipv6/syncookies.c:258
 tcp_v6_cookie_check net/ipv6/tcp_ipv6.c:1131 [inline]
 tcp_v6_do_rcv+0x1148/0x13b0 net/ipv6/tcp_ipv6.c:1486
 tcp_v6_rcv+0x3305/0x3840 net/ipv6/tcp_ipv6.c:1725
 ip6_protocol_deliver_rcu+0x2e9/0x1900 net/ipv6/ip6_input.c:422
 ip6_input_finish+0x14c/0x2c0 net/ipv6/ip6_input.c:464
 NF_HOOK include/linux/netfilter.h:307 [inline]
 NF_HOOK include/linux/netfilter.h:301 [inline]
 ip6_input+0x9c/0xd0 net/ipv6/ip6_input.c:473
 dst_input include/net/dst.h:461 [inline]
 ip6_rcv_finish net/ipv6/ip6_input.c:76 [inline]
 NF_HOOK include/linux/netfilter.h:307 [inline]
 NF_HOOK include/linux/netfilter.h:301 [inline]
 ipv6_rcv+0x27f/0x3b0 net/ipv6/ip6_input.c:297
 __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5405
 __netif_receive_skb+0x24/0x1b0 net/core/dev.c:5519
 process_backlog+0x3a0/0x7c0 net/core/dev.c:5847
 __napi_poll+0xb3/0x6e0 net/core/dev.c:6413
 napi_poll net/core/dev.c:6480 [inline]
 net_rx_action+0x8ec/0xc60 net/core/dev.c:6567
 __do_softirq+0x29b/0x9c2 kernel/softirq.c:558
 invoke_softirq kernel/softirq.c:432 [inline]
 __irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
 irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
 sysvec_apic_timer_interrupt+0x93/0xc0 arch/x86/kernel/apic/apic.c:1097

Fixes: 5b0b9e4c2c89 ("tcp: md5: incorrect tcp_header_len for incoming connections")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[fruggeri: Account for backport conflicts from 35b2c3211609 and 6fc8c827dd4f]
Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 6c2176f5ad48095aa1e2608b51bada5bebc568c1 linux-4.19.y)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---

This patch necessitates a respin for all 4.15 based kernels.

---
 include/net/tcp.h     | 5 +++++
 net/ipv4/syncookies.c | 1 +
 net/ipv4/tcp_ipv4.c   | 2 +-
 net/ipv6/syncookies.c | 1 +
 net/ipv6/tcp_ipv6.c   | 2 +-
 5 files changed, 9 insertions(+), 2 deletions(-)

Comments

Luke Nowakowski-Krijger Aug. 2, 2022, 3:21 p.m. UTC | #1
Acked-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>

On Tue, Aug 2, 2022 at 6:27 AM Tim Gardner <tim.gardner@canonical.com>
wrote:

> From: Eric Dumazet <edumazet@google.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1981658
>
> commit ba5a4fdd63ae0c575707030db0b634b160baddd7 upstream.
>
> syzbot complained about a recent change in TCP stack,
> hitting a NULL pointer [1]
>
> tcp request sockets have an af_specific pointer, which
> was used before the blamed change only for SYNACK generation
> in non SYNCOOKIE mode.
>
> tcp requests sockets momentarily created when third packet
> coming from client in SYNCOOKIE mode were not using
> treq->af_specific.
>
> Make sure this field is populated, in the same way normal
> TCP requests sockets do in tcp_conn_request().
>
> [1]
> TCP: request_sock_TCPv6: Possible SYN flooding on port 20002. Sending
> cookies.  Check SNMP counters.
> general protection fault, probably for non-canonical address
> 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN
> KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
> CPU: 1 PID: 3695 Comm: syz-executor864 Not tainted
> 5.18.0-rc3-syzkaller-00224-g5fd1fe4807f9 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> RIP: 0010:tcp_create_openreq_child+0xe16/0x16b0
> net/ipv4/tcp_minisocks.c:534
> Code: 48 c1 ea 03 80 3c 02 00 0f 85 e5 07 00 00 4c 8b b3 28 01 00 00 48 b8
> 00 00 00 00 00 fc ff df 49 8d 7e 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f
> 85 c9 07 00 00 48 8b 3c 24 48 89 de 41 ff 56 08 48
> RSP: 0018:ffffc90000de0588 EFLAGS: 00010202
> RAX: dffffc0000000000 RBX: ffff888076490330 RCX: 0000000000000100
> RDX: 0000000000000001 RSI: ffffffff87d67ff0 RDI: 0000000000000008
> RBP: ffff88806ee1c7f8 R08: 0000000000000000 R09: 0000000000000000
> R10: ffffffff87d67f00 R11: 0000000000000000 R12: ffff88806ee1bfc0
> R13: ffff88801b0e0368 R14: 0000000000000000 R15: 0000000000000000
> FS:  00007f517fe58700(0000) GS:ffff8880b9d00000(0000)
> knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007ffcead76960 CR3: 000000006f97b000 CR4: 00000000003506e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>  <IRQ>
>  tcp_v6_syn_recv_sock+0x199/0x23b0 net/ipv6/tcp_ipv6.c:1267
>  tcp_get_cookie_sock+0xc9/0x850 net/ipv4/syncookies.c:207
>  cookie_v6_check+0x15c3/0x2340 net/ipv6/syncookies.c:258
>  tcp_v6_cookie_check net/ipv6/tcp_ipv6.c:1131 [inline]
>  tcp_v6_do_rcv+0x1148/0x13b0 net/ipv6/tcp_ipv6.c:1486
>  tcp_v6_rcv+0x3305/0x3840 net/ipv6/tcp_ipv6.c:1725
>  ip6_protocol_deliver_rcu+0x2e9/0x1900 net/ipv6/ip6_input.c:422
>  ip6_input_finish+0x14c/0x2c0 net/ipv6/ip6_input.c:464
>  NF_HOOK include/linux/netfilter.h:307 [inline]
>  NF_HOOK include/linux/netfilter.h:301 [inline]
>  ip6_input+0x9c/0xd0 net/ipv6/ip6_input.c:473
>  dst_input include/net/dst.h:461 [inline]
>  ip6_rcv_finish net/ipv6/ip6_input.c:76 [inline]
>  NF_HOOK include/linux/netfilter.h:307 [inline]
>  NF_HOOK include/linux/netfilter.h:301 [inline]
>  ipv6_rcv+0x27f/0x3b0 net/ipv6/ip6_input.c:297
>  __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5405
>  __netif_receive_skb+0x24/0x1b0 net/core/dev.c:5519
>  process_backlog+0x3a0/0x7c0 net/core/dev.c:5847
>  __napi_poll+0xb3/0x6e0 net/core/dev.c:6413
>  napi_poll net/core/dev.c:6480 [inline]
>  net_rx_action+0x8ec/0xc60 net/core/dev.c:6567
>  __do_softirq+0x29b/0x9c2 kernel/softirq.c:558
>  invoke_softirq kernel/softirq.c:432 [inline]
>  __irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
>  irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
>  sysvec_apic_timer_interrupt+0x93/0xc0 arch/x86/kernel/apic/apic.c:1097
>
> Fixes: 5b0b9e4c2c89 ("tcp: md5: incorrect tcp_header_len for incoming
> connections")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> [fruggeri: Account for backport conflicts from 35b2c3211609 and
> 6fc8c827dd4f]
> Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> (cherry picked from commit 6c2176f5ad48095aa1e2608b51bada5bebc568c1
> linux-4.19.y)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>
> This patch necessitates a respin for all 4.15 based kernels.
>
> ---
>  include/net/tcp.h     | 5 +++++
>  net/ipv4/syncookies.c | 1 +
>  net/ipv4/tcp_ipv4.c   | 2 +-
>  net/ipv6/syncookies.c | 1 +
>  net/ipv6/tcp_ipv6.c   | 2 +-
>  5 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 6f8c1aab59d1..8750147b15ca 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1870,6 +1870,11 @@ struct tcp_request_sock_ops {
>                            enum tcp_synack_type synack_type);
>  };
>
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops;
> +#if IS_ENABLED(CONFIG_IPV6)
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops;
> +#endif
> +
>  #ifdef CONFIG_SYN_COOKIES
>  static inline __u32 cookie_init_sequence(const struct
> tcp_request_sock_ops *ops,
>                                          const struct sock *sk, struct
> sk_buff *skb,
> diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
> index 7e43d867fe21..7c1f1131b965 100644
> --- a/net/ipv4/syncookies.c
> +++ b/net/ipv4/syncookies.c
> @@ -337,6 +337,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct
> sk_buff *skb)
>
>         ireq = inet_rsk(req);
>         treq = tcp_rsk(req);
> +       treq->af_specific       = &tcp_request_sock_ipv4_ops;
>         treq->rcv_isn           = ntohl(th->seq) - 1;
>         treq->snt_isn           = cookie;
>         treq->ts_off            = 0;
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 8dd878f18aa7..e14183cf8b2a 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1306,7 +1306,7 @@ struct request_sock_ops tcp_request_sock_ops
> __read_mostly = {
>         .syn_ack_timeout =      tcp_syn_ack_timeout,
>  };
>
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
>         .mss_clamp      =       TCP_MSS_DEFAULT,
>  #ifdef CONFIG_TCP_MD5SIG
>         .req_md5_lookup =       tcp_v4_md5_lookup,
> diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
> index 4e6c886f1b73..84b2858f82c0 100644
> --- a/net/ipv6/syncookies.c
> +++ b/net/ipv6/syncookies.c
> @@ -181,6 +181,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct
> sk_buff *skb)
>
>         ireq = inet_rsk(req);
>         treq = tcp_rsk(req);
> +       treq->af_specific = &tcp_request_sock_ipv6_ops;
>         treq->tfo_listener = false;
>
>         if (security_inet_conn_request(sk, skb, req))
> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> index faad76566be3..3a0d50ac30e1 100644
> --- a/net/ipv6/tcp_ipv6.c
> +++ b/net/ipv6/tcp_ipv6.c
> @@ -774,7 +774,7 @@ struct request_sock_ops tcp6_request_sock_ops
> __read_mostly = {
>         .syn_ack_timeout =      tcp_syn_ack_timeout,
>  };
>
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
>         .mss_clamp      =       IPV6_MIN_MTU - sizeof(struct tcphdr) -
>                                 sizeof(struct ipv6hdr),
>  #ifdef CONFIG_TCP_MD5SIG
> --
> 2.37.1
>
>
> --
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
Marcelo Henrique Cerri Aug. 2, 2022, 4:47 p.m. UTC | #2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512


LGTM

Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>

On Tue, Aug 02 2022, Tim Gardner wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1981658
>
> commit ba5a4fdd63ae0c575707030db0b634b160baddd7 upstream.
>
> syzbot complained about a recent change in TCP stack,
> hitting a NULL pointer [1]
>
> tcp request sockets have an af_specific pointer, which
> was used before the blamed change only for SYNACK generation
> in non SYNCOOKIE mode.
>
> tcp requests sockets momentarily created when third packet
> coming from client in SYNCOOKIE mode were not using
> treq->af_specific.
>
> Make sure this field is populated, in the same way normal
> TCP requests sockets do in tcp_conn_request().
>
> [1]
> TCP: request_sock_TCPv6: Possible SYN flooding on port 20002. Sending cookies.  Check SNMP counters.
> general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN
> KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
> CPU: 1 PID: 3695 Comm: syz-executor864 Not tainted 5.18.0-rc3-syzkaller-00224-g5fd1fe4807f9 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> RIP: 0010:tcp_create_openreq_child+0xe16/0x16b0 net/ipv4/tcp_minisocks.c:534
> Code: 48 c1 ea 03 80 3c 02 00 0f 85 e5 07 00 00 4c 8b b3 28 01 00 00 48 b8 00 00 00 00 00 fc ff df 49 8d 7e 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 c9 07 00 00 48 8b 3c 24 48 89 de 41 ff 56 08 48
> RSP: 0018:ffffc90000de0588 EFLAGS: 00010202
> RAX: dffffc0000000000 RBX: ffff888076490330 RCX: 0000000000000100
> RDX: 0000000000000001 RSI: ffffffff87d67ff0 RDI: 0000000000000008
> RBP: ffff88806ee1c7f8 R08: 0000000000000000 R09: 0000000000000000
> R10: ffffffff87d67f00 R11: 0000000000000000 R12: ffff88806ee1bfc0
> R13: ffff88801b0e0368 R14: 0000000000000000 R15: 0000000000000000
> FS:  00007f517fe58700(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007ffcead76960 CR3: 000000006f97b000 CR4: 00000000003506e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>  <IRQ>
>  tcp_v6_syn_recv_sock+0x199/0x23b0 net/ipv6/tcp_ipv6.c:1267
>  tcp_get_cookie_sock+0xc9/0x850 net/ipv4/syncookies.c:207
>  cookie_v6_check+0x15c3/0x2340 net/ipv6/syncookies.c:258
>  tcp_v6_cookie_check net/ipv6/tcp_ipv6.c:1131 [inline]
>  tcp_v6_do_rcv+0x1148/0x13b0 net/ipv6/tcp_ipv6.c:1486
>  tcp_v6_rcv+0x3305/0x3840 net/ipv6/tcp_ipv6.c:1725
>  ip6_protocol_deliver_rcu+0x2e9/0x1900 net/ipv6/ip6_input.c:422
>  ip6_input_finish+0x14c/0x2c0 net/ipv6/ip6_input.c:464
>  NF_HOOK include/linux/netfilter.h:307 [inline]
>  NF_HOOK include/linux/netfilter.h:301 [inline]
>  ip6_input+0x9c/0xd0 net/ipv6/ip6_input.c:473
>  dst_input include/net/dst.h:461 [inline]
>  ip6_rcv_finish net/ipv6/ip6_input.c:76 [inline]
>  NF_HOOK include/linux/netfilter.h:307 [inline]
>  NF_HOOK include/linux/netfilter.h:301 [inline]
>  ipv6_rcv+0x27f/0x3b0 net/ipv6/ip6_input.c:297
>  __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5405
>  __netif_receive_skb+0x24/0x1b0 net/core/dev.c:5519
>  process_backlog+0x3a0/0x7c0 net/core/dev.c:5847
>  __napi_poll+0xb3/0x6e0 net/core/dev.c:6413
>  napi_poll net/core/dev.c:6480 [inline]
>  net_rx_action+0x8ec/0xc60 net/core/dev.c:6567
>  __do_softirq+0x29b/0x9c2 kernel/softirq.c:558
>  invoke_softirq kernel/softirq.c:432 [inline]
>  __irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
>  irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
>  sysvec_apic_timer_interrupt+0x93/0xc0 arch/x86/kernel/apic/apic.c:1097
>
> Fixes: 5b0b9e4c2c89 ("tcp: md5: incorrect tcp_header_len for incoming connections")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> [fruggeri: Account for backport conflicts from 35b2c3211609 and 6fc8c827dd4f]
> Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> (cherry picked from commit 6c2176f5ad48095aa1e2608b51bada5bebc568c1 linux-4.19.y)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>
> This patch necessitates a respin for all 4.15 based kernels.
>
> ---
>  include/net/tcp.h     | 5 +++++
>  net/ipv4/syncookies.c | 1 +
>  net/ipv4/tcp_ipv4.c   | 2 +-
>  net/ipv6/syncookies.c | 1 +
>  net/ipv6/tcp_ipv6.c   | 2 +-
>  5 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 6f8c1aab59d1..8750147b15ca 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1870,6 +1870,11 @@ struct tcp_request_sock_ops {
>  			   enum tcp_synack_type synack_type);
>  };
>
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops;
> +#if IS_ENABLED(CONFIG_IPV6)
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops;
> +#endif
> +
>  #ifdef CONFIG_SYN_COOKIES
>  static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops,
>  					 const struct sock *sk, struct sk_buff *skb,
> diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
> index 7e43d867fe21..7c1f1131b965 100644
> --- a/net/ipv4/syncookies.c
> +++ b/net/ipv4/syncookies.c
> @@ -337,6 +337,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
>
>  	ireq = inet_rsk(req);
>  	treq = tcp_rsk(req);
> +	treq->af_specific	= &tcp_request_sock_ipv4_ops;
>  	treq->rcv_isn		= ntohl(th->seq) - 1;
>  	treq->snt_isn		= cookie;
>  	treq->ts_off		= 0;
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 8dd878f18aa7..e14183cf8b2a 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1306,7 +1306,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = {
>  	.syn_ack_timeout =	tcp_syn_ack_timeout,
>  };
>
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
>  	.mss_clamp	=	TCP_MSS_DEFAULT,
>  #ifdef CONFIG_TCP_MD5SIG
>  	.req_md5_lookup	=	tcp_v4_md5_lookup,
> diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
> index 4e6c886f1b73..84b2858f82c0 100644
> --- a/net/ipv6/syncookies.c
> +++ b/net/ipv6/syncookies.c
> @@ -181,6 +181,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
>
>  	ireq = inet_rsk(req);
>  	treq = tcp_rsk(req);
> +	treq->af_specific = &tcp_request_sock_ipv6_ops;
>  	treq->tfo_listener = false;
>
>  	if (security_inet_conn_request(sk, skb, req))
> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> index faad76566be3..3a0d50ac30e1 100644
> --- a/net/ipv6/tcp_ipv6.c
> +++ b/net/ipv6/tcp_ipv6.c
> @@ -774,7 +774,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
>  	.syn_ack_timeout =	tcp_syn_ack_timeout,
>  };
>
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
>  	.mss_clamp	=	IPV6_MIN_MTU - sizeof(struct tcphdr) -
>  				sizeof(struct ipv6hdr),
>  #ifdef CONFIG_TCP_MD5SIG
> --
> 2.37.1

- --
Regards,
Marcelo
-----BEGIN PGP SIGNATURE-----

iQHQBAEBCgA6FiEExJjLjAfVL0XbfEr56e82LoessAkFAmLpVUMcHG1hcmNlbG8u
Y2VycmlAY2Fub25pY2FsLmNvbQAKCRDp7zYuh6ywCSCCDACY5qRk73zeD/8jpDBn
l8GW5UyDyNOKJ7UTgDA0+uWiszvb8G8KB3+3vgeUAXrzc7Ojv+UmCwUmUTXnfPCp
KqneEMhxDwSXfHPmFvFLPhtDqg+42xce0tgNpVuzqCh2LwZZavSP3TBXEDrvX/sw
R2lMeAp7esicnpgFaLKn9HgykCV1GsqUmsasL9JxlHTFYIOrYUET9HzzSw+yBpt2
S9iVtjtO2LywNH8vUUZVvUWONs8A2TbklpWpXbLpGMLJAMhv7Z4h76b4bp5g/PlG
BDv8iDcAmM7DjaBBq2K7IRkzq9xEFwRwECyTYv8ELlr7k/vMrBuJE3pbyixOScCO
gZxGPuNIj5/itlDA31Vr6p8sMLfdkWnUpIqlyV0NK9pQGAdIiQMw62iRbYpLrITc
ImvnaoexJVLkq080uVzvRbQcyY+eONTrpt4hLYGMASp43ypytYGE3gjp7T7QM+Zx
hTR63DBM9fyVNvj3kDM7R8DFyHpLydr5xZLEWpEkygZjBuU=
=8nvu
-----END PGP SIGNATURE-----
Stefan Bader Aug. 23, 2022, 7:22 a.m. UTC | #3
On 02.08.22 15:27, Tim Gardner wrote:
> From: Eric Dumazet <edumazet@google.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1981658
> 
> commit ba5a4fdd63ae0c575707030db0b634b160baddd7 upstream.
> 
> syzbot complained about a recent change in TCP stack,
> hitting a NULL pointer [1]
> 
> tcp request sockets have an af_specific pointer, which
> was used before the blamed change only for SYNACK generation
> in non SYNCOOKIE mode.
> 
> tcp requests sockets momentarily created when third packet
> coming from client in SYNCOOKIE mode were not using
> treq->af_specific.
> 
> Make sure this field is populated, in the same way normal
> TCP requests sockets do in tcp_conn_request().
> 
> [1]
> TCP: request_sock_TCPv6: Possible SYN flooding on port 20002. Sending cookies.  Check SNMP counters.
> general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] PREEMPT SMP KASAN
> KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
> CPU: 1 PID: 3695 Comm: syz-executor864 Not tainted 5.18.0-rc3-syzkaller-00224-g5fd1fe4807f9 #0
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> RIP: 0010:tcp_create_openreq_child+0xe16/0x16b0 net/ipv4/tcp_minisocks.c:534
> Code: 48 c1 ea 03 80 3c 02 00 0f 85 e5 07 00 00 4c 8b b3 28 01 00 00 48 b8 00 00 00 00 00 fc ff df 49 8d 7e 08 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 c9 07 00 00 48 8b 3c 24 48 89 de 41 ff 56 08 48
> RSP: 0018:ffffc90000de0588 EFLAGS: 00010202
> RAX: dffffc0000000000 RBX: ffff888076490330 RCX: 0000000000000100
> RDX: 0000000000000001 RSI: ffffffff87d67ff0 RDI: 0000000000000008
> RBP: ffff88806ee1c7f8 R08: 0000000000000000 R09: 0000000000000000
> R10: ffffffff87d67f00 R11: 0000000000000000 R12: ffff88806ee1bfc0
> R13: ffff88801b0e0368 R14: 0000000000000000 R15: 0000000000000000
> FS:  00007f517fe58700(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00007ffcead76960 CR3: 000000006f97b000 CR4: 00000000003506e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>   <IRQ>
>   tcp_v6_syn_recv_sock+0x199/0x23b0 net/ipv6/tcp_ipv6.c:1267
>   tcp_get_cookie_sock+0xc9/0x850 net/ipv4/syncookies.c:207
>   cookie_v6_check+0x15c3/0x2340 net/ipv6/syncookies.c:258
>   tcp_v6_cookie_check net/ipv6/tcp_ipv6.c:1131 [inline]
>   tcp_v6_do_rcv+0x1148/0x13b0 net/ipv6/tcp_ipv6.c:1486
>   tcp_v6_rcv+0x3305/0x3840 net/ipv6/tcp_ipv6.c:1725
>   ip6_protocol_deliver_rcu+0x2e9/0x1900 net/ipv6/ip6_input.c:422
>   ip6_input_finish+0x14c/0x2c0 net/ipv6/ip6_input.c:464
>   NF_HOOK include/linux/netfilter.h:307 [inline]
>   NF_HOOK include/linux/netfilter.h:301 [inline]
>   ip6_input+0x9c/0xd0 net/ipv6/ip6_input.c:473
>   dst_input include/net/dst.h:461 [inline]
>   ip6_rcv_finish net/ipv6/ip6_input.c:76 [inline]
>   NF_HOOK include/linux/netfilter.h:307 [inline]
>   NF_HOOK include/linux/netfilter.h:301 [inline]
>   ipv6_rcv+0x27f/0x3b0 net/ipv6/ip6_input.c:297
>   __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5405
>   __netif_receive_skb+0x24/0x1b0 net/core/dev.c:5519
>   process_backlog+0x3a0/0x7c0 net/core/dev.c:5847
>   __napi_poll+0xb3/0x6e0 net/core/dev.c:6413
>   napi_poll net/core/dev.c:6480 [inline]
>   net_rx_action+0x8ec/0xc60 net/core/dev.c:6567
>   __do_softirq+0x29b/0x9c2 kernel/softirq.c:558
>   invoke_softirq kernel/softirq.c:432 [inline]
>   __irq_exit_rcu+0x123/0x180 kernel/softirq.c:637
>   irq_exit_rcu+0x5/0x20 kernel/softirq.c:649
>   sysvec_apic_timer_interrupt+0x93/0xc0 arch/x86/kernel/apic/apic.c:1097
> 
> Fixes: 5b0b9e4c2c89 ("tcp: md5: incorrect tcp_header_len for incoming connections")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> [fruggeri: Account for backport conflicts from 35b2c3211609 and 6fc8c827dd4f]
> Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> (cherry picked from commit 6c2176f5ad48095aa1e2608b51bada5bebc568c1 linux-4.19.y)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
> 
> This patch necessitates a respin for all 4.15 based kernels.
> 
> ---

Applied to bionic:linux and already released in Ubuntu-4.15.0-191.202. Thanks.

-Stefan

>   include/net/tcp.h     | 5 +++++
>   net/ipv4/syncookies.c | 1 +
>   net/ipv4/tcp_ipv4.c   | 2 +-
>   net/ipv6/syncookies.c | 1 +
>   net/ipv6/tcp_ipv6.c   | 2 +-
>   5 files changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 6f8c1aab59d1..8750147b15ca 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1870,6 +1870,11 @@ struct tcp_request_sock_ops {
>   			   enum tcp_synack_type synack_type);
>   };
>   
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops;
> +#if IS_ENABLED(CONFIG_IPV6)
> +extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops;
> +#endif
> +
>   #ifdef CONFIG_SYN_COOKIES
>   static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops,
>   					 const struct sock *sk, struct sk_buff *skb,
> diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
> index 7e43d867fe21..7c1f1131b965 100644
> --- a/net/ipv4/syncookies.c
> +++ b/net/ipv4/syncookies.c
> @@ -337,6 +337,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
>   
>   	ireq = inet_rsk(req);
>   	treq = tcp_rsk(req);
> +	treq->af_specific	= &tcp_request_sock_ipv4_ops;
>   	treq->rcv_isn		= ntohl(th->seq) - 1;
>   	treq->snt_isn		= cookie;
>   	treq->ts_off		= 0;
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 8dd878f18aa7..e14183cf8b2a 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -1306,7 +1306,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = {
>   	.syn_ack_timeout =	tcp_syn_ack_timeout,
>   };
>   
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
>   	.mss_clamp	=	TCP_MSS_DEFAULT,
>   #ifdef CONFIG_TCP_MD5SIG
>   	.req_md5_lookup	=	tcp_v4_md5_lookup,
> diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
> index 4e6c886f1b73..84b2858f82c0 100644
> --- a/net/ipv6/syncookies.c
> +++ b/net/ipv6/syncookies.c
> @@ -181,6 +181,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
>   
>   	ireq = inet_rsk(req);
>   	treq = tcp_rsk(req);
> +	treq->af_specific = &tcp_request_sock_ipv6_ops;
>   	treq->tfo_listener = false;
>   
>   	if (security_inet_conn_request(sk, skb, req))
> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> index faad76566be3..3a0d50ac30e1 100644
> --- a/net/ipv6/tcp_ipv6.c
> +++ b/net/ipv6/tcp_ipv6.c
> @@ -774,7 +774,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
>   	.syn_ack_timeout =	tcp_syn_ack_timeout,
>   };
>   
> -static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
> +const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
>   	.mss_clamp	=	IPV6_MIN_MTU - sizeof(struct tcphdr) -
>   				sizeof(struct ipv6hdr),
>   #ifdef CONFIG_TCP_MD5SIG
diff mbox series

Patch

diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6f8c1aab59d1..8750147b15ca 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1870,6 +1870,11 @@  struct tcp_request_sock_ops {
 			   enum tcp_synack_type synack_type);
 };
 
+extern const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops;
+#if IS_ENABLED(CONFIG_IPV6)
+extern const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops;
+#endif
+
 #ifdef CONFIG_SYN_COOKIES
 static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops,
 					 const struct sock *sk, struct sk_buff *skb,
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 7e43d867fe21..7c1f1131b965 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -337,6 +337,7 @@  struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
 
 	ireq = inet_rsk(req);
 	treq = tcp_rsk(req);
+	treq->af_specific	= &tcp_request_sock_ipv4_ops;
 	treq->rcv_isn		= ntohl(th->seq) - 1;
 	treq->snt_isn		= cookie;
 	treq->ts_off		= 0;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 8dd878f18aa7..e14183cf8b2a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1306,7 +1306,7 @@  struct request_sock_ops tcp_request_sock_ops __read_mostly = {
 	.syn_ack_timeout =	tcp_syn_ack_timeout,
 };
 
-static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
+const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
 	.mss_clamp	=	TCP_MSS_DEFAULT,
 #ifdef CONFIG_TCP_MD5SIG
 	.req_md5_lookup	=	tcp_v4_md5_lookup,
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 4e6c886f1b73..84b2858f82c0 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -181,6 +181,7 @@  struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 
 	ireq = inet_rsk(req);
 	treq = tcp_rsk(req);
+	treq->af_specific = &tcp_request_sock_ipv6_ops;
 	treq->tfo_listener = false;
 
 	if (security_inet_conn_request(sk, skb, req))
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index faad76566be3..3a0d50ac30e1 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -774,7 +774,7 @@  struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
 	.syn_ack_timeout =	tcp_syn_ack_timeout,
 };
 
-static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
+const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
 	.mss_clamp	=	IPV6_MIN_MTU - sizeof(struct tcphdr) -
 				sizeof(struct ipv6hdr),
 #ifdef CONFIG_TCP_MD5SIG