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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
67b9f0b737
6 changed files with 35 additions and 13 deletions
|
@ -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;
|
||||
|
|
|
@ -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) ||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue