⬢ DragonFlyBSD Kernel Audit
DF-3071 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/tmpfs/tmpfs_subr.c
+++ b/sys/vfs/tmpfs/tmpfs_subr.c
@@ -104,6 +104,10 @@
 	KKASSERT(IFF(type == VLNK, target != NULL));
 	KKASSERT(IFF(type == VBLK || type == VCHR, rmajor != VNOVAL));
 
+	/*
+	 * DF-3071: close the check-then-act race; re-check under TMPFS_LOCK
+	 * after the (sleeping) allocation.
+	 */
 	if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max)
 		return (ENOSPC);
 
@@ -111,6 +115,13 @@
 			    M_WAITOK | M_ZERO | M_NULLOK);
 	if (nnode == NULL)
 		return (ENOSPC);
+	TMPFS_LOCK(tmp);
+	if (tmp->tm_nodes_inuse >= tmp->tm_nodes_max) {
+		TMPFS_UNLOCK(tmp);
+		kfree_obj(nnode, tmp->tm_node_zone);
+		return (ENOSPC);
+	}
+	TMPFS_UNLOCK(tmp);
 	tmpfs_node_init(nnode);
 
 	/* Generic initialization. */