From 15e40a45a990d2a6d786ef2282b9eb56b20a9231 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on macOS)" <rob@synchro.net>
Date: Sat, 23 Nov 2024 16:02:54 -0800
Subject: [PATCH] Fix potential deadlock in getnodedat(), observed on macOS

Upon any node.dab lock or read failure, this code would cause errormsg() which
would often/usually end up claling getnodedat() which would block forever trying
to acquire the ndoefile_mutex (introduced in commit b9633069, I'm not clear why).

Unlock/release the mutex *before* calling errormsg().
---
 src/sbbs3/getnode.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/sbbs3/getnode.cpp b/src/sbbs3/getnode.cpp
index 0864752568..cb789b8101 100644
--- a/src/sbbs3/getnode.cpp
+++ b/src/sbbs3/getnode.cpp
@@ -47,8 +47,8 @@ int sbbs_t::getnodedat(uint number, node_t *node, bool lockit)
 	pthread_mutex_lock(&nodefile_mutex);
 	if(nodefile==-1) {
 		if((nodefile=nopen(str,O_RDWR|O_DENYNONE))==-1) {
-			errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE);
 			pthread_mutex_unlock(&nodefile_mutex);
+			errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE);
 			return(errno); 
 		}
 	}
@@ -77,11 +77,11 @@ int sbbs_t::getnodedat(uint number, node_t *node, bool lockit)
 	}
 
 	if(count==LOOP_NODEDAB) {
-		errormsg(WHERE,rd==sizeof(node_t) ? ERR_LOCK : ERR_READ,"node.dab",number+1);
 		if(nodefile!=-1)
 			close(nodefile);
 		nodefile=-1;
 		pthread_mutex_unlock(&nodefile_mutex);
+		errormsg(WHERE,rd==sizeof(node_t) ? ERR_LOCK : ERR_READ,"node.dab",number+1);
 		return(-2);
 	}
 	pthread_mutex_unlock(&nodefile_mutex);
-- 
GitLab