Commit 79a392a3 authored by David S. Miller's avatar David S. Miller

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

Florian Westphal says:

====================
netfilter: bugfixes for net

The following set contains netfilter fixes for the *net* tree.

Regressions (rc only):
recent ebtables crash fix was incomplete, it added a memory leak.

The patch to fix possible buffer overrun for BIG TCP in ftp conntrack
tried to be too clever, we cannot re-use ct->lock: NAT engine might
grab it again -> deadlock.  Revert back to a global spinlock.
Both from myself.

Remove the documentation for the recently removed
'nf_conntrack_helper' sysctl as well, from Pablo Neira.

The static_branch_inc() that guards the 'chain stats enabled' path
needs to be deferred further, until the entire transaction was created.
From Tetsuo Handa.

Older bugs:
Since 5.3:
nf_tables_addchain may leak pcpu memory in error path when
offloading fails. Also from Tetsuo Handa.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6a1dbfef d2508893
...@@ -70,15 +70,6 @@ nf_conntrack_generic_timeout - INTEGER (seconds) ...@@ -70,15 +70,6 @@ nf_conntrack_generic_timeout - INTEGER (seconds)
Default for generic timeout. This refers to layer 4 unknown/unsupported Default for generic timeout. This refers to layer 4 unknown/unsupported
protocols. protocols.
nf_conntrack_helper - BOOLEAN
- 0 - disabled (default)
- not 0 - enabled
Enable automatic conntrack helper assignment.
If disabled it is required to set up iptables rules to assign
helpers to connections. See the CT target description in the
iptables-extensions(8) man page for further information.
nf_conntrack_icmp_timeout - INTEGER (seconds) nf_conntrack_icmp_timeout - INTEGER (seconds)
default 30 default 30
......
...@@ -1040,8 +1040,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl, ...@@ -1040,8 +1040,10 @@ static int do_replace_finish(struct net *net, struct ebt_replace *repl,
goto free_iterate; goto free_iterate;
} }
if (repl->valid_hooks != t->valid_hooks) if (repl->valid_hooks != t->valid_hooks) {
ret = -EINVAL;
goto free_unlock; goto free_unlock;
}
if (repl->num_counters && repl->num_counters != t->private->nentries) { if (repl->num_counters && repl->num_counters != t->private->nentries) {
ret = -EINVAL; ret = -EINVAL;
......
...@@ -33,6 +33,7 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); ...@@ -33,6 +33,7 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
MODULE_DESCRIPTION("ftp connection tracking helper"); MODULE_DESCRIPTION("ftp connection tracking helper");
MODULE_ALIAS("ip_conntrack_ftp"); MODULE_ALIAS("ip_conntrack_ftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME); MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
static DEFINE_SPINLOCK(nf_ftp_lock);
#define MAX_PORTS 8 #define MAX_PORTS 8
static u_int16_t ports[MAX_PORTS]; static u_int16_t ports[MAX_PORTS];
...@@ -409,7 +410,8 @@ static int help(struct sk_buff *skb, ...@@ -409,7 +410,8 @@ static int help(struct sk_buff *skb,
} }
datalen = skb->len - dataoff; datalen = skb->len - dataoff;
spin_lock_bh(&ct->lock); /* seqadj (nat) uses ct->lock internally, nf_nat_ftp would cause deadlock */
spin_lock_bh(&nf_ftp_lock);
fb_ptr = skb->data + dataoff; fb_ptr = skb->data + dataoff;
ends_in_nl = (fb_ptr[datalen - 1] == '\n'); ends_in_nl = (fb_ptr[datalen - 1] == '\n');
...@@ -538,7 +540,7 @@ static int help(struct sk_buff *skb, ...@@ -538,7 +540,7 @@ static int help(struct sk_buff *skb,
if (ends_in_nl) if (ends_in_nl)
update_nl_seq(ct, seq, ct_ftp_info, dir, skb); update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
out: out:
spin_unlock_bh(&ct->lock); spin_unlock_bh(&nf_ftp_lock);
return ret; return ret;
} }
......
...@@ -2197,7 +2197,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, ...@@ -2197,7 +2197,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct nlattr * const *nla = ctx->nla; const struct nlattr * const *nla = ctx->nla;
struct nft_stats __percpu *stats = NULL;
struct nft_table *table = ctx->table; struct nft_table *table = ctx->table;
struct nft_base_chain *basechain; struct nft_base_chain *basechain;
struct net *net = ctx->net; struct net *net = ctx->net;
...@@ -2212,6 +2211,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, ...@@ -2212,6 +2211,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
return -EOVERFLOW; return -EOVERFLOW;
if (nla[NFTA_CHAIN_HOOK]) { if (nla[NFTA_CHAIN_HOOK]) {
struct nft_stats __percpu *stats = NULL;
struct nft_chain_hook hook; struct nft_chain_hook hook;
if (flags & NFT_CHAIN_BINDING) if (flags & NFT_CHAIN_BINDING)
...@@ -2243,8 +2243,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, ...@@ -2243,8 +2243,11 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
if (err < 0) { if (err < 0) {
nft_chain_release_hook(&hook); nft_chain_release_hook(&hook);
kfree(basechain); kfree(basechain);
free_percpu(stats);
return err; return err;
} }
if (stats)
static_branch_inc(&nft_counters_enabled);
} else { } else {
if (flags & NFT_CHAIN_BASE) if (flags & NFT_CHAIN_BASE)
return -EINVAL; return -EINVAL;
...@@ -2319,9 +2322,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask, ...@@ -2319,9 +2322,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
goto err_unregister_hook; goto err_unregister_hook;
} }
if (stats)
static_branch_inc(&nft_counters_enabled);
table->use++; table->use++;
return 0; return 0;
......
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