Commit 5f7b51bf authored by Jozsef Kadlecsik's avatar Jozsef Kadlecsik Committed by Pablo Neira Ayuso
Browse files

netfilter: ipset: Limit the maximal range of consecutive elements to add/delete



The range size of consecutive elements were not limited. Thus one could
define a huge range which may result soft lockup errors due to the long
execution time. Now the range size is limited to 2^20 entries.

Reported-by: default avatarBrad Spengler <spender@grsecurity.net>
Signed-off-by: default avatarJozsef Kadlecsik <kadlec@netfilter.org>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent c7d10223
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -196,6 +196,9 @@ struct ip_set_region {
	u32 elements;		/* Number of elements vs timeout */
};

/* Max range where every element is added/deleted in one step */
#define IPSET_MAX_RANGE		(1<<20)

/* The max revision number supported by any set type + 1 */
#define IPSET_REVISION_MAX	9

+8 −1
Original line number Diff line number Diff line
@@ -132,8 +132,11 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
		if (ret)
			return ret;
		if (ip > ip_to)
		if (ip > ip_to) {
			if (ip_to == 0)
				return -IPSET_ERR_HASH_ELEM;
			swap(ip, ip_to);
		}
	} else if (tb[IPSET_ATTR_CIDR]) {
		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);

@@ -144,6 +147,10 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],

	hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);

	/* 64bit division is not allowed on 32bit */
	if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
		return -ERANGE;

	if (retried) {
		ip = ntohl(h->next.ip);
		e.ip = htonl(ip);
+9 −1
Original line number Diff line number Diff line
@@ -121,6 +121,8 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],

	e.mark = ntohl(nla_get_be32(tb[IPSET_ATTR_MARK]));
	e.mark &= h->markmask;
	if (e.mark == 0 && e.ip == 0)
		return -IPSET_ERR_HASH_ELEM;

	if (adt == IPSET_TEST ||
	    !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR])) {
@@ -133,8 +135,11 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
		if (ret)
			return ret;
		if (ip > ip_to)
		if (ip > ip_to) {
			if (e.mark == 0 && ip_to == 0)
				return -IPSET_ERR_HASH_ELEM;
			swap(ip, ip_to);
		}
	} else if (tb[IPSET_ATTR_CIDR]) {
		u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);

@@ -143,6 +148,9 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
		ip_set_mask_from_to(ip, ip_to, cidr);
	}

	if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
		return -ERANGE;

	if (retried)
		ip = ntohl(h->next.ip);
	for (; ip <= ip_to; ip++) {
+3 −0
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
			swap(port, port_to);
	}

	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
		return -ERANGE;

	if (retried)
		ip = ntohl(h->next.ip);
	for (; ip <= ip_to; ip++) {
+3 −0
Original line number Diff line number Diff line
@@ -180,6 +180,9 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
			swap(port, port_to);
	}

	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
		return -ERANGE;

	if (retried)
		ip = ntohl(h->next.ip);
	for (; ip <= ip_to; ip++) {
Loading