Commit 55919b32 authored by David S. Miller's avatar David S. Miller

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

Pablo Neira Ayuso says:

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

The following contain more Netfilter fixes for net:

1) syzbot warning in nfnetlink bind, from Florian.

2) Refetch conntrack after __nf_conntrack_confirm(), from Florian Westphal.

3) Move struct nf_ct_timeout back at the bottom of the ctnl_time, to
   where it before recent update, also from Florian.

4) Add NL_SET_BAD_ATTR() to nf_tables netlink for proper set element
   commands error reporting.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 02ded5a1 b53c1166
...@@ -58,8 +58,13 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb) ...@@ -58,8 +58,13 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
int ret = NF_ACCEPT; int ret = NF_ACCEPT;
if (ct) { if (ct) {
if (!nf_ct_is_confirmed(ct)) if (!nf_ct_is_confirmed(ct)) {
ret = __nf_conntrack_confirm(skb); ret = __nf_conntrack_confirm(skb);
if (ret == NF_ACCEPT)
ct = (struct nf_conn *)skb_nfct(skb);
}
if (ret == NF_ACCEPT && nf_ct_ecache_exist(ct)) if (ret == NF_ACCEPT && nf_ct_ecache_exist(ct))
nf_ct_deliver_cached_events(ct); nf_ct_deliver_cached_events(ct);
} }
......
...@@ -5348,8 +5348,10 @@ static int nf_tables_getsetelem(struct sk_buff *skb, ...@@ -5348,8 +5348,10 @@ static int nf_tables_getsetelem(struct sk_buff *skb,
nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
err = nft_get_set_elem(&ctx, set, attr); err = nft_get_set_elem(&ctx, set, attr);
if (err < 0) if (err < 0) {
NL_SET_BAD_ATTR(extack, attr);
break; break;
}
} }
return err; return err;
...@@ -6126,8 +6128,10 @@ static int nf_tables_newsetelem(struct sk_buff *skb, ...@@ -6126,8 +6128,10 @@ static int nf_tables_newsetelem(struct sk_buff *skb,
nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
err = nft_add_set_elem(&ctx, set, attr, info->nlh->nlmsg_flags); err = nft_add_set_elem(&ctx, set, attr, info->nlh->nlmsg_flags);
if (err < 0) if (err < 0) {
NL_SET_BAD_ATTR(extack, attr);
return err; return err;
}
} }
if (nft_net->validate_state == NFT_VALIDATE_DO) if (nft_net->validate_state == NFT_VALIDATE_DO)
...@@ -6397,8 +6401,10 @@ static int nf_tables_delsetelem(struct sk_buff *skb, ...@@ -6397,8 +6401,10 @@ static int nf_tables_delsetelem(struct sk_buff *skb,
nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
err = nft_del_setelem(&ctx, set, attr); err = nft_del_setelem(&ctx, set, attr);
if (err < 0) if (err < 0) {
NL_SET_BAD_ATTR(extack, attr);
break; break;
}
} }
return err; return err;
} }
......
...@@ -45,7 +45,6 @@ MODULE_DESCRIPTION("Netfilter messages via netlink socket"); ...@@ -45,7 +45,6 @@ MODULE_DESCRIPTION("Netfilter messages via netlink socket");
static unsigned int nfnetlink_pernet_id __read_mostly; static unsigned int nfnetlink_pernet_id __read_mostly;
struct nfnl_net { struct nfnl_net {
unsigned int ctnetlink_listeners;
struct sock *nfnl; struct sock *nfnl;
}; };
...@@ -673,18 +672,8 @@ static int nfnetlink_bind(struct net *net, int group) ...@@ -673,18 +672,8 @@ static int nfnetlink_bind(struct net *net, int group)
#ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_EVENTS
if (type == NFNL_SUBSYS_CTNETLINK) { if (type == NFNL_SUBSYS_CTNETLINK) {
struct nfnl_net *nfnlnet = nfnl_pernet(net);
nfnl_lock(NFNL_SUBSYS_CTNETLINK); nfnl_lock(NFNL_SUBSYS_CTNETLINK);
WRITE_ONCE(net->ct.ctnetlink_has_listener, true);
if (WARN_ON_ONCE(nfnlnet->ctnetlink_listeners == UINT_MAX)) {
nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
return -EOVERFLOW;
}
nfnlnet->ctnetlink_listeners++;
if (nfnlnet->ctnetlink_listeners == 1)
WRITE_ONCE(net->ct.ctnetlink_has_listener, true);
nfnl_unlock(NFNL_SUBSYS_CTNETLINK); nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
} }
#endif #endif
...@@ -694,15 +683,12 @@ static int nfnetlink_bind(struct net *net, int group) ...@@ -694,15 +683,12 @@ static int nfnetlink_bind(struct net *net, int group)
static void nfnetlink_unbind(struct net *net, int group) static void nfnetlink_unbind(struct net *net, int group)
{ {
#ifdef CONFIG_NF_CONNTRACK_EVENTS #ifdef CONFIG_NF_CONNTRACK_EVENTS
int type = nfnl_group2type[group]; if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
return;
if (type == NFNL_SUBSYS_CTNETLINK) {
struct nfnl_net *nfnlnet = nfnl_pernet(net);
if (nfnl_group2type[group] == NFNL_SUBSYS_CTNETLINK) {
nfnl_lock(NFNL_SUBSYS_CTNETLINK); nfnl_lock(NFNL_SUBSYS_CTNETLINK);
WARN_ON_ONCE(nfnlnet->ctnetlink_listeners == 0); if (!nfnetlink_has_listeners(net, group))
nfnlnet->ctnetlink_listeners--;
if (nfnlnet->ctnetlink_listeners == 0)
WRITE_ONCE(net->ct.ctnetlink_has_listener, false); WRITE_ONCE(net->ct.ctnetlink_has_listener, false);
nfnl_unlock(NFNL_SUBSYS_CTNETLINK); nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
} }
......
...@@ -35,12 +35,13 @@ static unsigned int nfct_timeout_id __read_mostly; ...@@ -35,12 +35,13 @@ static unsigned int nfct_timeout_id __read_mostly;
struct ctnl_timeout { struct ctnl_timeout {
struct list_head head; struct list_head head;
struct list_head free_head;
struct rcu_head rcu_head; struct rcu_head rcu_head;
refcount_t refcnt; refcount_t refcnt;
char name[CTNL_TIMEOUT_NAME_MAX]; char name[CTNL_TIMEOUT_NAME_MAX];
struct nf_ct_timeout timeout;
struct list_head free_head; /* must be at the end */
struct nf_ct_timeout timeout;
}; };
struct nfct_timeout_pernet { struct nfct_timeout_pernet {
......
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