Page MenuHomeFreeBSD

socket: Fix a race between kevent(2) and listen(2)
ClosedPublic

Authored by markj on Jun 15 2022, 1:12 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Oct 12, 10:20 PM
Unknown Object (File)
Sun, Oct 12, 10:48 AM
Unknown Object (File)
Sun, Oct 12, 10:48 AM
Unknown Object (File)
Sun, Oct 12, 10:48 AM
Unknown Object (File)
Sun, Oct 12, 10:47 AM
Unknown Object (File)
Sat, Oct 11, 11:54 PM
Unknown Object (File)
Mon, Oct 6, 3:32 AM
Unknown Object (File)
Thu, Sep 25, 7:30 PM
Subscribers

Details

Summary

When locking the knote list for a socket, we check whether the socket is
a listening socket in order to select the appropriate mutex; a listening
socket uses the socket lock, while data sockets use socket buffer
mutexes.

If SOLISTENING(so) is false and the knote lock routine locks a socket
buffer, then it must re-check whether the socket is a listening socket
since solisten_proto() could have changed the socket's identity.

Reported by: syzkaller

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

markj requested review of this revision.Jun 15 2022, 1:12 PM

Thanks, Mark!

If I was writing this I would prefer goto over for(;;) and break as human reading of the code should be that looping here is extremely unprobable:

retry:
if (SOLISTENING(so))
        SOLISTEN_LOCK(so);
else {
        SOCK_RECVBUF_LOCK(so);
        if (__predict_false(SOLISTENING(so))) {
                  SOCK_RECVBUF_UNLOCK(so);
                  goto retry;
        }
}
This revision is now accepted and ready to land.Jun 15 2022, 7:19 PM
This revision now requires review to proceed.Jun 15 2022, 8:08 PM
This revision was not accepted when it landed; it landed in state Needs Review.Jun 16 2022, 2:36 PM
This revision was automatically updated to reflect the committed changes.