Failure to check array bounds in nethash

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I think I've found a bug in ip_set_nethash.c.  Within nethash_add(), we have:

	if (map->elements >= limit || map->nets[cidr-1] == UINT16_MAX)
		return -ERANGE;	
	if (cidr <= 0 || cidr >= 32)
		return -EINVAL;

First, this does bounds checking on "cidr" only after we have already
used "cidr" to do a lookup in "nets".

Second, the bounds check itself is insufficient, because "nets" has length 30:

struct ip_set_nethash {
        ...
	uint16_t nets[30];		/* nr of nets by CIDR sizes */
        ...
}

Therefore, any block of size /31 causes us to read off the end of the
array.  Later in the function, we write to this location too, causing
undefined behavior.  I went looking for bugs here because I was seeing
inconsistent behavior when adding /31 blocks to a nethash.  Sometimes
I can add them, and sometimes they fail with ERANGE.

-Ed
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux