DragonFlyBSD Kernel Audit
DF-0782 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/fuse/fuse_vnops.c b/sys/vfs/fuse/fuse_vnops.c
index 0000000..1111111 100644
--- a/sys/vfs/fuse/fuse_vnops.c
+++ b/sys/vfs/fuse/fuse_vnops.c
@@ -1453,6 +1453,19 @@
 	if (fuse_test_nosys(fmp, FUSE_WRITE))
 		return EOPNOTSUPP;
 
+	/*
+	 * Reject negative offsets (mirror fuse_vop_read) and writes whose
+	 * offset + resid would wrap past OFF_MAX.  Without these the arithmetic
+	 * at `newsize = uio->uio_offset + uio->uio_resid' below wraps to a
+	 * negative off_t which is masked by the subsequent
+	 * `if (newsize < oldsize)' clamp, bypassing the FUSE_MAXFILESIZE check
+	 * and driving fuse_reg_resize() with newsize < 0 (KKASSERT panic).
+	 */
+	if (uio->uio_offset < 0)
+		return (EINVAL);
+	if (uio->uio_offset > FUSE_MAXFILESIZE - uio->uio_resid)
+		return (EFBIG);
+
 	error = 0;
 	if (uio->uio_resid == 0)
 		return error;