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);