Commit 67b9f0b7 authored by David S. Miller's avatar David S. Miller

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) Endianess fix for the new nf_tables netlink trace infrastructure,
   NFTA_TRACE_POLICY endianess was not correct, patch from Liping Zhang.

2) Fix broken re-route after userspace queueing in nf_tables route
   chain. This patch is large but it is simple since it is just getting
   this code in sync with iptable_mangle. Also from Liping.

3) NAT mangling via ctnetlink lies to userspace when nf_nat_setup_info()
   fails to setup the NAT conntrack extension. This problem has been
   there since the beginning, but it can now show up after rhashtable
   conversion.

4) Fix possible NULL pointer dereference due to failures in allocating
   the synproxy and seqadj conntrack extensions, from Gao feng.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents da499f8f 4440a2ab
...@@ -27,6 +27,20 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct) ...@@ -27,6 +27,20 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct)
#endif #endif
} }
static inline bool nf_ct_add_synproxy(struct nf_conn *ct,
const struct nf_conn *tmpl)
{
if (tmpl && nfct_synproxy(tmpl)) {
if (!nfct_seqadj_ext_add(ct))
return false;
if (!nfct_synproxy_ext_add(ct))
return false;
}
return true;
}
struct synproxy_stats { struct synproxy_stats {
unsigned int syn_received; unsigned int syn_received;
unsigned int cookie_invalid; unsigned int cookie_invalid;
......
...@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, ...@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv,
__be32 saddr, daddr; __be32 saddr, daddr;
u_int8_t tos; u_int8_t tos;
const struct iphdr *iph; const struct iphdr *iph;
int err;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) || if (skb->len < sizeof(struct iphdr) ||
...@@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(void *priv, ...@@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(void *priv,
tos = iph->tos; tos = iph->tos;
ret = nft_do_chain(&pkt, priv); ret = nft_do_chain(&pkt, priv);
if (ret != NF_DROP && ret != NF_QUEUE) { if (ret != NF_DROP && ret != NF_STOLEN) {
iph = ip_hdr(skb); iph = ip_hdr(skb);
if (iph->saddr != saddr || if (iph->saddr != saddr ||
iph->daddr != daddr || iph->daddr != daddr ||
skb->mark != mark || skb->mark != mark ||
iph->tos != tos) iph->tos != tos) {
if (ip_route_me_harder(state->net, skb, RTN_UNSPEC)) err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
ret = NF_DROP; if (err < 0)
ret = NF_DROP_ERR(err);
}
} }
return ret; return ret;
} }
......
...@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv, ...@@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv,
struct in6_addr saddr, daddr; struct in6_addr saddr, daddr;
u_int8_t hop_limit; u_int8_t hop_limit;
u32 mark, flowlabel; u32 mark, flowlabel;
int err;
/* malformed packet, drop it */ /* malformed packet, drop it */
if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0) if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0)
...@@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(void *priv, ...@@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(void *priv,
flowlabel = *((u32 *)ipv6_hdr(skb)); flowlabel = *((u32 *)ipv6_hdr(skb));
ret = nft_do_chain(&pkt, priv); ret = nft_do_chain(&pkt, priv);
if (ret != NF_DROP && ret != NF_QUEUE && if (ret != NF_DROP && ret != NF_STOLEN &&
(memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) || (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) || memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
skb->mark != mark || skb->mark != mark ||
ipv6_hdr(skb)->hop_limit != hop_limit || ipv6_hdr(skb)->hop_limit != hop_limit ||
flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP; err = ip6_route_me_harder(state->net, skb);
if (err < 0)
ret = NF_DROP_ERR(err);
}
return ret; return ret;
} }
......
...@@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
if (IS_ERR(ct)) if (IS_ERR(ct))
return (struct nf_conntrack_tuple_hash *)ct; return (struct nf_conntrack_tuple_hash *)ct;
if (tmpl && nfct_synproxy(tmpl)) { if (!nf_ct_add_synproxy(ct, tmpl)) {
nfct_seqadj_ext_add(ct); nf_conntrack_free(ct);
nfct_synproxy_ext_add(ct); return ERR_PTR(-ENOMEM);
} }
timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL; timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
......
...@@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct, ...@@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct,
ct->status |= IPS_DST_NAT; ct->status |= IPS_DST_NAT;
if (nfct_help(ct)) if (nfct_help(ct))
nfct_seqadj_ext_add(ct); if (!nfct_seqadj_ext_add(ct))
return NF_DROP;
} }
if (maniptype == NF_NAT_MANIP_SRC) { if (maniptype == NF_NAT_MANIP_SRC) {
...@@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct, ...@@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
if (err < 0) if (err < 0)
return err; return err;
return nf_nat_setup_info(ct, &range, manip); return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0;
} }
#else #else
static int static int
......
...@@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_traceinfo *info) ...@@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_traceinfo *info)
break; break;
case NFT_TRACETYPE_POLICY: case NFT_TRACETYPE_POLICY:
if (nla_put_be32(skb, NFTA_TRACE_POLICY, if (nla_put_be32(skb, NFTA_TRACE_POLICY,
info->basechain->policy)) htonl(info->basechain->policy)))
goto nla_put_failure; goto nla_put_failure;
break; break;
} }
......
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