Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Browse files Browse the repository at this point in the history
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for net:

1) Restrict range element expansion in ipset to avoid soft lockup,
   from Jozsef Kadlecsik.

2) Memleak in error path for nf_conntrack_bridge for IPv4 packets,
   from Yajun Deng.

3) Simplify conntrack garbage collection strategy to avoid frequent
   wake-ups, from Florian Westphal.

4) Fix NFNLA_HOOK_FUNCTION_NAME string, do not include module name.

5) Missing chain family netlink attribute in chain description
   in nfnetlink_hook.

6) Incorrect sequence number on nfnetlink_hook dumps.

7) Use netlink request family in reply message for consistency.

8) Remove offload_pickup sysctl, use conntrack for established state
   instead, from Florian Westphal.

9) Translate NFPROTO_INET/ingress to NFPROTO_NETDEV/ingress, since
   NFPROTO_INET is not exposed through nfnetlink_hook.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf:
  netfilter: nfnetlink_hook: translate inet ingress to netdev
  netfilter: conntrack: remove offload_pickup sysctl again
  netfilter: nfnetlink_hook: Use same family as request message
  netfilter: nfnetlink_hook: use the sequence number of the request message
  netfilter: nfnetlink_hook: missing chain family
  netfilter: nfnetlink_hook: strip off module name from hookfn
  netfilter: conntrack: collect all entries in one cycle
  netfilter: nf_conntrack_bridge: Fix memory leak when error
  netfilter: ipset: Limit the maximal range of consecutive elements to add/delete
====================

Link: https://lore.kernel.org/r/20210806151149.6356-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
kuba-moo committed Aug 6, 2021
2 parents 704e624 + 269fc69 commit cc4e5ee
Show file tree
Hide file tree
Showing 21 changed files with 151 additions and 95 deletions.
10 changes: 0 additions & 10 deletions Documentation/networking/nf_conntrack-sysctl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,9 @@ nf_flowtable_tcp_timeout - INTEGER (seconds)
TCP connections may be offloaded from nf conntrack to nf flow table.
Once aged, the connection is returned to nf conntrack with tcp pickup timeout.

nf_flowtable_tcp_pickup - INTEGER (seconds)
default 120

TCP connection timeout after being aged from nf flow table offload.

nf_flowtable_udp_timeout - INTEGER (seconds)
default 30

Control offload timeout for udp connections.
UDP connections may be offloaded from nf conntrack to nf flow table.
Once aged, the connection is returned to nf conntrack with udp pickup timeout.

nf_flowtable_udp_pickup - INTEGER (seconds)
default 30

UDP connection timeout after being aged from nf flow table offload.
3 changes: 3 additions & 0 deletions include/linux/netfilter/ipset/ip_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 0 additions & 2 deletions include/net/netns/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ struct nf_tcp_net {
u8 tcp_ignore_invalid_rst;
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
unsigned int offload_timeout;
unsigned int offload_pickup;
#endif
};

Expand All @@ -44,7 +43,6 @@ struct nf_udp_net {
unsigned int timeouts[UDP_CT_MAX];
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
unsigned int offload_timeout;
unsigned int offload_pickup;
#endif
};

Expand Down
9 changes: 9 additions & 0 deletions include/uapi/linux/netfilter/nfnetlink_hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ enum nfnl_hook_chain_info_attributes {
};
#define NFNLA_HOOK_INFO_MAX (__NFNLA_HOOK_INFO_MAX - 1)

enum nfnl_hook_chain_desc_attributes {
NFNLA_CHAIN_UNSPEC,
NFNLA_CHAIN_TABLE,
NFNLA_CHAIN_FAMILY,
NFNLA_CHAIN_NAME,
__NFNLA_CHAIN_MAX,
};
#define NFNLA_CHAIN_MAX (__NFNLA_CHAIN_MAX - 1)

/**
* enum nfnl_hook_chaintype - chain type
*
Expand Down
6 changes: 6 additions & 0 deletions net/bridge/netfilter/nf_conntrack_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,

skb = ip_fraglist_next(&iter);
}

if (!err)
return 0;

kfree_skb_list(iter.frag);

return err;
}
slow_path:
Expand Down
9 changes: 8 additions & 1 deletion net/netfilter/ipset/ip_set_hash_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);

Expand All @@ -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);
Expand Down
10 changes: 9 additions & 1 deletion net/netfilter/ipset/ip_set_hash_ipmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -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])) {
Expand All @@ -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]);

Expand All @@ -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++) {
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/ipset/ip_set_hash_ipport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/ipset/ip_set_hash_ipportip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/ipset/ip_set_hash_ipportnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ hash_ipportnet4_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;

ip2_to = ip2_from;
if (tb[IPSET_ATTR_IP2_TO]) {
ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
Expand Down
11 changes: 10 additions & 1 deletion net/netfilter/ipset/ip_set_hash_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net4_elem e = { .cidr = HOST_MASK };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to = 0;
u32 ip = 0, ip_to = 0, ipn, n = 0;
int ret;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -188,6 +188,15 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
if (ip + UINT_MAX == ip_to)
return -IPSET_ERR_HASH_RANGE;
}
ipn = ip;
do {
ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
n++;
} while (ipn++ < ip_to);

if (n > IPSET_MAX_RANGE)
return -ERANGE;

if (retried)
ip = ntohl(h->next.ip);
do {
Expand Down
10 changes: 9 additions & 1 deletion net/netfilter/ipset/ip_set_hash_netiface.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to = 0;
u32 ip = 0, ip_to = 0, ipn, n = 0;
int ret;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -256,6 +256,14 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
} else {
ip_set_mask_from_to(ip, ip_to, e.cidr);
}
ipn = ip;
do {
ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
n++;
} while (ipn++ < ip_to);

if (n > IPSET_MAX_RANGE)
return -ERANGE;

if (retried)
ip = ntohl(h->next.ip);
Expand Down
16 changes: 15 additions & 1 deletion net/netfilter/ipset/ip_set_hash_netnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netnet4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to = 0;
u32 ip2 = 0, ip2_from = 0, ip2_to = 0;
u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
u64 n = 0, m = 0;
int ret;

if (tb[IPSET_ATTR_LINENO])
Expand Down Expand Up @@ -244,6 +245,19 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
} else {
ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
}
ipn = ip;
do {
ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
n++;
} while (ipn++ < ip_to);
ipn = ip2_from;
do {
ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
m++;
} while (ipn++ < ip2_to);

if (n*m > IPSET_MAX_RANGE)
return -ERANGE;

if (retried) {
ip = ntohl(h->next.ip[0]);
Expand Down
11 changes: 10 additions & 1 deletion net/netfilter/ipset/ip_set_hash_netport.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to, p = 0, ip = 0, ip_to = 0;
u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
u64 n = 0;
bool with_ports = false;
u8 cidr;
int ret;
Expand Down Expand Up @@ -235,6 +236,14 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
} else {
ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
}
ipn = ip;
do {
ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
n++;
} while (ipn++ < ip_to);

if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
return -ERANGE;

if (retried) {
ip = ntohl(h->next.ip);
Expand Down
16 changes: 15 additions & 1 deletion net/netfilter/ipset/ip_set_hash_netportnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netportnet4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to = 0, p = 0, port, port_to;
u32 ip2_from = 0, ip2_to = 0, ip2;
u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
u64 n = 0, m = 0;
bool with_ports = false;
int ret;

Expand Down Expand Up @@ -284,6 +285,19 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
} else {
ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
}
ipn = ip;
do {
ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
n++;
} while (ipn++ < ip_to);
ipn = ip2_from;
do {
ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
m++;
} while (ipn++ < ip2_to);

if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
return -ERANGE;

if (retried) {
ip = ntohl(h->next.ip[0]);
Expand Down
Loading

0 comments on commit cc4e5ee

Please sign in to comment.