forked from Minki/linux
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: 1) Fix use after free of struct proc_dir_entry in ipt_CLUSTERIP, patch from Sabrina Dubroca. 2) Fix spurious EINVAL errors from iptables over nft compatibility layer. 3) Reload pointer to ip header only if there is non-terminal verdict, ie. XT_CONTINUE, otherwise invalid memory access may happen, patch from Taehee Yoo. 4) Fix interaction between SYNPROXY and NAT, SYNPROXY adds sequence adjustment already, however from nf_nat_setup() assumes there's not. Patch from Xin Long. 5) Fix burst arithmetics in nft_limit as Joe Stringer mentioned during NFWS in Faro. Patch from Andy Zhou. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
af57d2b720
@ -268,14 +268,14 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
acpar.targinfo = t->data;
|
||||
verdict = t->u.kernel.target->target(skb, &acpar);
|
||||
|
||||
/* Target might have changed stuff. */
|
||||
arp = arp_hdr(skb);
|
||||
|
||||
if (verdict == XT_CONTINUE)
|
||||
if (verdict == XT_CONTINUE) {
|
||||
/* Target might have changed stuff. */
|
||||
arp = arp_hdr(skb);
|
||||
e = arpt_next_entry(e);
|
||||
else
|
||||
} else {
|
||||
/* Verdict */
|
||||
break;
|
||||
}
|
||||
} while (!acpar.hotdrop);
|
||||
xt_write_recseq_end(addend);
|
||||
local_bh_enable();
|
||||
|
@ -352,13 +352,14 @@ ipt_do_table(struct sk_buff *skb,
|
||||
acpar.targinfo = t->data;
|
||||
|
||||
verdict = t->u.kernel.target->target(skb, &acpar);
|
||||
/* Target might have changed stuff. */
|
||||
ip = ip_hdr(skb);
|
||||
if (verdict == XT_CONTINUE)
|
||||
if (verdict == XT_CONTINUE) {
|
||||
/* Target might have changed stuff. */
|
||||
ip = ip_hdr(skb);
|
||||
e = ipt_next_entry(e);
|
||||
else
|
||||
} else {
|
||||
/* Verdict */
|
||||
break;
|
||||
}
|
||||
} while (!acpar.hotdrop);
|
||||
|
||||
xt_write_recseq_end(addend);
|
||||
|
@ -117,7 +117,8 @@ clusterip_config_entry_put(struct net *net, struct clusterip_config *c)
|
||||
* functions are also incrementing the refcount on their own,
|
||||
* so it's safe to remove the entry even if it's in use. */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
proc_remove(c->pde);
|
||||
if (cn->procdir)
|
||||
proc_remove(c->pde);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@ -815,6 +816,7 @@ static void clusterip_net_exit(struct net *net)
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct clusterip_net *cn = net_generic(net, clusterip_net_id);
|
||||
proc_remove(cn->procdir);
|
||||
cn->procdir = NULL;
|
||||
#endif
|
||||
nf_unregister_net_hook(net, &cip_arp_ops);
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ nf_nat_setup_info(struct nf_conn *ct,
|
||||
else
|
||||
ct->status |= IPS_DST_NAT;
|
||||
|
||||
if (nfct_help(ct))
|
||||
if (nfct_help(ct) && !nfct_seqadj(ct))
|
||||
if (!nfct_seqadj_ext_add(ct))
|
||||
return NF_DROP;
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
|
||||
const struct nf_hook_ops *ops = &basechain->ops[0];
|
||||
|
||||
hook_mask = 1 << ops->hooknum;
|
||||
if (!(hook_mask & target->hooks))
|
||||
if (target->hooks && !(hook_mask & target->hooks))
|
||||
return -EINVAL;
|
||||
|
||||
ret = nft_compat_chain_validate_dependency(target->table,
|
||||
@ -484,7 +484,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
|
||||
const struct nf_hook_ops *ops = &basechain->ops[0];
|
||||
|
||||
hook_mask = 1 << ops->hooknum;
|
||||
if (!(hook_mask & match->hooks))
|
||||
if (match->hooks && !(hook_mask & match->hooks))
|
||||
return -EINVAL;
|
||||
|
||||
ret = nft_compat_chain_validate_dependency(match->table,
|
||||
|
@ -65,19 +65,23 @@ static int nft_limit_init(struct nft_limit *limit,
|
||||
limit->nsecs = unit * NSEC_PER_SEC;
|
||||
if (limit->rate == 0 || limit->nsecs < unit)
|
||||
return -EOVERFLOW;
|
||||
limit->tokens = limit->tokens_max = limit->nsecs;
|
||||
|
||||
if (tb[NFTA_LIMIT_BURST]) {
|
||||
u64 rate;
|
||||
|
||||
if (tb[NFTA_LIMIT_BURST])
|
||||
limit->burst = ntohl(nla_get_be32(tb[NFTA_LIMIT_BURST]));
|
||||
else
|
||||
limit->burst = 0;
|
||||
|
||||
rate = limit->rate + limit->burst;
|
||||
if (rate < limit->rate)
|
||||
return -EOVERFLOW;
|
||||
if (limit->rate + limit->burst < limit->rate)
|
||||
return -EOVERFLOW;
|
||||
|
||||
/* The token bucket size limits the number of tokens can be
|
||||
* accumulated. tokens_max specifies the bucket size.
|
||||
* tokens_max = unit * (rate + burst) / rate.
|
||||
*/
|
||||
limit->tokens = div_u64(limit->nsecs * (limit->rate + limit->burst),
|
||||
limit->rate);
|
||||
limit->tokens_max = limit->tokens;
|
||||
|
||||
limit->rate = rate;
|
||||
}
|
||||
if (tb[NFTA_LIMIT_FLAGS]) {
|
||||
u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
|
||||
|
||||
@ -95,9 +99,8 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit,
|
||||
{
|
||||
u32 flags = limit->invert ? NFT_LIMIT_F_INV : 0;
|
||||
u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC);
|
||||
u64 rate = limit->rate - limit->burst;
|
||||
|
||||
if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(rate),
|
||||
if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(limit->rate),
|
||||
NFTA_LIMIT_PAD) ||
|
||||
nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs),
|
||||
NFTA_LIMIT_PAD) ||
|
||||
|
Loading…
Reference in New Issue
Block a user