⛏️ index : haiku.git

author Augustin Cavalier <waddlesplash@gmail.com> 2024-08-29 16:14:01.0 -04:00:00
committer waddlesplash <waddlesplash@gmail.com> 2024-08-29 20:15:07.0 +00:00:00
commit
0eb97928a4e8f86476eb5fcd83c8cf520bfaed98 [patch]
tree
29f5f83400a99ffd3851a876285f3dd5ed2876ce
parent
57114149c769a670beedbba0ff95000da5046506
download
0eb97928a4e8f86476eb5fcd83c8cf520bfaed98.tar.gz

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 <waddlesplash@gmail.com>

Diff

 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<UnixStreamEndpoint> 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);