DragonFlyBSD Kernel Audit
DF-0471 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/net/ipfw3/ip_fw3.c b/sys/net/ipfw3/ip_fw3.c
--- a/sys/net/ipfw3/ip_fw3.c
+++ b/sys/net/ipfw3/ip_fw3.c
@@ -1039,6 +1039,16 @@
 ip_fw3_ctl_x(struct sockopt *sopt)
 {
 	ip_fw_x_header *x_header;
+
+	/*
+	 * DF-0471: sopt_valsize is size_t (unsigned).  If it is smaller than
+	 * the 4-byte ip_fw_x_header, the subtraction below wraps to ~SIZE_MAX
+	 * and the following bcopy walks off the end of the option buffer,
+	 * corrupting kernel memory.  Reject short payloads up front.
+	 */
+	if (sopt->sopt_valsize < sizeof(ip_fw_x_header))
+		return EINVAL;
+
 	x_header = (ip_fw_x_header *)(sopt->sopt_val);
 	sopt->sopt_name = x_header->opcode;
 	sopt->sopt_valsize -= sizeof(ip_fw_x_header);