Index | Thread | Search

From:
Vitaliy Makkoveev <mvs@openbsd.org>
Subject:
Re: inpcb use after free
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org
Date:
Thu, 12 Jun 2025 22:51:50 +0300

Download raw body.

Thread
On Thu, Jun 12, 2025 at 08:34:20PM +0200, Alexander Bluhm wrote:
> Hi,
> 
> syzkaller found a use-after-free in my fix for the socket leak
> yesterday.
> 
> Reported-by: syzbot+05b4b109c890334897af@syzkaller.appspotmail.com
> 
> panic: kernel diagnostic assertion "(TAILQ_NEXT(inp, inp_queue) == NULL) ||
> +(TAILQ_NEXT(inp, inp_queue) == _Q_INVALID)" failed: file
> +"/syzkaller/managers/main/kernel/sys/netinet/in_pcb.c", line 673
> Starting stack trace...
> panic(ffffffff8342cfde) at panic+0x1ba sys/kern/subr_prf.c:229
> __assert(ffffffff833df4e4,ffffffff833caf1a,2a1,ffffffff833a396f) at
> +__assert+0x29 sys/kern/subr_prf.c:-1
> in_pcbunref(fffffd80715647b0) at in_pcbunref+0x206 sys/netinet/in_pcb.c:672
> tcp_input_solocked(ffff80002a74b640,ffff80002a74b64c,0,2,ffff80002a74b638) at
> +tcp_input_solocked+0xfd sys/netinet/tcp_input.c:2229
> tcp_input_mlist(ffffffff838ebd20,2) at tcp_input_mlist+0x93
> +sys/netinet/tcp_input.c:-1
> if_input_process(ffff800000b11800,ffff80002a74b718,0) at if_input_process+0x229
> +sys/net/if.c:1015
> ifiq_process(ffff800000b11c18) at ifiq_process+0xcd sys/net/ifq.c:874
> taskq_thread(ffff80000002c000) at taskq_thread+0xd4 sys/kern/kern_task.c:446
> end trace frame: 0x0, count: 249
> End of stack trace.
> 
> If syn_cache_get() goes to the resetandabort case, the listen inpcb
> is stored in listeninp and inp.  There we call in_pcbunref(inp),
> so the listen socket is accidently freed.
> 
> ok?
> 

ok mvs

> bluhm
> 
> Index: netinet/tcp_input.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
> diff -u -p -r1.451 tcp_input.c
> --- netinet/tcp_input.c	11 Jun 2025 14:30:07 -0000	1.451
> +++ netinet/tcp_input.c	12 Jun 2025 18:12:05 -0000
> @@ -3654,6 +3654,7 @@ syn_cache_get(struct sockaddr *src, stru
>  	 */
>  	listenso = so;
>  	listeninp = inp;
> +	inp = NULL;
>  	so = sonewconn(listenso, SS_ISCONNECTED, M_DONTWAIT);
>  	if (so == NULL)
>  		goto resetandabort;
>