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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250911034337.43331-2-anderson@allelesecurity.com>
Date: Thu, 11 Sep 2025 00:43:38 -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
Cc: Anderson Nascimento <anderson@...elesecurity.com>
Subject: [PATCH v2] net/tcp: Fix a NULL pointer dereference when using TCP-AO with TCP_REPAIR.

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().

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


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ