From 0eb97928a4e8f86476eb5fcd83c8cf520bfaed98 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 29 Aug 2024 16:14:01 -0400 Subject: [PATCH] protocols/unix: Hold an extra reference during stream endpoint close. See inline comment: otherwise it might be deleted when we release it in Disconnect() but before we unlock it. Also fix _LockConnectedEndpoints() to unset the locker object if returning an error, rather than returning a locked endpoint that we don't hold a reference to. Fixes #18927. (cherry picked from commit 33e9a82042d48c3e18dabc360c3854cf2ebe05dd) Change-Id: Ib349cd312a4f41d3f699f875a98ca89c9540bc5d Reviewed-on: https://review.haiku-os.org/c/haiku/+/8126 Reviewed-by: waddlesplash --- src/add-ons/kernel/network/protocols/unix/UnixStreamEndpoint.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/unix/UnixStreamEndpoint.cpp b/src/add-ons/kernel/network/protocols/unix/UnixStreamEndpoint.cpp index b1688a3..7cae2de 100644 --- a/src/add-ons/kernel/network/protocols/unix/UnixStreamEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/unix/UnixStreamEndpoint.cpp @@ -107,8 +107,13 @@ UnixStreamEndpointLocker locker(this); if (fState == unix_stream_endpoint_state::Connected) { + BReference peerReference; UnixStreamEndpointLocker peerLocker; if (_LockConnectedEndpoints(locker, peerLocker) == B_OK) { + // The peer may be destroyed when we release it, + // so grab a reference for the locker's sake. + peerReference.SetTo(peerLocker.Get(), false); + // We're still connected. Disconnect both endpoints! fPeerEndpoint->_Disconnect(); _Disconnect(); @@ -764,12 +769,13 @@ // We're the child, but locking order is the other way around. locker.Unlock(); peerLocker.SetTo(peerEndpoint, false); - locker.Lock(); // recheck our state, also whether the peer is still the same - if (fState != unix_stream_endpoint_state::Connected || peerEndpoint != fPeerEndpoint) + if (fState != unix_stream_endpoint_state::Connected || peerEndpoint != fPeerEndpoint) { + peerLocker.Unset(); RETURN_ERROR(ENOTCONN); + } } else peerLocker.SetTo(peerEndpoint, false); -- gitore 0.2.3