svn commit: r292592 - head/sys/fs/cuse

Hans Petter Selasky hselasky at FreeBSD.org
Tue Dec 22 09:26:26 UTC 2015


Author: hselasky
Date: Tue Dec 22 09:26:24 2015
New Revision: 292592
URL: https://svnweb.freebsd.org/changeset/base/292592

Log:
  Guard against the same process being both CUSE server and client at
  the same time. This can easily lead to a deadlock when destroying the
  character devices nodes.

Modified:
  head/sys/fs/cuse/cuse.c

Modified: head/sys/fs/cuse/cuse.c
==============================================================================
--- head/sys/fs/cuse/cuse.c	Tue Dec 22 09:08:21 2015	(r292591)
+++ head/sys/fs/cuse/cuse.c	Tue Dec 22 09:26:24 2015	(r292592)
@@ -108,6 +108,7 @@ struct cuse_server {
 	TAILQ_HEAD(, cuse_client) hcli;
 	struct cv cv;
 	struct selinfo selinfo;
+	pid_t	pid;
 	int	is_closing;
 	int	refs;
 };
@@ -691,6 +692,10 @@ cuse_server_open(struct cdev *dev, int f
 		free(pcs, M_CUSE);
 		return (ENOMEM);
 	}
+
+	/* store current process ID */
+	pcs->pid = curproc->p_pid;
+
 	TAILQ_INIT(&pcs->head);
 	TAILQ_INIT(&pcs->hdev);
 	TAILQ_INIT(&pcs->hcli);
@@ -1357,9 +1362,15 @@ cuse_client_open(struct cdev *dev, int f
 	if (pcsd != NULL) {
 		pcs = pcsd->server;
 		pcd = pcsd->user_dev;
+		/*
+		 * Check that the refcount didn't wrap and that the
+		 * same process is not both client and server. This
+		 * can easily lead to deadlocks when destroying the
+		 * CUSE character device nodes:
+		 */
 		pcs->refs++;
-		if (pcs->refs < 0) {
-			/* overflow */
+		if (pcs->refs < 0 || pcs->pid == curproc->p_pid) {
+			/* overflow or wrong PID */
 			pcs->refs--;
 			pcsd = NULL;
 		}


More information about the svn-src-head mailing list