DragonFlyBSD Kernel Audit
DF-2580 / 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
--- 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;
+	/*
+	 * DF-2580: bound-check the table id once, before any dispatch.
+	 * Every table_*_dispatch() does `table_ctx += id' against the
+	 * ctx->table_ctx[IPFW_TABLES_MAX] array with no other check; an
+	 * out-of-range signed id gives a controlled kernel heap OOB
+	 * read/write.  LIST iterates all slots and never indexes by id,
+	 * so it is exempt.
+	 */
+	if (sopt->sopt_name != IP_FW_TABLE_LIST &&
+	    sopt->sopt_valsize >= sizeof(int)) {
+		struct ipfw_ioc_table *ioc =
+		    (struct ipfw_ioc_table *)sopt->sopt_val;
+		if (ioc->id < 0 || ioc->id >= IPFW_TABLES_MAX)
+			return (EINVAL);
+	}
 	switch (sopt->sopt_name) {
 		case IP_FW_TABLE_CREATE:
 			error = ip_fw3_ctl_table_create(sopt);