lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAPhRvkxWPC1F6XOJMNJeDufz0mELLLCSKhw0vqjrAT5bHQxWAA@mail.gmail.com>
Date: Thu, 11 Sep 2025 10:03:36 -0300
From: Anderson Nascimento <anderson@...elesecurity.com>
To: edumazet@...gle.com, ncardwell@...gle.com, kuniyu@...gle.com, 
	davem@...emloft.net, dsahern@...nel.org, kuba@...nel.org, pabeni@...hat.com, 
	horms@...nel.org, netdev@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] net/tcp: Fix a NULL pointer dereference when using
 TCP-AO with TCP_REPAIR.

On Thu, Sep 11, 2025 at 12:48 AM Anderson Nascimento
<anderson@...elesecurity.com> wrote:
>
> A NULL pointer dereference can occur in tcp_ao_finish_connect() during a
> connect() system call on a socket with a TCP-AO key added and TCP_REPAIR
> enabled.
>
> The function is called with skb being NULL and attempts to dereference it
> on tcp_hdr(skb)->seq without a prior skb validation.
>
> Fix this by checking if skb is NULL before dereferencing it. If skb is
> not NULL, the ao->risn is set to tcp_hdr(skb)->seq. If skb is NULL,
> ao->risn is set to 0 to keep compatibility with calls made from
> tcp_rcv_synsent_state_process().

The description here should be:

If skb is not NULL, the ao->risn is set to tcp_hdr(skb)->seq to keep
compatibility with the call made from tcp_rcv_synsent_state_process().
If skb is NULL, ao->risn is set to 0.

>
> int main(void){
>         struct sockaddr_in sockaddr;
>         struct tcp_ao_add tcp_ao;
>         int sk;
>         int one = 1;
>
>         memset(&sockaddr,'\0',sizeof(sockaddr));
>         memset(&tcp_ao,'\0',sizeof(tcp_ao));
>
>         sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
>
>         sockaddr.sin_family = AF_INET;
>
>         memcpy(tcp_ao.alg_name,"cmac(aes128)",12);
>         memcpy(tcp_ao.key,"ABCDEFGHABCDEFGH",16);
>         tcp_ao.keylen = 16;
>
>         memcpy(&tcp_ao.addr,&sockaddr,sizeof(sockaddr));
>
>         setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tcp_ao,
>         sizeof(tcp_ao));
>         setsockopt(sk, IPPROTO_TCP, TCP_REPAIR, &one, sizeof(one));
>
>         sockaddr.sin_family = AF_INET;
>         sockaddr.sin_port = htobe16(123);
>
>         inet_aton("127.0.0.1", &sockaddr.sin_addr);
>
>         connect(sk,(struct sockaddr *)&sockaddr,sizeof(sockaddr));
>
> return 0;
> }
>
> $ gcc tcp-ao-nullptr.c -o tcp-ao-nullptr -Wall
> $ unshare -Urn
> # ip addr add 127.0.0.1 dev lo
> # ./tcp-ao-nullptr
>
> BUG: kernel NULL pointer dereference, address: 00000000000000b6
> PGD 1f648d067 P4D 1f648d067 PUD 1982e8067 PMD 0
> Oops: Oops: 0000 [#1] SMP NOPTI
> Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop
> Reference Platform, BIOS 6.00 11/12/2020
> RIP: 0010:tcp_ao_finish_connect (net/ipv4/tcp_ao.c:1182)
> Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 0f 1f 00 0f 1f
>  44 00 00 41 54 55 53 48 8b af 00 09 00 00 48 85 ed 74 3e <0f> b7 86 b6 00
>  00 00 48 8b 96 c8 00 00 00 49 89 fc 8b 44 02 04 c7
> All code
> ========
>    0:   90                      nop
>    1:   90                      nop
>    2:   90                      nop
>    3:   90                      nop
>    4:   90                      nop
>    5:   90                      nop
>    6:   90                      nop
>    7:   90                      nop
>    8:   90                      nop
>    9:   90                      nop
>    a:   90                      nop
>    b:   90                      nop
>    c:   90                      nop
>    d:   90                      nop
>    e:   90                      nop
>    f:   90                      nop
>   10:   90                      nop
>   11:   66 0f 1f 00             nopw   (%rax)
>   15:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   1a:   41 54                   push   %r12
>   1c:   55                      push   %rbp
>   1d:   53                      push   %rbx
>   1e:   48 8b af 00 09 00 00    mov    0x900(%rdi),%rbp
>   25:   48 85 ed                test   %rbp,%rbp
>   28:   74 3e                   je     0x68
>   2a:*  0f b7 86 b6 00 00 00    movzwl 0xb6(%rsi),%eax
> <-- trapping instruction
>   31:   48 8b 96 c8 00 00 00    mov    0xc8(%rsi),%rdx
>   38:   49 89 fc                mov    %rdi,%r12
>   3b:   8b 44 02 04             mov    0x4(%rdx,%rax,1),%eax
>   3f:   c7                      .byte 0xc7
>
> Code starting with the faulting instruction
> ===========================================
>    0:   0f b7 86 b6 00 00 00    movzwl 0xb6(%rsi),%eax
>    7:   48 8b 96 c8 00 00 00    mov    0xc8(%rsi),%rdx
>    e:   49 89 fc                mov    %rdi,%r12
>   11:   8b 44 02 04             mov    0x4(%rdx,%rax,1),%eax
>   15:   c7                      .byte 0xc7
> RSP: 0018:ffffcf7a858f3a50 EFLAGS: 00010282
> RAX: 0000000000000000 RBX: ffff8e51e8150000 RCX: 0000000000000002
> RDX: ffffcf7a858f3a1f RSI: 0000000000000000 RDI: ffff8e51e8150000
> RBP: ffff8e51c1509e80 R08: ffff8e51e81506bc R09: 0000000000000001
> R10: 0000000000000000 R11: ffff8e51e8150000 R12: 0000000000000000
> R13: ffff8e51c7019680 R14: ffff8e51d20d1cc0 R15: ffff8e51e8150000
> FS:  00007faa5e4dc740(0000) GS:ffff8e533e55f000(0000) knlGS:00000000000000
> 00
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000000000b6 CR3: 000000016d3e0003 CR4: 00000000003706f0
> Call Trace:
> <TASK>
> tcp_finish_connect (net/ipv4/tcp_input.c:6267)
> tcp_connect (net/ipv4/tcp_output.c:4141)
> tcp_v4_connect (net/ipv4/tcp_ipv4.c:345 (discriminator 1))
> __inet_stream_connect (net/ipv4/af_inet.c:677)
> ? release_sock (./include/linux/list.h:373 (discriminator 2) ./include/
> linux/wait.h:127 (discriminator 2) net/core/sock.c:3733 (discriminator 2))
>  inet_stream_connect (net/ipv4/af_inet.c:749)
> __sys_connect (./include/linux/file.h:62 (discriminator 1) ./include/linux
> /file.h:83 (discriminator 1) net/socket.c:2095 (discriminator 1))
> __x64_sys_connect (net/socket.c:2111 (discriminator 1) net/socket.c:2108
> (discriminator 1) net/socket.c:2108 (discriminator 1))
> do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/
> entry/syscall_64.c:94 (discriminator 1))
> ? do_read_fault (mm/memory.c:5565)
> ? handle_pte_fault (mm/memory.c:6047)
> ? do_fault (mm/memory.c:5707)
> ? __handle_mm_fault (mm/memory.c:5963 mm/memory.c:6131)
> ? count_memcg_events (mm/memcontrol.c:839 (discriminator 4))
> ? handle_mm_fault (mm/memory.c:6237 mm/memory.c:6390)
> ? do_user_addr_fault (arch/x86/mm/fault.c:1337)
> ? clear_bhb_loop (arch/x86/entry/entry_64.S:1548)
> ? clear_bhb_loop (arch/x86/entry/entry_64.S:1548)
> ? clear_bhb_loop (arch/x86/entry/entry_64.S:1548)
> entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
> RIP: 0033:0x7faa5e54d77e
> Code: 4d 89 d8 e8 d4 bc 00 00 4c 8b 5d f8 41 8b 93 08 03 00 00 59 5e 48 83
>  f8 fc 74 11 c9 c3 0f 1f 80 00 00 00 00 48 8b 45 10 0f 05 <c9> c3 83 e2 39
>  83 fa 08 75 e7 e8 13 ff ff ff 0f 1f 00 f3 0f 1e fa
> All code
> ========
>    0:   4d 89 d8                mov    %r11,%r8
>    3:   e8 d4 bc 00 00          call   0xbcdc
>    8:   4c 8b 5d f8             mov    -0x8(%rbp),%r11
>    c:   41 8b 93 08 03 00 00    mov    0x308(%r11),%edx
>   13:   59                      pop    %rcx
>   14:   5e                      pop    %rsi
>   15:   48 83 f8 fc             cmp    $0xfffffffffffffffc,%rax
>   19:   74 11                   je     0x2c
>   1b:   c9                      leave
>   1c:   c3                      ret
>   1d:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)
>   24:   48 8b 45 10             mov    0x10(%rbp),%rax
>   28:   0f 05                   syscall
>   2a:*  c9                      leave           <-- trapping instruction
>   2b:   c3                      ret
>   2c:   83 e2 39                and    $0x39,%edx
>   2f:   83 fa 08                cmp    $0x8,%edx
>   32:   75 e7                   jne    0x1b
>   34:   e8 13 ff ff ff          call   0xffffffffffffff4c
>   39:   0f 1f 00                nopl   (%rax)
>   3c:   f3 0f 1e fa             endbr64
>
> Code starting with the faulting instruction
> ===========================================
>    0:   c9                      leave
>    1:   c3                      ret
>    2:   83 e2 39                and    $0x39,%edx
>    5:   83 fa 08                cmp    $0x8,%edx
>    8:   75 e7                   jne    0xfffffffffffffff1
>    a:   e8 13 ff ff ff          call   0xffffffffffffff22
>    f:   0f 1f 00                nopl   (%rax)
>   12:   f3 0f 1e fa             endbr64
> RSP: 002b:00007ffc0e35e350 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
> RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007faa5e54d77e
> RDX: 0000000000000010 RSI: 00007ffc0e35e4e0 RDI: 0000000000000003
> RBP: 00007ffc0e35e360 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000202 R12: 00007ffc0e35e628
> R13: 0000000000000001 R14: 00007faa5e717000 R15: 0000000000402e00
> </TASK>
> Modules linked in: rfkill nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib
> nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct
> nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables
> qrtr intel_rapl_msr intel_rapl_common intel_uncore_frequency_common
> intel_pmc_core pmt_telemetry pmt_class intel_pmc_ssram_telemetry
> intel_vsec rapl vmw_balloon pktcdvd i2c_piix4 i2c_smbus joydev loop
> nfnetlink vsock_loopback vmw_vsock_virtio_transport_common
> vmw_vsock_vmci_transport vsock zram vmw_vmci lz4hc_compress lz4_compress
> xfs polyval_clmulni ghash_clmulni_intel sha512_ssse3 sha1_ssse3 vmwgfx
> drm_ttm_helper vmxnet3 nvme nvme_tcp ata_generic ttm nvme_fabrics
> pata_acpi nvme_core nvme_keyring nvme_auth serio_raw sunrpc be2iscsi bnx2i
>  cnic uio cxgb4i cxgb4 tls cxgb3i cxgb3 mdio libcxgbi libcxgb qla4xxx
> iscsi_boot_sysfs iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi
> scsi_dh_rdac scsi_dh_emc scsi_dh_alua fuse i2c_dev dm_multipath
> CR2: 00000000000000b6
> ---[ end trace 0000000000000000 ]---
> RIP: 0010:tcp_ao_finish_connect (net/ipv4/tcp_ao.c:1182)
> Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 0f 1f 00 0f 1f
>  44 00 00 41 54 55 53 48 8b af 00 09 00 00 48 85 ed 74 3e <0f> b7 86 b6 00
>  00 00 48 8b 96 c8 00 00 00 49 89 fc 8b 44 02 04 c7
> All code
> ========
>    0:   90                      nop
>    1:   90                      nop
>    2:   90                      nop
>    3:   90                      nop
>    4:   90                      nop
>    5:   90                      nop
>    6:   90                      nop
>    7:   90                      nop
>    8:   90                      nop
>    9:   90                      nop
>    a:   90                      nop
>    b:   90                      nop
>    c:   90                      nop
>    d:   90                      nop
>    e:   90                      nop
>    f:   90                      nop
>   10:   90                      nop
>   11:   66 0f 1f 00             nopw   (%rax)
>   15:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
>   1a:   41 54                   push   %r12
>   1c:   55                      push   %rbp
>   1d:   53                      push   %rbx
>   1e:   48 8b af 00 09 00 00    mov    0x900(%rdi),%rbp
>   25:   48 85 ed                test   %rbp,%rbp
>   28:   74 3e                   je     0x68
>   2a:*  0f b7 86 b6 00 00 00    movzwl 0xb6(%rsi),%eax
> <-- trapping instruction
>   31:   48 8b 96 c8 00 00 00    mov    0xc8(%rsi),%rdx
>   38:   49 89 fc                mov    %rdi,%r12
>   3b:   8b 44 02 04             mov    0x4(%rdx,%rax,1),%eax
>   3f:   c7                      .byte 0xc7
>
> Code starting with the faulting instruction
> ===========================================
>    0:   0f b7 86 b6 00 00 00    movzwl 0xb6(%rsi),%eax
>    7:   48 8b 96 c8 00 00 00    mov    0xc8(%rsi),%rdx
>    e:   49 89 fc                mov    %rdi,%r12
>   11:   8b 44 02 04             mov    0x4(%rdx,%rax,1),%eax
>   15:   c7                      .byte 0xc7
> RSP: 0018:ffffcf7a858f3a50 EFLAGS: 00010282
> RAX: 0000000000000000 RBX: ffff8e51e8150000 RCX: 0000000000000002
> RDX: ffffcf7a858f3a1f RSI: 0000000000000000 RDI: ffff8e51e8150000
> RBP: ffff8e51c1509e80 R08: ffff8e51e81506bc R09: 0000000000000001
> R10: 0000000000000000 R11: ffff8e51e8150000 R12: 0000000000000000
> R13: ffff8e51c7019680 R14: ffff8e51d20d1cc0 R15: ffff8e51e8150000
> FS:  00007faa5e4dc740(0000) GS:ffff8e533e55f000(0000) knlGS:0000000000000
> 000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000000000b6 CR3: 000000016d3e0003 CR4: 00000000003706f0
> note: tcp-ao-nullptr[41065] exited with irqs disabled
>
> Fixes: 7c2ffaf ("net/tcp: Calculate TCP-AO traffic keys")
> Signed-off-by: Anderson Nascimento <anderson@...elesecurity.com>
> ---
> Changes in v2:
> - Wrap the description at 75 columns
> - Add full decoded stack trace
> - Link to v1: https://lore.kernel.org/all/20250911013052.2233-1-anderson@allelesecurity.com/
>
>  net/ipv4/tcp_ao.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
> index bbb8d5f0eae7..abe913de8652 100644
> --- a/net/ipv4/tcp_ao.c
> +++ b/net/ipv4/tcp_ao.c
> @@ -1178,7 +1178,11 @@ void tcp_ao_finish_connect(struct sock *sk, struct sk_buff *skb)
>         if (!ao)
>                 return;
>
> -       WRITE_ONCE(ao->risn, tcp_hdr(skb)->seq);
> +       /* sk with TCP_REPAIR_ON does not have skb in tcp_finish_connect */
> +       if (skb)
> +               WRITE_ONCE(ao->risn, tcp_hdr(skb)->seq);
> +       else
> +               WRITE_ONCE(ao->risn, 0);
>         ao->rcv_sne = 0;
>
>         hlist_for_each_entry_rcu(key, &ao->head, node, lockdep_sock_is_held(sk))
> --
> 2.51.0
>


-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ