Bug 208035 - IPFW firewall heap overflow
Summary: IPFW firewall heap overflow
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-ipfw (Nobody)
Depends on:
Reported: 2016-03-15 17:50 UTC by CTurt
Modified: 2020-09-19 16:49 UTC (History)
7 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description CTurt 2016-03-15 17:50:01 UTC
There is a heap overflow, triggerable as root only in the IPFW firewall handling code.


static int
ipfw_nat_cfg(struct sockopt *sopt)
	struct cfg_nat_legacy *cfg;
	struct nat44_cfg_nat *ucfg;
	struct cfg_redir_legacy *rdir;
	struct nat44_cfg_redir *urdir;
	char *buf;
	size_t len, len2;
	int error, i;

	len = sopt->sopt_valsize;
	len2 = len + 128;

	 * Allocate 2x buffer to store converted structures.
	 * new redir_cfg has shrinked, so we're sure that
	 * new buffer size is enough.
	buf = malloc(roundup2(len, 8) + len2, M_TEMP, M_WAITOK | M_ZERO);
	error = sooptcopyin(sopt, buf, len, sizeof(struct cfg_nat_legacy));

The size calculation passed to `malloc` can be overflown, resulting in heap overflow on `sooptcopyin`.

This function is called when the `IP_FW_NAT_CFG` command is passed to `ipfw_ctl`:

ipfw_ctl(struct sockopt *sopt)

	/* Save original valsize before it is altered via sooptcopyin() */
	valsize = sopt->sopt_valsize;
	opt = sopt->sopt_name;


	switch (opt) {
			error = ipfw_nat_cfg_ptr(sopt);
		else {
			printf("IP_FW_NAT_CFG: %s\n",
			    "ipfw_nat not present, please load it");
			error = EINVAL;

`ipfw_ctl` is only called by `ipfw_ctl3`, which is available only to root processes (must have `PRIV_NETINET_IPFW` privilege):

ipfw_ctl3(struct sockopt *sopt)

	error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
	if (error != 0)
		return (error);

	if (sopt->sopt_name != IP_FW3)
		return (ipfw_ctl(sopt));
Comment 1 Andrey V. Elsukov freebsd_committer 2016-05-16 14:08:33 UTC
This code looks like left for compatibility with old binaries. Probably it can be completely removed.