Re: [BUG] null-ptr-deref bug in sctp_packet_bundle_auth

Xin Long <[email protected]>
Newsgroups org.kernel.vger.linux-sctp
Message-ID <CADvbK_dvRiP05x-+rfvz0vbRO5a4iVmEFKmSsKiQnLEmKENNxw@mail.gmail.com>
On Thu, Jan 8, 2026 at 3:20 AM Chen Zhen <[email protected]> wrote:
>
> On 25/12/18 10:00, Chen Zhen wrote:
> > ==================
> > Syzkaller reproducer:
> >
> > {Threaded:false Repeat:true RepeatTimes:0 Procs:10 Slowdown:1 Sandbox:none SandboxArg:0 Leak:false NetInjection:true NetDevices:true NetReset:true Cgroups:true BinfmtMisc:true CloseFDs:true KCSAN:false DevlinkPCI:false NicVF:false USB:false VhciInjection:false Wifi:false IEEE802154:false Sysctl:true Swap:true UseTmpDir:true HandleSegv:true Repro:false Trace:false LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
> > perf_event_open(0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > sendmsg$nl_route_sched(0xffffffffffffffff, 0x0, 0x0)
> > r0 = perf_event_open(0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > r1 = socket$key(0xf, 0x3, 0x2)
> > sendmsg$key(r1, 0x0, 0x0)
> > fchown(r0, 0x0, 0xee01)
> > sendmsg$key(r1, 0x0, 0x0)
> > read$FUSE(0xffffffffffffffff, 0x0, 0x0)
> > prlimit64(0x0, 0xe, 0x0, 0x0)
> > sched_setscheduler(0x0, 0x2, 0x0)
> > sched_setscheduler(0x0, 0x2, 0x0)
> > ioctl$FS_IOC_SETFLAGS(0xffffffffffffffff, 0x40086602, 0x0)
> > sendmmsg$unix(0xffffffffffffffff, 0x0, 0x0, 0x0)
> > openat$null(0xffffffffffffff9c, 0x0, 0x600000, 0x0)
> > getpgid(0x0)
> > socket$nl_xfrm(0x10, 0x3, 0x6)
> > perf_event_open(0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > perf_event_open(&(0x7f0000000200)={0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @perf_bp={0x0}}, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > write$eventfd(0xffffffffffffffff, 0x0, 0x0)
> > perf_event_open(0x0, 0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0x3)
> > perf_event_open(0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > socket$vsock_dgram(0x28, 0x2, 0x0)
> > clock_adjtime(0x0, 0x0)
> > perf_event_open(0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > perf_event_open(&(0x7f0000000200)={0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @perf_bp={0x0}}, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0)
> > r2 = socket$inet6_sctp(0xa, 0x1, 0x84)
> > setsockopt(r2, 0x84, 0x81, &(0x7f00000002c0)="1a00000019000000", 0x8)
> > setsockopt$inet_sctp_SCTP_SOCKOPT_BINDX_ADD(r2, 0x84, 0x64, &(0x7f0000000380)=[@in6={0xa, 0x4e23, 0x0, @loopback}], 0x1c)
> > setsockopt$inet_sctp6_SCTP_AUTH_CHUNK(r2, 0x84, 0x15, &(0x7f00000001c0), 0x1)
> > r3 = syz_open_procfs$procfs_self_proc_file(0xffffffffffffffff, &(0x7f0000000180)='fail-nth\x00')
> > write$cgroup_int(r3, &(0x7f0000000200)=0x48, 0x12)
> > perf_event_open(&(0x7f0000000480)={0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, @perf_config_ext}, 0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0x0)
> > r4 = openat$euleros_proc_task_file(0xffffffffffffff9c, &(0x7f0000000440)='/proc/self/patch_state\x00', 0x20000, 0x0)
> > perf_event_open(0x0, 0x0, 0x6, r4, 0x2)
> > setsockopt$inet_sctp6_SCTP_ASSOCINFO(r3, 0x84, 0x1, &(0x7f0000000040)={0x0, 0xd6, 0x2, 0x2d820323, 0x7, 0x1}, 0x14)
> > sendto$inet6(r2, &(0x7f0000000000)=' ', 0x1, 0x0, &(0x7f0000000080)={0xa, 0x4e23, 0x0, @loopback}, 0x1c)
> > sendto$inet6(r2, &(0x7f0000000000)=' ', 0x1, 0x0, &(0x7f0000000080)={0xa, 0x4e23, 0x0, @loopback}, 0x1c)
> > ==================
> >
> > It seems to be rare case because I cannot trigger this bug again with 24h+ of reproducing.
> >
> > Thanks.
> After 10+ days of reproducing the bug finally re-occur...
> I investigated the vmcore dmesg and found this fault-injection backtrace just
> before the bug happened:
> ======================
> FAULT_INJECTION: forcing a failure.
>     name failslab, interval 1, probability 0, space 0, times 0
> CPU: 0 PID: 2898 Comm: syz-executor.8 Kdump: loaded Tainted: G        W          6.6.0 #2
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0xbd/0xe0
>  should_fail_ex+0x4b0/0x5b0
>  should_failslab+0xc3/0x120
>  __kmem_cache_alloc_node+0x67/0x5f0
>  __kmalloc+0x4e/0x150
>  sctp_auth_create_key+0x3d/0xe0
>  sctp_auth_make_key_vector+0x103/0x1e0
>  sctp_auth_asoc_create_secret+0xc6/0x340
>  sctp_auth_asoc_init_active_key.part.0+0x160/0x4b0
>  sctp_auth_asoc_init_active_key+0x67/0x90
>  sctp_cmd_interpreter.isra.0+0x2ccc/0x62c0
>  sctp_do_sm+0x1a3/0x670
>  sctp_assoc_bh_rcv+0x33e/0x640
>  sctp_inq_push+0x1dd/0x280
>  sctp_backlog_rcv+0x19e/0x11c0
>  __release_sock+0x29c/0x310
>  release_sock+0x59/0x1b0
>  sctp_wait_for_connect+0x35f/0x5d0
>  sctp_sendmsg_to_asoc+0x1865/0x1c90
>  sctp_sendmsg+0xc98/0x1e40
>  inet_sendmsg+0x122/0x150
>  __sock_sendmsg+0x1c6/0x2a0
>  __sys_sendto+0x203/0x2e0
>  __x64_sys_sendto+0xe2/0x1c0
>  do_syscall_64+0x6c/0x120
>  entry_SYSCALL_64_after_hwframe+0x78/0xe2
> RIP: 0033:0x7f70f2493bdd
> Code: c3 e8 17 32 00 00 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
> RSP: 002b:00007f70f1ffebf8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
> RAX: ffffffffffffffda RBX: 00007f70f25dbf80 RCX: 00007f70f2493bdd
> RDX: 0000000000000001 RSI: 0000000020000000 RDI: 0000000000000005
> RBP: 00007f70f24f1499 R08: 0000000020000080 R09: 000000000000001c
> R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
> R13: 00007fffe62d14df R14: 00007fffe62d1680 R15: 00007f70f1ffed80
>  </TASK>
> ======================
> And indeed the asoc->shkey、asoc->asoc_shared_key、chunk->auth_chunk、chunk->shkey
> are all NULL in the vmcore memory.
> Is there any possible that the slab force failure caused the asoc->shkey NULL
> then chunk->shkey NULL after sctp_datamsg_from_user() but chunk->auth is true
> so resulted in null-ptr-deref?
>
Hi Chen, Thanks for reproducing it.

Yes, I think I can make sense of this now.

The slab force failure happens while processing INIT_ACK along the
following path:

sctp_do_sm()
 -> sctp_sf_do_5_1C_ack()
   -> sctp_cmd_interpreter(SCTP_CMD_ASSOC_SHKEY)
      -> sctp_auth_asoc_init_active_key()  <-- FAILED

In sctp_sf_do_5_1C_ack(), the SCTP_CMD_ASSOC_SHKEY command (which
calls sctp_auth_asoc_init_active_key) is currently added after:

- SCTP_CMD_TIMER_START (starting the T1_COOKIE timer), and
- SCTP_CMD_NEW_STATE (transition to COOKIE_ECHOED).

If SCTP_CMD_ASSOC_SHKEY fails, asoc->shkey remains NULL. However,
asoc->peer.auth_capable and asoc->peer.peer_chunks have already been
set earlier by SCTP_CMD_PEER_INIT (via sctp_cmd_process_init). As a
result, a DATA chunk with auth = 1 and shkey = NULL can still be
queued for transmission.

At that point, the association has already entered the COOKIE_ECHOED
state, and the T1_COOKIE timer may generate a COOKIE_ECHO chunk. Then,
sctp_outq_flush_data() allows the DATA chunk to send in COOKIE_ECHOED
state when a COOKIE_ECHO chunk exists, which leads to the observed
issue.

My thought is to move the SCTP_CMD_ASSOC_SHKEY command before
SCTP_CMD_TIMER_START (T1_COOKIE), even before SCTP_CMD_TIMER_STOP
(T1_INIT). This way, if shared key generation fails, the DATA chunk
in the outqueue won’t be allowed to send, and the T1_INIT timer can
also retransmit INIT. The client can then receive/process INIT_ACK
again and retry SCTP_CMD_ASSOC_SHKEY in sctp_sf_do_5_1C_ack().

Something like:

diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 3755ba079d07..7b823d759141 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -603,6 +603,11 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
        sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
                        SCTP_PEER_INIT(initchunk));

+       /* SCTP-AUTH: generate the association shared keys so that
+        * we can potentially sign the COOKIE-ECHO.
+        */
+       sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
+
        /* Reset init error count upon receipt of INIT-ACK.  */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());

@@ -617,11 +622,6 @@ enum sctp_disposition sctp_sf_do_5_1C_ack(struct net *net,
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_COOKIE_ECHOED));

-       /* SCTP-AUTH: generate the association shared keys so that
-        * we can potentially sign the COOKIE-ECHO.
-        */
-       sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_SHKEY, SCTP_NULL());
-
        /* 5.1 C) "A" shall then send the State Cookie received in the
         * INIT ACK chunk in a COOKIE ECHO chunk, ...
         */

Could you give this a try?

Thanks.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.