⬢ DragonFlyBSD Kernel Audit
DF-2643 / fix.diff
← back to finding ↓ download raw
--- sys/vfs/hammer2/hammer2_strategy.c
+++ sys/vfs/hammer2/hammer2_strategy.c
@@ -621,13 +621,24 @@
 	 * Actual operation
 	 */
 	parent = hammer2_inode_chain(ip, clindex, HAMMER2_RESOLVE_ALWAYS);
-	hammer2_write_file_core(bio_data, ip, &parent,
-				lbase, IO_ASYNC, pblksize,
-				xop->head.mtid, &error);
 	if (parent) {
-		hammer2_chain_unlock(parent);
-		hammer2_chain_drop(parent);
-		parent = NULL;	/* safety */
+		hammer2_write_file_core(bio_data, ip, &parent,
+					lbase, IO_ASYNC, pblksize,
+					xop->head.mtid, &error);
+		if (parent) {
+			hammer2_chain_unlock(parent);
+			hammer2_chain_drop(parent);
+			parent = NULL;	/* safety */
+		}
+	} else {
+		/*
+		 * DF-2643: the inode chain can be gone (device removal /
+		 * repoint race, see hammer2_admin.c XXX note); fail the
+		 * write with EIO like the read xop does instead of
+		 * dereferencing NULL in hammer2_write_file_core ->
+		 * hammer2_assign_physical -> hammer2_chain_lookup.
+		 */
+		error = HAMMER2_ERROR_EIO;
 	}
 	hammer2_xop_feed(&xop->head, NULL, clindex, error);