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,
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 18, 2016
2 parents ce449ba + 1463847 commit 695ef16
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 18 deletions.
1 change: 1 addition & 0 deletions include/net/netfilter/nf_tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ struct nft_set_elem {

struct nft_set;
struct nft_set_iter {
u8 genmask;
unsigned int count;
unsigned int skip;
int err;
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/netfilter/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ header-y += xt_NFLOG.h
header-y += xt_NFQUEUE.h
header-y += xt_RATEEST.h
header-y += xt_SECMARK.h
header-y += xt_SYNPROXY.h
header-y += xt_TCPMSS.h
header-y += xt_TCPOPTSTRIP.h
header-y += xt_TEE.h
Expand Down
2 changes: 2 additions & 0 deletions include/uapi/linux/netfilter/xt_SYNPROXY.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _XT_SYNPROXY_H
#define _XT_SYNPROXY_H

#include <linux/types.h>

#define XT_SYNPROXY_OPT_MSS 0x01
#define XT_SYNPROXY_OPT_WSCALE 0x02
#define XT_SYNPROXY_OPT_SACK_PERM 0x04
Expand Down
2 changes: 2 additions & 0 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,8 @@ void nf_conntrack_cleanup_end(void)
nf_conntrack_tstamp_fini();
nf_conntrack_acct_fini();
nf_conntrack_expect_fini();

kmem_cache_destroy(nf_conntrack_cachep);
}

/*
Expand Down
24 changes: 11 additions & 13 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
list_for_each_entry(i, &set->bindings, list) {
if (binding->flags & NFT_SET_MAP &&
if (i->flags & NFT_SET_MAP &&
i->chain == binding->chain)
goto bind;
}

iter.genmask = nft_genmask_next(ctx->net);
iter.skip = 0;
iter.count = 0;
iter.err = 0;
iter.fn = nf_tables_bind_check_setelem;

set->ops->walk(ctx, set, &iter);
if (iter.err < 0) {
/* Destroy anonymous sets if binding fails */
if (set->flags & NFT_SET_ANONYMOUS)
nf_tables_set_destroy(ctx, set);

if (iter.err < 0)
return iter.err;
}
}
bind:
binding->chain = ctx->chain;
Expand Down Expand Up @@ -3192,12 +3188,13 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
if (nest == NULL)
goto nla_put_failure;

args.cb = cb;
args.skb = skb;
args.iter.skip = cb->args[0];
args.iter.count = 0;
args.iter.err = 0;
args.iter.fn = nf_tables_dump_setelem;
args.cb = cb;
args.skb = skb;
args.iter.genmask = nft_genmask_cur(ctx.net);
args.iter.skip = cb->args[0];
args.iter.count = 0;
args.iter.err = 0;
args.iter.fn = nf_tables_dump_setelem;
set->ops->walk(&ctx, set, &args.iter);

nla_nest_end(skb, nest);
Expand Down Expand Up @@ -4284,6 +4281,7 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
binding->chain != chain)
continue;

iter.genmask = nft_genmask_next(ctx->net);
iter.skip = 0;
iter.count = 0;
iter.err = 0;
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_tables_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
list_for_each_entry_continue_rcu(rule, &chain->rules, list) {

/* This rule is not active, skip. */
if (unlikely(rule->genmask & (1 << gencursor)))
if (unlikely(rule->genmask & gencursor))
continue;

rulenum++;
Expand Down
3 changes: 1 addition & 2 deletions net/netfilter/nft_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 rhashtable_iter hti;
struct nft_set_elem elem;
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
int err;

err = rhashtable_walk_init(&priv->ht, &hti, GFP_KERNEL);
Expand Down Expand Up @@ -218,7 +217,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
goto cont;
if (nft_set_elem_expired(&he->ext))
goto cont;
if (!nft_set_elem_active(&he->ext, genmask))
if (!nft_set_elem_active(&he->ext, iter->genmask))
goto cont;

elem.priv = he;
Expand Down
3 changes: 1 addition & 2 deletions net/netfilter/nft_rbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,14 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
struct nft_rbtree_elem *rbe;
struct nft_set_elem elem;
struct rb_node *node;
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));

spin_lock_bh(&nft_rbtree_lock);
for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
rbe = rb_entry(node, struct nft_rbtree_elem, node);

if (iter->count < iter->skip)
goto cont;
if (!nft_set_elem_active(&rbe->ext, genmask))
if (!nft_set_elem_active(&rbe->ext, iter->genmask))
goto cont;

elem.priv = rbe;
Expand Down

0 comments on commit 695ef16

Please sign in to comment.