Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Browse files Browse the repository at this point in the history
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: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Sep 13, 2016
2 parents da499f8 + 4440a2a commit 67b9f0b
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 13 deletions.
14 changes: 14 additions & 0 deletions include/net/netfilter/nf_conntrack_synproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ static inline struct nf_conn_synproxy *nfct_synproxy_ext_add(struct nf_conn *ct)
#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 {
unsigned int syn_received;
unsigned int cookie_invalid;
Expand Down
11 changes: 7 additions & 4 deletions net/ipv4/netfilter/nft_chain_route_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv,
__be32 saddr, daddr;
u_int8_t tos;
const struct iphdr *iph;
int err;

/* root is playing with raw sockets. */
if (skb->len < sizeof(struct iphdr) ||
Expand All @@ -46,15 +47,17 @@ static unsigned int nf_route_table_hook(void *priv,
tos = iph->tos;

ret = nft_do_chain(&pkt, priv);
if (ret != NF_DROP && ret != NF_QUEUE) {
if (ret != NF_DROP && ret != NF_STOLEN) {
iph = ip_hdr(skb);

if (iph->saddr != saddr ||
iph->daddr != daddr ||
skb->mark != mark ||
iph->tos != tos)
if (ip_route_me_harder(state->net, skb, RTN_UNSPEC))
ret = NF_DROP;
iph->tos != tos) {
err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
if (err < 0)
ret = NF_DROP_ERR(err);
}
}
return ret;
}
Expand Down
10 changes: 7 additions & 3 deletions net/ipv6/netfilter/nft_chain_route_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static unsigned int nf_route_table_hook(void *priv,
struct in6_addr saddr, daddr;
u_int8_t hop_limit;
u32 mark, flowlabel;
int err;

/* malformed packet, drop it */
if (nft_set_pktinfo_ipv6(&pkt, skb, state) < 0)
Expand All @@ -46,13 +47,16 @@ static unsigned int nf_route_table_hook(void *priv,
flowlabel = *((u32 *)ipv6_hdr(skb));

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)->daddr, &daddr, sizeof(daddr)) ||
skb->mark != mark ||
ipv6_hdr(skb)->hop_limit != hop_limit ||
flowlabel != *((u_int32_t *)ipv6_hdr(skb))))
return ip6_route_me_harder(state->net, skb) == 0 ? ret : NF_DROP;
flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
err = ip6_route_me_harder(state->net, skb);
if (err < 0)
ret = NF_DROP_ERR(err);
}

return ret;
}
Expand Down
6 changes: 3 additions & 3 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1035,9 +1035,9 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
if (IS_ERR(ct))
return (struct nf_conntrack_tuple_hash *)ct;

if (tmpl && nfct_synproxy(tmpl)) {
nfct_seqadj_ext_add(ct);
nfct_synproxy_ext_add(ct);
if (!nf_ct_add_synproxy(ct, tmpl)) {
nf_conntrack_free(ct);
return ERR_PTR(-ENOMEM);
}

timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;
Expand Down
5 changes: 3 additions & 2 deletions net/netfilter/nf_nat_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ nf_nat_setup_info(struct nf_conn *ct,
ct->status |= IPS_DST_NAT;

if (nfct_help(ct))
nfct_seqadj_ext_add(ct);
if (!nfct_seqadj_ext_add(ct))
return NF_DROP;
}

if (maniptype == NF_NAT_MANIP_SRC) {
Expand Down Expand Up @@ -807,7 +808,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
if (err < 0)
return err;

return nf_nat_setup_info(ct, &range, manip);
return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0;
}
#else
static int
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/nf_tables_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ void nft_trace_notify(struct nft_traceinfo *info)
break;
case NFT_TRACETYPE_POLICY:
if (nla_put_be32(skb, NFTA_TRACE_POLICY,
info->basechain->policy))
htonl(info->basechain->policy)))
goto nla_put_failure;
break;
}
Expand Down

0 comments on commit 67b9f0b

Please sign in to comment.