mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
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 updates for your net tree, they are: 1) Dump only conntrack that belong to this namespace via /proc file. This is some fallout from the conversion to single conntrack table for all netns, patch from Liping Zhang. 2) Missing MODULE_ALIAS_NF_LOGGER() for the ARP family that prevents module autoloading, also from Liping Zhang. 3) Report overquota event to the right netnamespace, again from Liping. 4) Fix tproxy listener sk refcount that leads to crash, from Eric Dumazet. 5) Fix racy refcounting on object deletion from nfnetlink and rule removal both for nfacct and cttimeout, from Liping Zhang. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
53409afd3e
@ -15,6 +15,6 @@ struct nf_acct;
|
||||
struct nf_acct *nfnl_acct_find_get(struct net *net, const char *filter_name);
|
||||
void nfnl_acct_put(struct nf_acct *acct);
|
||||
void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct);
|
||||
extern int nfnl_acct_overquota(const struct sk_buff *skb,
|
||||
struct nf_acct *nfacct);
|
||||
int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb,
|
||||
struct nf_acct *nfacct);
|
||||
#endif /* _NFNL_ACCT_H */
|
||||
|
@ -205,6 +205,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
|
||||
const struct nf_conntrack_l3proto *l3proto;
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
struct net *net = seq_file_net(s);
|
||||
int ret = 0;
|
||||
|
||||
NF_CT_ASSERT(ct);
|
||||
@ -215,6 +216,9 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
if (NF_CT_DIRECTION(hash))
|
||||
goto release;
|
||||
|
||||
if (!net_eq(nf_ct_net(ct), net))
|
||||
goto release;
|
||||
|
||||
l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
|
||||
NF_CT_ASSERT(l3proto);
|
||||
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
|
||||
|
@ -326,14 +326,14 @@ static int nfnl_acct_try_del(struct nf_acct *cur)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* we want to avoid races with nfnl_acct_find_get. */
|
||||
if (atomic_dec_and_test(&cur->refcnt)) {
|
||||
/* We want to avoid races with nfnl_acct_put. So only when the current
|
||||
* refcnt is 1, we decrease it to 0.
|
||||
*/
|
||||
if (atomic_cmpxchg(&cur->refcnt, 1, 0) == 1) {
|
||||
/* We are protected by nfnl mutex. */
|
||||
list_del_rcu(&cur->head);
|
||||
kfree_rcu(cur, rcu_head);
|
||||
} else {
|
||||
/* still in use, restore reference counter. */
|
||||
atomic_inc(&cur->refcnt);
|
||||
ret = -EBUSY;
|
||||
}
|
||||
return ret;
|
||||
@ -443,7 +443,7 @@ void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nfnl_acct_update);
|
||||
|
||||
static void nfnl_overquota_report(struct nf_acct *nfacct)
|
||||
static void nfnl_overquota_report(struct net *net, struct nf_acct *nfacct)
|
||||
{
|
||||
int ret;
|
||||
struct sk_buff *skb;
|
||||
@ -458,11 +458,12 @@ static void nfnl_overquota_report(struct nf_acct *nfacct)
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
netlink_broadcast(init_net.nfnl, skb, 0, NFNLGRP_ACCT_QUOTA,
|
||||
netlink_broadcast(net->nfnl, skb, 0, NFNLGRP_ACCT_QUOTA,
|
||||
GFP_ATOMIC);
|
||||
}
|
||||
|
||||
int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct)
|
||||
int nfnl_acct_overquota(struct net *net, const struct sk_buff *skb,
|
||||
struct nf_acct *nfacct)
|
||||
{
|
||||
u64 now;
|
||||
u64 *quota;
|
||||
@ -480,7 +481,7 @@ int nfnl_acct_overquota(const struct sk_buff *skb, struct nf_acct *nfacct)
|
||||
|
||||
if (now >= *quota &&
|
||||
!test_and_set_bit(NFACCT_OVERQUOTA_BIT, &nfacct->flags)) {
|
||||
nfnl_overquota_report(nfacct);
|
||||
nfnl_overquota_report(net, nfacct);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -330,16 +330,16 @@ static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* we want to avoid races with nf_ct_timeout_find_get. */
|
||||
if (atomic_dec_and_test(&timeout->refcnt)) {
|
||||
/* We want to avoid races with ctnl_timeout_put. So only when the
|
||||
* current refcnt is 1, we decrease it to 0.
|
||||
*/
|
||||
if (atomic_cmpxchg(&timeout->refcnt, 1, 0) == 1) {
|
||||
/* We are protected by nfnl mutex. */
|
||||
list_del_rcu(&timeout->head);
|
||||
nf_ct_l4proto_put(timeout->l4proto);
|
||||
ctnl_untimeout(net, timeout);
|
||||
kfree_rcu(timeout, rcu_head);
|
||||
} else {
|
||||
/* still in use, restore reference counter. */
|
||||
atomic_inc(&timeout->refcnt);
|
||||
ret = -EBUSY;
|
||||
}
|
||||
return ret;
|
||||
@ -543,7 +543,9 @@ err:
|
||||
|
||||
static void ctnl_timeout_put(struct ctnl_timeout *timeout)
|
||||
{
|
||||
atomic_dec(&timeout->refcnt);
|
||||
if (atomic_dec_and_test(&timeout->refcnt))
|
||||
kfree_rcu(timeout, rcu_head);
|
||||
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
|
||||
@ -591,7 +593,9 @@ static void __net_exit cttimeout_net_exit(struct net *net)
|
||||
list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) {
|
||||
list_del_rcu(&cur->head);
|
||||
nf_ct_l4proto_put(cur->l4proto);
|
||||
kfree_rcu(cur, rcu_head);
|
||||
|
||||
if (atomic_dec_and_test(&cur->refcnt))
|
||||
kfree_rcu(cur, rcu_head);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1147,6 +1147,7 @@ MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
|
||||
MODULE_ALIAS_NF_LOGGER(AF_INET, 1);
|
||||
MODULE_ALIAS_NF_LOGGER(AF_INET6, 1);
|
||||
MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1);
|
||||
MODULE_ALIAS_NF_LOGGER(3, 1); /* NFPROTO_ARP */
|
||||
|
||||
module_init(nfnetlink_log_init);
|
||||
module_exit(nfnetlink_log_fini);
|
||||
|
@ -127,6 +127,8 @@ nf_tproxy_get_sock_v4(struct net *net, struct sk_buff *skb, void *hp,
|
||||
daddr, dport,
|
||||
in->ifindex);
|
||||
|
||||
if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
|
||||
sk = NULL;
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
@ -195,6 +197,8 @@ nf_tproxy_get_sock_v6(struct net *net, struct sk_buff *skb, int thoff, void *hp,
|
||||
daddr, ntohs(dport),
|
||||
in->ifindex);
|
||||
|
||||
if (sk && !atomic_inc_not_zero(&sk->sk_refcnt))
|
||||
sk = NULL;
|
||||
/* NOTE: we return listeners even if bound to
|
||||
* 0.0.0.0, those are filtered out in
|
||||
* xt_socket, since xt_TPROXY needs 0 bound
|
||||
|
@ -26,7 +26,7 @@ static bool nfacct_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
|
||||
nfnl_acct_update(skb, info->nfacct);
|
||||
|
||||
overquota = nfnl_acct_overquota(skb, info->nfacct);
|
||||
overquota = nfnl_acct_overquota(par->net, skb, info->nfacct);
|
||||
|
||||
return overquota == NFACCT_UNDERQUOTA ? false : true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user