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 your net tree:

1) Missing module autoloadfor icmp and icmpv6 x_tables matches,
   from Florian Westphal.

2) Possible non-linear access to TCP header from tproxy, from
   Mate Eckl.

3) Do not allow rbtree to be used for single elements, this patch
   moves all set backend into one single module since such thing
   can only happen if hashtable module is explicitly blacklisted,
   which should not ever be done.

4) Reject error and standard targets from nft_compat for sanity
   reasons, they are never used from there.

5) Don't crash on double hashsize module parameter, from Andrey
   Ryabinin.

6) Drop dst on skb before placing it in the fragmentation
   reassembly queue, from Florian Westphal.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Jul 9, 2018
2 parents 6508b67 + 84379c9 commit 26420d9
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 102 deletions.
6 changes: 6 additions & 0 deletions include/net/netfilter/nf_tables_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,10 @@ extern const struct nft_expr_ops nft_payload_fast_ops;
extern struct static_key_false nft_counters_enabled;
extern struct static_key_false nft_trace_enabled;

extern struct nft_set_type nft_set_rhash_type;
extern struct nft_set_type nft_set_hash_type;
extern struct nft_set_type nft_set_hash_fast_type;
extern struct nft_set_type nft_set_rbtree_type;
extern struct nft_set_type nft_set_bitmap_type;

#endif /* _NET_NF_TABLES_CORE_H */
4 changes: 2 additions & 2 deletions include/net/netfilter/nf_tproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
* belonging to established connections going through that one.
*/
struct sock *
nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb,
const u8 protocol,
const __be32 saddr, const __be32 daddr,
const __be16 sport, const __be16 dport,
Expand Down Expand Up @@ -103,7 +103,7 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
struct sock *sk);

struct sock *
nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff,
const u8 protocol,
const struct in6_addr *saddr, const struct in6_addr *daddr,
const __be16 sport, const __be16 dport,
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,7 @@ static struct xt_match ipt_builtin_mt[] __read_mostly = {
.checkentry = icmp_checkentry,
.proto = IPPROTO_ICMP,
.family = NFPROTO_IPV4,
.me = THIS_MODULE,
},
};

Expand Down
18 changes: 12 additions & 6 deletions net/ipv4/netfilter/nf_tproxy_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ nf_tproxy_handle_time_wait4(struct net *net, struct sk_buff *skb,
* to a listener socket if there's one */
struct sock *sk2;

sk2 = nf_tproxy_get_sock_v4(net, skb, hp, iph->protocol,
sk2 = nf_tproxy_get_sock_v4(net, skb, iph->protocol,
iph->saddr, laddr ? laddr : iph->daddr,
hp->source, lport ? lport : hp->dest,
skb->dev, NF_TPROXY_LOOKUP_LISTENER);
Expand Down Expand Up @@ -71,24 +71,29 @@ __be32 nf_tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr)
EXPORT_SYMBOL_GPL(nf_tproxy_laddr4);

struct sock *
nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb,
const u8 protocol,
const __be32 saddr, const __be32 daddr,
const __be16 sport, const __be16 dport,
const struct net_device *in,
const enum nf_tproxy_lookup_t lookup_type)
{
struct sock *sk;
struct tcphdr *tcph;

switch (protocol) {
case IPPROTO_TCP:
case IPPROTO_TCP: {
struct tcphdr _hdr, *hp;

hp = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(struct tcphdr), &_hdr);
if (hp == NULL)
return NULL;

switch (lookup_type) {
case NF_TPROXY_LOOKUP_LISTENER:
tcph = hp;
sk = inet_lookup_listener(net, &tcp_hashinfo, skb,
ip_hdrlen(skb) +
__tcp_hdrlen(tcph),
__tcp_hdrlen(hp),
saddr, sport,
daddr, dport,
in->ifindex, 0);
Expand All @@ -110,6 +115,7 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
BUG();
}
break;
}
case IPPROTO_UDP:
sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
in->ifindex);
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,7 @@ static struct xt_match ip6t_builtin_mt[] __read_mostly = {
.checkentry = icmp6_checkentry,
.proto = IPPROTO_ICMPV6,
.family = NFPROTO_IPV6,
.me = THIS_MODULE,
},
};

Expand Down
2 changes: 2 additions & 0 deletions net/ipv6/netfilter/nf_conntrack_reasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
fq->q.meat == fq->q.len &&
nf_ct_frag6_reasm(fq, skb, dev))
ret = 0;
else
skb_dst_drop(skb);

out_unlock:
spin_unlock_bh(&fq->q.lock);
Expand Down
18 changes: 12 additions & 6 deletions net/ipv6/netfilter/nf_tproxy_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
* to a listener socket if there's one */
struct sock *sk2;

sk2 = nf_tproxy_get_sock_v6(net, skb, thoff, hp, tproto,
sk2 = nf_tproxy_get_sock_v6(net, skb, thoff, tproto,
&iph->saddr,
nf_tproxy_laddr6(skb, laddr, &iph->daddr),
hp->source,
Expand All @@ -72,23 +72,28 @@ nf_tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff,
EXPORT_SYMBOL_GPL(nf_tproxy_handle_time_wait6);

struct sock *
nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff,
const u8 protocol,
const struct in6_addr *saddr, const struct in6_addr *daddr,
const __be16 sport, const __be16 dport,
const struct net_device *in,
const enum nf_tproxy_lookup_t lookup_type)
{
struct sock *sk;
struct tcphdr *tcph;

switch (protocol) {
case IPPROTO_TCP:
case IPPROTO_TCP: {
struct tcphdr _hdr, *hp;

hp = skb_header_pointer(skb, thoff,
sizeof(struct tcphdr), &_hdr);
if (hp == NULL)
return NULL;

switch (lookup_type) {
case NF_TPROXY_LOOKUP_LISTENER:
tcph = hp;
sk = inet6_lookup_listener(net, &tcp_hashinfo, skb,
thoff + __tcp_hdrlen(tcph),
thoff + __tcp_hdrlen(hp),
saddr, sport,
daddr, ntohs(dport),
in->ifindex, 0);
Expand All @@ -110,6 +115,7 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
BUG();
}
break;
}
case IPPROTO_UDP:
sk = udp6_lib_lookup(net, saddr, sport, daddr, dport,
in->ifindex);
Expand Down
25 changes: 7 additions & 18 deletions net/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,13 @@ config NF_TABLES

if NF_TABLES

config NF_TABLES_SET
tristate "Netfilter nf_tables set infrastructure"
help
This option enables the nf_tables set infrastructure that allows to
look up for elements in a set and to build one-way mappings between
matchings and actions.

config NF_TABLES_INET
depends on IPV6
select NF_TABLES_IPV4
Expand Down Expand Up @@ -493,24 +500,6 @@ config NFT_FLOW_OFFLOAD
This option adds the "flow_offload" expression that you can use to
choose what flows are placed into the hardware.

config NFT_SET_RBTREE
tristate "Netfilter nf_tables rbtree set module"
help
This option adds the "rbtree" set type (Red Black tree) that is used
to build interval-based sets.

config NFT_SET_HASH
tristate "Netfilter nf_tables hash set module"
help
This option adds the "hash" set type that is used to build one-way
mappings between matchings and actions.

config NFT_SET_BITMAP
tristate "Netfilter nf_tables bitmap set module"
help
This option adds the "bitmap" set type that is used to build sets
whose keys are smaller or equal to 16 bits.

config NFT_COUNTER
tristate "Netfilter nf_tables counter module"
help
Expand Down
7 changes: 4 additions & 3 deletions net/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ nf_tables-objs := nf_tables_core.o nf_tables_api.o nft_chain_filter.o \
nft_bitwise.o nft_byteorder.o nft_payload.o nft_lookup.o \
nft_dynset.o nft_meta.o nft_rt.o nft_exthdr.o

nf_tables_set-objs := nf_tables_set_core.o \
nft_set_hash.o nft_set_bitmap.o nft_set_rbtree.o

obj-$(CONFIG_NF_TABLES) += nf_tables.o
obj-$(CONFIG_NF_TABLES_SET) += nf_tables_set.o
obj-$(CONFIG_NFT_COMPAT) += nft_compat.o
obj-$(CONFIG_NFT_CONNLIMIT) += nft_connlimit.o
obj-$(CONFIG_NFT_NUMGEN) += nft_numgen.o
Expand All @@ -91,9 +95,6 @@ obj-$(CONFIG_NFT_QUEUE) += nft_queue.o
obj-$(CONFIG_NFT_QUOTA) += nft_quota.o
obj-$(CONFIG_NFT_REJECT) += nft_reject.o
obj-$(CONFIG_NFT_REJECT_INET) += nft_reject_inet.o
obj-$(CONFIG_NFT_SET_RBTREE) += nft_set_rbtree.o
obj-$(CONFIG_NFT_SET_HASH) += nft_set_hash.o
obj-$(CONFIG_NFT_SET_BITMAP) += nft_set_bitmap.o
obj-$(CONFIG_NFT_COUNTER) += nft_counter.o
obj-$(CONFIG_NFT_LOG) += nft_log.o
obj-$(CONFIG_NFT_MASQ) += nft_masq.o
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,7 @@ int nf_conntrack_set_hashsize(const char *val, const struct kernel_param *kp)
return -EOPNOTSUPP;

/* On boot, we can set this without any fancy locking. */
if (!nf_conntrack_htable_size)
if (!nf_conntrack_hash)
return param_set_uint(val, kp);

rc = kstrtouint(val, 0, &hashsize);
Expand Down
28 changes: 28 additions & 0 deletions net/netfilter/nf_tables_set_core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <net/netfilter/nf_tables_core.h>

static int __init nf_tables_set_module_init(void)
{
nft_register_set(&nft_set_hash_fast_type);
nft_register_set(&nft_set_hash_type);
nft_register_set(&nft_set_rhash_type);
nft_register_set(&nft_set_bitmap_type);
nft_register_set(&nft_set_rbtree_type);

return 0;
}

static void __exit nf_tables_set_module_exit(void)
{
nft_unregister_set(&nft_set_rbtree_type);
nft_unregister_set(&nft_set_bitmap_type);
nft_unregister_set(&nft_set_rhash_type);
nft_unregister_set(&nft_set_hash_type);
nft_unregister_set(&nft_set_hash_fast_type);
}

module_init(nf_tables_set_module_init);
module_exit(nf_tables_set_module_exit);

MODULE_LICENSE("GPL");
MODULE_ALIAS_NFT_SET();
13 changes: 13 additions & 0 deletions net/netfilter/nft_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,10 +832,18 @@ nft_target_select_ops(const struct nft_ctx *ctx,
rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV]));
family = ctx->family;

if (strcmp(tg_name, XT_ERROR_TARGET) == 0 ||
strcmp(tg_name, XT_STANDARD_TARGET) == 0 ||
strcmp(tg_name, "standard") == 0)
return ERR_PTR(-EINVAL);

/* Re-use the existing target if it's already loaded. */
list_for_each_entry(nft_target, &nft_target_list, head) {
struct xt_target *target = nft_target->ops.data;

if (!target->target)
continue;

if (nft_target_cmp(target, tg_name, rev, family))
return &nft_target->ops;
}
Expand All @@ -844,6 +852,11 @@ nft_target_select_ops(const struct nft_ctx *ctx,
if (IS_ERR(target))
return ERR_PTR(-ENOENT);

if (!target->target) {
err = -EINVAL;
goto err;
}

if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) {
err = -EINVAL;
goto err;
Expand Down
19 changes: 1 addition & 18 deletions net/netfilter/nft_set_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features,
return true;
}

static struct nft_set_type nft_bitmap_type __read_mostly = {
struct nft_set_type nft_set_bitmap_type __read_mostly = {
.owner = THIS_MODULE,
.ops = {
.privsize = nft_bitmap_privsize,
Expand All @@ -314,20 +314,3 @@ static struct nft_set_type nft_bitmap_type __read_mostly = {
.get = nft_bitmap_get,
},
};

static int __init nft_bitmap_module_init(void)
{
return nft_register_set(&nft_bitmap_type);
}

static void __exit nft_bitmap_module_exit(void)
{
nft_unregister_set(&nft_bitmap_type);
}

module_init(nft_bitmap_module_init);
module_exit(nft_bitmap_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
MODULE_ALIAS_NFT_SET();
29 changes: 3 additions & 26 deletions net/netfilter/nft_set_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ static bool nft_hash_fast_estimate(const struct nft_set_desc *desc, u32 features
return true;
}

static struct nft_set_type nft_rhash_type __read_mostly = {
struct nft_set_type nft_set_rhash_type __read_mostly = {
.owner = THIS_MODULE,
.features = NFT_SET_MAP | NFT_SET_OBJECT |
NFT_SET_TIMEOUT | NFT_SET_EVAL,
Expand All @@ -677,7 +677,7 @@ static struct nft_set_type nft_rhash_type __read_mostly = {
},
};

static struct nft_set_type nft_hash_type __read_mostly = {
struct nft_set_type nft_set_hash_type __read_mostly = {
.owner = THIS_MODULE,
.features = NFT_SET_MAP | NFT_SET_OBJECT,
.ops = {
Expand All @@ -697,7 +697,7 @@ static struct nft_set_type nft_hash_type __read_mostly = {
},
};

static struct nft_set_type nft_hash_fast_type __read_mostly = {
struct nft_set_type nft_set_hash_fast_type __read_mostly = {
.owner = THIS_MODULE,
.features = NFT_SET_MAP | NFT_SET_OBJECT,
.ops = {
Expand All @@ -716,26 +716,3 @@ static struct nft_set_type nft_hash_fast_type __read_mostly = {
.get = nft_hash_get,
},
};

static int __init nft_hash_module_init(void)
{
if (nft_register_set(&nft_hash_fast_type) ||
nft_register_set(&nft_hash_type) ||
nft_register_set(&nft_rhash_type))
return 1;
return 0;
}

static void __exit nft_hash_module_exit(void)
{
nft_unregister_set(&nft_rhash_type);
nft_unregister_set(&nft_hash_type);
nft_unregister_set(&nft_hash_fast_type);
}

module_init(nft_hash_module_init);
module_exit(nft_hash_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_ALIAS_NFT_SET();
Loading

0 comments on commit 26420d9

Please sign in to comment.