DragonFlyBSD Kernel Audit
DF-2663 / inject2663.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_ondisk.c
+++ b/sys/vfs/hammer2/hammer2_ondisk.c
@@ -46,6 +46,22 @@
 #include <sys/lock.h>
 
 #include "hammer2.h"
+#include <sys/sysctl.h>
+
+SYSCTL_DECL(_vfs_hammer2);
+
+/*
+ * DF-2663 fault injection: make the mount-time DIOCGPART appear to fail
+ * (simulates real failure modes: async slice-probe race after
+ * disk_setdiskinfo(), d_slice == NULL, raw-device fallback ENOTTY), so the
+ * volu_size containment check below is skipped.
+ *
+ * ENVIRONMENT SIMULATION ONLY -- never part of a fix.
+ */
+int hammer2_df2663_fail_diocgpart = 0;
+SYSCTL_INT(_vfs_hammer2, OID_AUTO, df2663_fail_diocgpart, CTLFLAG_RW,
+	   &hammer2_df2663_fail_diocgpart, 0,
+	   "FAULT-INJECT fail DIOCGPART for the 320MB test volume");
 
 #define hprintf(X, ...)	kprintf("hammer2_ondisk: " X, ## __VA_ARGS__)
 
@@ -280,14 +296,24 @@
 			return EINVAL;
 		}
 		/* check volume size vs block device size */
-		if (VOP_IOCTL(vol->dev->devvp, DIOCGPART, (void*)&part, 0,
-			      curthread->td_ucred , NULL) == 0) {
+		{
+			int dioerr = VOP_IOCTL(vol->dev->devvp, DIOCGPART,
+						(void*)&part, 0,
+						curthread->td_ucred, NULL);
+			if (hammer2_df2663_fail_diocgpart &&
+			    vol->size == 0x14000000ULL) {
+				/* DF-2663: only the 320MB forged test
+				 * volume, never the guest root fs */
+				dioerr = ENXIO;
+			}
+			if (dioerr == 0) {
 			if (vol->size > part.media_size) {
 				hprintf("%s's size 0x%016jx exceeds device size "
 					"0x%016jx\n", path, (intmax_t)vol->size,
 					part.media_size);
 				return EINVAL;
 			}
+			}
 		}
 		if (vol->size == 0) {
 			hprintf("%s has size of 0\n", path);