DragonFlyBSD Kernel Audit
DF-3055 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/dirfs/dirfs_vnops.c b/sys/vfs/dirfs/dirfs_vnops.c
index a9acfbb5..c0d6ad28 100644
--- a/sys/vfs/dirfs/dirfs_vnops.c
+++ b/sys/vfs/dirfs/dirfs_vnops.c
@@ -1066,12 +1066,13 @@ dirfs_nmkdir(struct vop_nmkdir_args *ap)
 	} else { /* Directory has been made */
 		error = dirfs_alloc_file(dmp, &dnp, pdnp, ncp, vpp,
 		    vap, O_DIRECTORY);
-		if (error)
-			error = errno;
-		cache_setunresolved(ap->a_nch);
-		cache_setvp(ap->a_nch, *vpp);
-		dirfs_knote(dvp, NOTE_WRITE | NOTE_LINK);
-	}
+		if (error == 0) {
+			cache_setunresolved(ap->a_nch);
+			cache_setvp(ap->a_nch, *vpp);
+			dirfs_knote(dvp, NOTE_WRITE | NOTE_LINK);
+		}
+		/* else: propagate error, do NOT cache_setvp(NULL) and do
+		 * not clobber it with a stale errno */
 	dirfs_node_unlock(pdnp);
 
 	if (extrapath)
@@ -1193,12 +1194,13 @@ dirfs_nsymlink(struct vop_nsymlink_args *ap)
 	} else { /* Symlink has been made */
 		error = dirfs_alloc_file(dmp, &dnp, pdnp, ncp, vpp,
 		    NULL, 0);
-		if (error)
-			error = errno;
-		cache_setunresolved(ap->a_nch);
-		cache_setvp(ap->a_nch, *vpp);
-		dirfs_knote(*vpp, NOTE_WRITE);
-	}
+		if (error == 0) {
+			cache_setunresolved(ap->a_nch);
+			cache_setvp(ap->a_nch, *vpp);
+			dirfs_knote(*vpp, NOTE_WRITE);
+		}
+		/* else: *vpp was never set by dirfs_alloc_file() -- using
+		 * it here dereferences NULL */
 	dbg(5, "path=%s a_target=%s\n", path, ap->a_target);
 
 	KTR_LOG(dirfs_nsymlink, dnp, ap->a_target, path, error);