Commit 695ef16c authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

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

The following patchset contains Netfilter fixes for your net tree,
they are rather small patches but fixing several outstanding bugs in
nf_conntrack and nf_tables, as well as minor problems with missing
SYNPROXY header uapi installation:

1) Oneliner not to leak conntrack kmemcache on module removal, this
   problem was introduced in the previous merge window, patch from
   Florian Westphal.

2) Two fixes for insufficient ruleset loop validation, one due to
   incorrect flag check in nf_tables_bind_set() and another related to
   silly wrong generation mask logic from the walk path, from Liping
   Zhang.

3) Fix double-free of anonymous sets on error, this fix simplifies the
   code to let the abort path take care of releasing the set object,
   also from Liping Zhang.

4) The introduction of helper function for transactions broke the skip
   inactive rules logic from the nft_do_chain(), again from Liping
   Zhang.

5) Two patches to install uapi xt_SYNPROXY.h header and calm down
   kbuild robot due to missing #include <linux/types.h>.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ce449ba7 1463847e
...@@ -167,6 +167,7 @@ struct nft_set_elem { ...@@ -167,6 +167,7 @@ struct nft_set_elem {
struct nft_set; struct nft_set;
struct nft_set_iter { struct nft_set_iter {
u8 genmask;
unsigned int count; unsigned int count;
unsigned int skip; unsigned int skip;
int err; int err;
......
...@@ -33,6 +33,7 @@ header-y += xt_NFLOG.h ...@@ -33,6 +33,7 @@ header-y += xt_NFLOG.h
header-y += xt_NFQUEUE.h header-y += xt_NFQUEUE.h
header-y += xt_RATEEST.h header-y += xt_RATEEST.h
header-y += xt_SECMARK.h header-y += xt_SECMARK.h
header-y += xt_SYNPROXY.h
header-y += xt_TCPMSS.h header-y += xt_TCPMSS.h
header-y += xt_TCPOPTSTRIP.h header-y += xt_TCPOPTSTRIP.h
header-y += xt_TEE.h header-y += xt_TEE.h
......
#ifndef _XT_SYNPROXY_H #ifndef _XT_SYNPROXY_H
#define _XT_SYNPROXY_H #define _XT_SYNPROXY_H
#include <linux/types.h>
#define XT_SYNPROXY_OPT_MSS 0x01 #define XT_SYNPROXY_OPT_MSS 0x01
#define XT_SYNPROXY_OPT_WSCALE 0x02 #define XT_SYNPROXY_OPT_WSCALE 0x02
#define XT_SYNPROXY_OPT_SACK_PERM 0x04 #define XT_SYNPROXY_OPT_SACK_PERM 0x04
......
...@@ -1544,6 +1544,8 @@ void nf_conntrack_cleanup_end(void) ...@@ -1544,6 +1544,8 @@ void nf_conntrack_cleanup_end(void)
nf_conntrack_tstamp_fini(); nf_conntrack_tstamp_fini();
nf_conntrack_acct_fini(); nf_conntrack_acct_fini();
nf_conntrack_expect_fini(); nf_conntrack_expect_fini();
kmem_cache_destroy(nf_conntrack_cachep);
} }
/* /*
......
...@@ -2946,24 +2946,20 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, ...@@ -2946,24 +2946,20 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
* jumps are already validated for that chain. * jumps are already validated for that chain.
*/ */
list_for_each_entry(i, &set->bindings, list) { list_for_each_entry(i, &set->bindings, list) {
if (binding->flags & NFT_SET_MAP && if (i->flags & NFT_SET_MAP &&
i->chain == binding->chain) i->chain == binding->chain)
goto bind; goto bind;
} }
iter.genmask = nft_genmask_next(ctx->net);
iter.skip = 0; iter.skip = 0;
iter.count = 0; iter.count = 0;
iter.err = 0; iter.err = 0;
iter.fn = nf_tables_bind_check_setelem; iter.fn = nf_tables_bind_check_setelem;
set->ops->walk(ctx, set, &iter); set->ops->walk(ctx, set, &iter);
if (iter.err < 0) { if (iter.err < 0)
/* Destroy anonymous sets if binding fails */
if (set->flags & NFT_SET_ANONYMOUS)
nf_tables_set_destroy(ctx, set);
return iter.err; return iter.err;
}
} }
bind: bind:
binding->chain = ctx->chain; binding->chain = ctx->chain;
...@@ -3192,12 +3188,13 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -3192,12 +3188,13 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
if (nest == NULL) if (nest == NULL)
goto nla_put_failure; goto nla_put_failure;
args.cb = cb; args.cb = cb;
args.skb = skb; args.skb = skb;
args.iter.skip = cb->args[0]; args.iter.genmask = nft_genmask_cur(ctx.net);
args.iter.count = 0; args.iter.skip = cb->args[0];
args.iter.err = 0; args.iter.count = 0;
args.iter.fn = nf_tables_dump_setelem; args.iter.err = 0;
args.iter.fn = nf_tables_dump_setelem;
set->ops->walk(&ctx, set, &args.iter); set->ops->walk(&ctx, set, &args.iter);
nla_nest_end(skb, nest); nla_nest_end(skb, nest);
...@@ -4284,6 +4281,7 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx, ...@@ -4284,6 +4281,7 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
binding->chain != chain) binding->chain != chain)
continue; continue;
iter.genmask = nft_genmask_next(ctx->net);
iter.skip = 0; iter.skip = 0;
iter.count = 0; iter.count = 0;
iter.err = 0; iter.err = 0;
......
...@@ -143,7 +143,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) ...@@ -143,7 +143,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
list_for_each_entry_continue_rcu(rule, &chain->rules, list) { list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
/* This rule is not active, skip. */ /* This rule is not active, skip. */
if (unlikely(rule->genmask & (1 << gencursor))) if (unlikely(rule->genmask & gencursor))
continue; continue;
rulenum++; rulenum++;
......
...@@ -189,7 +189,6 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, ...@@ -189,7 +189,6 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
struct nft_hash_elem *he; struct nft_hash_elem *he;
struct rhashtable_iter hti; struct rhashtable_iter hti;
struct nft_set_elem elem; struct nft_set_elem elem;
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
int err; int err;
err = rhashtable_walk_init(&priv->ht, &hti, GFP_KERNEL); err = rhashtable_walk_init(&priv->ht, &hti, GFP_KERNEL);
...@@ -218,7 +217,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, ...@@ -218,7 +217,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
goto cont; goto cont;
if (nft_set_elem_expired(&he->ext)) if (nft_set_elem_expired(&he->ext))
goto cont; goto cont;
if (!nft_set_elem_active(&he->ext, genmask)) if (!nft_set_elem_active(&he->ext, iter->genmask))
goto cont; goto cont;
elem.priv = he; elem.priv = he;
......
...@@ -211,7 +211,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, ...@@ -211,7 +211,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
struct nft_rbtree_elem *rbe; struct nft_rbtree_elem *rbe;
struct nft_set_elem elem; struct nft_set_elem elem;
struct rb_node *node; struct rb_node *node;
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
spin_lock_bh(&nft_rbtree_lock); spin_lock_bh(&nft_rbtree_lock);
for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
...@@ -219,7 +218,7 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, ...@@ -219,7 +218,7 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
if (iter->count < iter->skip) if (iter->count < iter->skip)
goto cont; goto cont;
if (!nft_set_elem_active(&rbe->ext, genmask)) if (!nft_set_elem_active(&rbe->ext, iter->genmask))
goto cont; goto cont;
elem.priv = rbe; elem.priv = rbe;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment