Skip to content

Commit

Permalink
In sosplice(), temporarily release the socket lock before calling
Browse files Browse the repository at this point in the history
FRELE() as the last reference could be dropped which in turn will cause
soclose() to be called where the socket lock is unconditionally
acquired. Note that this is only a problem for sockets protected by the
non-recursive NET_LOCK() right now.

ok mpi@ visa@

Reported-by: syzbot+7c805a09545d997b924d@syzkaller.appspotmail.com
  • Loading branch information
anton committed Apr 12, 2020
1 parent 911793f commit 27427a7
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
/* $OpenBSD: uipc_socket.c,v 1.243 2020/04/07 13:27:51 visa Exp $ */
/* $OpenBSD: uipc_socket.c,v 1.244 2020/04/12 16:15:18 anton Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */

/*
Expand Down Expand Up @@ -1259,7 +1259,15 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv)
sbunlock(sosp, &sosp->so_snd);
sbunlock(so, &so->so_rcv);
frele:
/*
* FRELE() must not be called with the socket lock held. It is safe to
* release the lock here as long as no other operation happen on the
* socket when sosplice() returns. The dance could be avoided by
* grabbing the socket lock inside this function.
*/
sounlock(so, SL_LOCKED);
FRELE(fp, curproc);
solock(so);
return (error);
}

Expand Down

0 comments on commit 27427a7

Please sign in to comment.