DragonFlyBSD Kernel Audit
DF-2714 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1562,6 +1562,15 @@
 }
 
 /*
+ * Upper bound on the total number of header/trailer bytes sendfile(2)
+ * will marshal into mbufs (sys_sendfile()).  The marshalling happens
+ * before any socket-buffer accounting, so without this cap an
+ * unprivileged user can force the kernel to allocate an attacker-chosen
+ * amount of mbuf memory (up to SSIZE_MAX worth of header bytes).
+ */
+#define	SF_HDTR_MAXBYTES	(1024 * 1024)
+
+/*
  * sendfile(2).
  * int sendfile(int fd, int s, off_t offset, size_t nbytes,
  *	 struct sf_hdtr *hdtr, off_t *sbytes, int flags)
@@ -1626,6 +1635,10 @@
 					     hdtr.hdr_cnt, &hbytes);
 			if (error)
 				goto done;
+			if (hbytes > SF_HDTR_MAXBYTES) {
+				error = EINVAL;
+				goto done;
+			}
 			auio.uio_iov = iov;
 			auio.uio_iovcnt = hdtr.hdr_cnt;
 			auio.uio_offset = 0;
@@ -1655,6 +1668,10 @@
 				     hdtr.trl_cnt, &auio.uio_resid);
 		if (error)
 			goto done;
+		if (auio.uio_resid > SF_HDTR_MAXBYTES) {
+			error = EINVAL;
+			goto done;
+		}
 		auio.uio_iov = iov;
 		auio.uio_iovcnt = hdtr.trl_cnt;
 		auio.uio_offset = 0;