DragonFlyBSD Kernel Audit
DF-0924 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/procfs/procfs_map.c b/sys/vfs/procfs/procfs_map.c
--- a/sys/vfs/procfs/procfs_map.c
+++ b/sys/vfs/procfs/procfs_map.c
@@ -58,6 +58,7 @@
 	     struct uio *uio)
 {
 	struct proc *p = lp->lwp_proc;
+#define PROCFS_MAP_MAXBUF	(1U << 20)	/* 1 MiB, ample for one read */
 	ssize_t buflen = uio->uio_offset + uio->uio_resid;
 	struct vnode *vp;
 	char *fullpath, *freepath;
@@ -74,6 +75,14 @@
 
 	if (uio->uio_offset < 0 || uio->uio_resid < 0 || buflen >= INT_MAX)
 		return EINVAL;
+	/*
+	 * The output is positionally truncated by uiomove_frombuf below, so
+	 * the buffer only needs to hold one read's worth of formatted output.
+	 * Cap it so a hostile read() length cannot force a multi-GiB up-front
+	 * kmalloc in sbuf_new (DF-0924).  1 MiB is ample for any single read.
+	 */
+	if (buflen > PROCFS_MAP_MAXBUF)
+		buflen = PROCFS_MAP_MAXBUF;
 	sb = sbuf_new (sb, NULL, buflen+1, 0);
 	if (sb == NULL)
 		return EIO;