Thread (2 messages) flat view 2 messages, 2 authors, 21d ago
COLD21d

[PATCH net] sctp: fix slab OOB read from oversized AUTH parameters in COOKIE-ECHO

From: Henry Martin <hidden>
Date: 2026-08-23 13:04:18
Also in: linux-sctp
Subsystem: networking [general], sctp protocol, the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Marcelo Ricardo Leitner, Xin Long, Linus Torvalds

sctp_unpack_cookie() copies the attacker-supplied sctp_cookie into the
new association without validating the length fields of the three
embedded AUTH parameters (auth_random, auth_hmacs, auth_chunks) against
their fixed in-struct capacities (36/12/20 bytes). When cookie
authentication is disabled (net.sctp.cookie_hmac_alg=none), a remote
peer can forge a COOKIE-ECHO with an inflated param_hdr.length.

The polluted length then drives out-of-bounds reads past the
association: n_elt in sctp_auth_asoc_verify_hmac_id() (up to ~64KB of
16-bit probe reads), the key vector memcpy in
sctp_auth_make_key_vector() (up to ~64KB source read copied into the
HMAC key material), and the chunk-id scan in __sctp_auth_cid().
KASAN reports slab-out-of-bounds reads crossing into unrelated slabs.
[  552.245703] ==================================================================
[  552.245873] BUG: KASAN: slab-out-of-bounds in sctp_auth_asoc_verify_hmac_id+0x105/0x110
[  552.246050] Read of size 2 at addr ffff8881012a90f4 by task poc_guest/333

[  552.246258] CPU: 1 UID: 0 PID: 333 Comm: poc_guest Tainted: G    B               7.2.0-rc6-dirtyfrag-00017-g848acc8ffe1b-dirty #65 PREEMPT(lazy) 
[  552.246283] Tainted: [B]=BAD_PAGE
[  552.246291] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-4.tl4 04/01/2014
[  552.246304] Call Trace:
[  552.246328]  <IRQ>
[  552.246344]  dump_stack_lvl+0x53/0x70
[  552.246374]  print_report+0xce/0x620
[  552.246395]  ? sctp_auth_asoc_verify_hmac_id+0x105/0x110
[  552.246412]  kasan_report+0xce/0x100
[  552.246430]  ? sctp_auth_asoc_verify_hmac_id+0x105/0x110
[  552.246453]  sctp_auth_asoc_verify_hmac_id+0x105/0x110
[  552.246473]  sctp_sf_authenticate+0xd2/0x470
[  552.246491]  ? __pfx__raw_spin_lock+0x10/0x10
[  552.246508]  sctp_auth_chunk_verify+0x25b/0x380
[  552.246526]  ? __pfx_sctp_auth_chunk_verify+0x10/0x10
[  552.246558]  ? sctp_auth_asoc_init_active_key+0x1eb/0x810
[  552.246576]  ? sctp_auth_asoc_init_active_key+0x163/0x810
[  552.246598]  sctp_sf_do_5_1D_ce+0x6cf/0x1b50
[  552.246619]  ? __pfx_sctp_sf_do_5_1D_ce+0x10/0x10
[  552.246637]  ? stack_depot_save_flags+0x485/0x7f0
[  552.246675]  ? __pfx_sctp_sm_lookup_event+0x10/0x10
[  552.246696]  sctp_do_sm+0x111/0x5b90
[  552.246732]  ? ip_local_deliver_finish+0x31c/0x4a0
[  552.246751]  ? ip_rcv+0x2ed/0x360
[  552.246768]  ? process_backlog+0x1ea/0x5f0
[  552.246785]  ? __napi_poll+0xa1/0x530
[  552.246801]  ? net_rx_action+0x944/0xfa0
[  552.246816]  ? handle_softirqs+0x1bd/0x620
[  552.246831]  ? do_softirq+0x43/0x60
[  552.246844]  ? __local_bh_enable_ip+0x6a/0x70
[  552.246858]  ? __dev_queue_xmit+0x9f3/0x3470
[  552.246874]  ? ip_finish_output2+0x724/0x1900
[  552.246889]  ? __pfx_sctp_do_sm+0x10/0x10
[  552.246903]  ? raw_sendmsg+0xe72/0x2710
[  552.246919]  ? __x64_sys_sendto+0xe0/0x1c0
[  552.246938]  ? do_syscall_64+0x102/0x5a0
[  552.246955]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  552.246991]  ? __pfx_sctp_epaddr_lookup_transport+0x10/0x10
[  552.247013]  sctp_endpoint_bh_rcv+0x2c4/0x8e0
[  552.247038]  sctp_rcv+0x1545/0x3980
[  552.247063]  ? sock_queue_rcv_skb_reason+0x39/0x70
[  552.247081]  ? __pfx_sctp_rcv+0x10/0x10
[  552.247105]  ? __pfx_raw_local_deliver+0x10/0x10
[  552.247121]  ? lapic_next_event+0x15/0x20
[  552.247138]  ? clockevents_program_event+0x2bf/0x860
[  552.247159]  ip_protocol_deliver_rcu+0x279/0x2f0
[  552.247176]  ? _raw_spin_lock+0x84/0xe0
[  552.247192]  ip_local_deliver_finish+0x31c/0x4a0
[  552.247211]  ip_local_deliver+0x18b/0x2d0
--
[  552.247752]  ? __pfx___dev_queue_xmit+0x10/0x10
[  552.247769]  ? csum_and_copy_from_iter_full+0x1d9/0x1da0
[  552.247788]  ? kasan_save_track+0x14/0x30
[  552.247803]  ? __kasan_kmalloc+0x8f/0xa0
[  552.247821]  ? __alloc_skb+0x123/0x890
[  552.247843]  ? selinux_ip_postroute+0x3fe/0xb00
[  552.247863]  ip_finish_output2+0x724/0x1900
[  552.247882]  ? __pfx_ip_finish_output2+0x10/0x10
[  552.247899]  ? __ip_append_data+0x16ec/0x4150
[  552.247925]  __ip_finish_output+0x508/0xa30
[  552.247944]  ? __pfx___ip_finish_output+0x10/0x10
[  552.247961]  ? nf_hook_slow+0xaa/0x1c0
[  552.247981]  ip_output+0x17d/0x2f0
[  552.247999]  ? __pfx_ip_output+0x10/0x10
[  552.248015]  ? __ip_make_skb+0xe0f/0x2520
[  552.248031]  ? __pfx_ip_finish_output+0x10/0x10
[  552.248047]  ? ip_append_data+0xcb/0x170
[  552.248066]  ip_push_pending_frames+0x15a/0x1a0
[  552.248084]  raw_sendmsg+0xe72/0x2710
[  552.248107]  ? __pfx_raw_sendmsg+0x10/0x10
[  552.248122]  ? mutex_unlock+0x82/0xd0
[  552.248137]  ? __pfx_mutex_unlock+0x10/0x10
[  552.248157]  ? anon_pipe_write+0xa18/0x1900
[  552.248193]  ? selinux_socket_sendmsg+0x91/0x270
[  552.248215]  __sys_sendto+0x31b/0x390
[  552.248235]  ? __pfx___sys_sendto+0x10/0x10
[  552.248278]  ? ksys_write+0x181/0x1d0
[  552.248295]  ? __pfx_ksys_write+0x10/0x10
[  552.248334]  __x64_sys_sendto+0xe0/0x1c0
[  552.248354]  ? fpregs_assert_state_consistent+0x63/0xf0
[  552.248379]  do_syscall_64+0x102/0x5a0
[  552.248400]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  552.248420] RIP: 0033:0x7facd02ef0a7
[  552.248442] Code: c7 c0 ff ff ff ff eb be 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 80 3d a5 ef 0d 00 00 41 89 ca 74 10 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 69 c3 55 48 89 e5 53 48 83 ec 38 44 89 4d d0
[  552.248461] RSP: 002b:00007ffc9f687208 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
[  552.248489] RAX: ffffffffffffffda RBX: 0000000000000144 RCX: 00007facd02ef0a7
[  552.248501] RDX: 0000000000000150 RSI: 00007ffc9f687234 RDI: 0000000000000003
[  552.248512] RBP: 000000000100007f R08: 00007ffc9f687210 R09: 0000000000000010
[  552.248523] R10: 0000000000000000 R11: 0000000000000202 R12: 000000000000014e
[  552.248534] R13: 00007ffc9f688100 R14: 0000000000000144 R15: 0000000000000100
[  552.248555]  </TASK>

[  552.260224] Allocated by task 1:
[  552.260304]  kasan_save_stack+0x33/0x60
[  552.260410]  kasan_save_track+0x14/0x30
[  552.260501]  __kasan_kmalloc+0x8f/0xa0
[  552.260588]  __kmalloc_cache_noprof+0x1b6/0x420
[  552.260714]  pci_alloc_bus.constprop.0+0x3f/0x300
[  552.260847]  pci_register_host_bridge+0xcf/0x15f0
[  552.260957]  pci_create_root_bus+0x1e5/0x300
[  552.261076]  acpi_pci_root_create+0x42d/0x880
[  552.261193]  pci_acpi_scan_root+0x3df/0x5a0
[  552.261320]  acpi_pci_root_add+0x369/0x8e0
[  552.261453]  acpi_bus_attach+0x4f3/0xa40
[  552.261574]  device_for_each_child+0xf8/0x170
[  552.261732]  acpi_dev_for_each_child+0x7a/0xa0
[  552.261849]  acpi_bus_attach+0x72b/0xa40
[  552.261983]  device_for_each_child+0xf8/0x170
[  552.262087]  acpi_dev_for_each_child+0x7a/0xa0
[  552.262187]  acpi_bus_attach+0x72b/0xa40
[  552.262281]  acpi_bus_scan+0xbd/0x3e0
[  552.262384]  acpi_scan_init+0x1c9/0x580
[  552.262470]  acpi_init+0x2e2/0x6d0
[  552.262540]  do_one_initcall+0xa6/0x370
[  552.262626]  kernel_init_freeable+0x42d/0x760
[  552.262727]  kernel_init+0x1f/0x1e0
[  552.262867]  ret_from_fork+0x3af/0x620
[  552.262974]  ret_from_fork_asm+0x1a/0x30

[  552.263133] The buggy address belongs to the object at ffff8881012a8800
                which belongs to the cache kmalloc-2k of size 2048
[  552.263468] The buggy address is located 1244 bytes to the right of
                allocated 1048-byte region [ffff8881012a8800, ffff8881012a8c18)

[  552.263836] The buggy address belongs to the physical page:
[  552.263955] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1012a8
[  552.264112] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[  552.264255] flags: 0x200000000000040(head|node=0|zone=2)
[  552.264383] page_type: f5(slab)
[  552.264460] raw: 0200000000000040 ffff888100043240 ffffea0004044410 ffffea0004057c10
[  552.264616] raw: 0000000000000000 0000000800050005 00000000f5000000 0000000000000000
[  552.264850] head: 0200000000000040 ffff888100043240 ffffea0004044410 ffffea0004057c10
[  552.264998] head: 0000000000000000 0000000800050005 00000000f5000000 0000000000000000
[  552.265145] head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[  552.265288] head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000008
[  552.265437] page dumped because: kasan: bad access detected

[  552.265575] Memory state around the buggy address:
[  552.265660]  ffff8881012a8f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  552.265881]  ffff8881012a9000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  552.266013] >ffff8881012a9080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  552.266143]                                                              ^
[  552.266272]  ffff8881012a9100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  552.266412]  ffff8881012a9180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  552.266544] ==================================================================
[  553.517512] systemd[1]: e2scrub_all.service: Deactivated successfully.
[  553.545039] systemd[1]: Finished e2scrub_all.service - Online ext4 Metadata Check for All Filesystems.
[  553.682216] systemd[1]: systemd-journald.service: Main process exited, code=killed, status=6/ABRT
[  553.688936] systemd[1]: systemd-journald.service: Failed with result 'watchdog'.
[  553.698303] systemd[1]: systemd-journald.service: Consumed 7min 31.125s CPU time.
[  553.716114] systemd[1]: systemd-journald.service: Scheduled restart job, restart counter is at 1.
[  553.849464] systemd[1]: Starting systemd-journald.service - Journal Service...
[  554.149027] systemd[1]: systemd-update-utmp-runlevel.service: Deactivated successfully.
[  554.176031] systemd[1]: Finished systemd-update-utmp-runlevel.service - Record Runlevel Change in UTMP.
[  554.675881] systemd-journald[352]: Collecting audit messages is disabled.
[  554.722954] systemd-journald[352]: File /var/log/journal/650a0aae2d504220b5076f94e1b000de/system.journal corrupted or uncleanly shut down, renaming and replacing.
[  555.046104] systemd[1]: fstrim.service: Deactivated successfully.
[  555.053901] systemd[1]: Finished fstrim.service - Discard unused blocks on filesystems from /etc/fstab.
[  555.063225] systemd[1]: fstrim.service: Consumed 1.297s CPU time.
[  555.079769] systemd-journald[352]: /dev/kmsg buffer overrun, some messages lost.
[  556.021993] systemd[1]: Started systemd-journald.service - Journal Service.

Reject cookies whose embedded AUTH parameter lengths exceed the
struct capacities, the same "malformed" path used for other corrupt
cookie fields.

The issue was found by ZeroHive, a vulnerability hunting agent at
Tencent Yunding Lab.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Henry Martin <redacted>
---
 net/sctp/sm_make_chunk.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 5a335c980a7a4..0634241fd6649 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1855,6 +1855,16 @@ struct sctp_association *sctp_unpack_cookie(
 	/* Populate the association from the cookie.  */
 	memcpy(&retval->c, bear_cookie, sizeof(*bear_cookie));
 
+	if (ntohs(((__be16 *)retval->c.auth_random)[1]) >
+	    sizeof(retval->c.auth_random) ||
+	    ntohs(((__be16 *)retval->c.auth_hmacs)[1]) >
+	    sizeof(retval->c.auth_hmacs) ||
+	    ntohs(((__be16 *)retval->c.auth_chunks)[1]) >
+	    sizeof(retval->c.auth_chunks)) {
+		*error = -SCTP_IERROR_MALFORMED;
+		goto fail;
+	}
+
 	if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie,
 						 GFP_ATOMIC) < 0) {
 		*error = -SCTP_IERROR_NOMEM;
--
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help