DragonFlyBSD Kernel Audit
DF-0915 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/fuse/fuse_device.c b/sys/vfs/fuse/fuse_device.c
--- a/sys/vfs/fuse/fuse_device.c
+++ b/sys/vfs/fuse/fuse_device.c
@@ -187,6 +187,20 @@
 	}
 	ohd = fb.buf;
 
+	/* DF-0915: validate the daemon-claimed length against what it actually
+	 * wrote.  fuse_audit_length() checks ohd->len against the opcode/request,
+	 * but consumers use fb.len (== uio_resid).  Without this, a daemon that
+	 * writes more bytes than ohd->len claims overflows consumer destination
+	 * buffers (e.g. the FUSE_READ memcpy into bp->b_data, fuse_vnops.c:2054). */
+	if (ohd->len < sizeof(*ohd) || ohd->len > fb.len) {
+		fuse_buf_free(&fb);
+		return EINVAL;
+	}
+	/* Clamp the buffer length to the daemon-claimed length so consumers
+	 * (fuse_out_data_size = fb.len - sizeof(*ohd)) never copy past the
+	 * audit-validated reply length. */
+	fb.len = ohd->len;
+
 	mtx_lock(&fmp->ipc_lock);
 	TAILQ_FOREACH(fip, &fmp->reply_head, reply_entry) {
 		if (fip->unique == ohd->unique) {