DragonFlyBSD Kernel Audit
DF-0670 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/net/ipfw3_basic/ip_fw3_table.c b/sys/net/ipfw3_basic/ip_fw3_table.c
index 395ba09..84a2eae 100644
--- a/sys/net/ipfw3_basic/ip_fw3_table.c
+++ b/sys/net/ipfw3_basic/ip_fw3_table.c
@@ -524,6 +524,21 @@
 ip_fw3_ctl_table_sockopt(struct sockopt *sopt)
 {
 	int error = 0;
+
+	/*
+	 * Reject any set request whose value buffer is too small for the
+	 * expected ipfw_ioc_table header.  ip_fw3_ctl_x strips the 4-byte
+	 * x_header from sopt_val but does not re-validate sopt_valsize, so
+	 * without this guard the dispatch handlers below read ioc_table->type
+	 * (off 4) and ioc_table->name (off 12..43) past the end of a short
+	 * kernel buffer -> heap OOB read.  (DF-0670)
+	 */
+	if (sopt->sopt_dir == SOPT_SET &&
+	    sopt->sopt_name != IP_FW_TABLE_LIST &&
+	    sopt->sopt_name != IP_FW_TABLE_SHOW &&
+	    sopt->sopt_valsize < sizeof(struct ipfw_ioc_table))
+		return EINVAL;
+
 	switch (sopt->sopt_name) {
 		case IP_FW_TABLE_CREATE:
 			error = ip_fw3_ctl_table_create(sopt);