DragonFlyBSD Kernel Audit
DF-0855 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/dirfs/dirfs_subr.c b/sys/vfs/dirfs/dirfs_subr.c
--- a/sys/vfs/dirfs/dirfs_subr.c
+++ b/sys/vfs/dirfs/dirfs_subr.c
@@ -477,7 +477,8 @@
 		if (count <= MAXPATHLEN)
 			buf[MAXPATHLEN - count] = '/';
 		dnp1 = dnp1->dn_parent;
-		KKASSERT(dnp1 != NULL);
+		if (dnp1 == NULL)
+			break;
 	}
 
 	if (dnp1 && count <= MAXPATHLEN) {
diff --git a/sys/vfs/dirfs/dirfs_vnops.c b/sys/vfs/dirfs/dirfs_vnops.c
--- a/sys/vfs/dirfs/dirfs_vnops.c
+++ b/sys/vfs/dirfs/dirfs_vnops.c
@@ -388,10 +388,15 @@
 	if (!dirfs_node_isroot(dnp)) {
 		pathnp = dirfs_findfd(dmp, dnp, &tmp, &pathfree);
 
-		KKASSERT(pathnp->dn_fd != DIRFS_NOFD);
+		if (pathnp == NULL) {
+			/* Node has been unlinked (dn_parent == NULL). */
+			error = ESTALE;
+		} else {
+			KKASSERT(pathnp->dn_fd != DIRFS_NOFD);
 
-		error = dirfs_node_stat(pathnp->dn_fd, tmp, dnp);
-		dirfs_dropfd(dmp, pathnp, pathfree);
+			error = dirfs_node_stat(pathnp->dn_fd, tmp, dnp);
+			dirfs_dropfd(dmp, pathnp, pathfree);
+		}
 	} else {
 		error = dirfs_node_stat(DIRFS_NOFD, dmp->dm_path, dnp);
 	}