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)
Jan 28 2024, 1:45 PM
Unknown Object (File)
Dec 20 2023, 4:14 AM
Unknown Object (File)
Dec 18 2023, 12:04 PM
Unknown Object (File)
Dec 8 2023, 8:25 PM
Unknown Object (File)
Nov 10 2023, 12:51 AM
Unknown Object (File)
Oct 8 2023, 11:43 PM
Unknown Object (File)
Sep 30 2023, 10:50 AM
Unknown Object (File)
Aug 29 2023, 10:23 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.