mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-28 13:22:57 +00:00
net/sched: act_ipt: add sanity checks on skb before calling target
Netfilter targets make assumptions on the skb state, for example
iphdr is supposed to be in the linear area.
This is normally done by IP stack, but in act_ipt case no
such checks are made.
Some targets can even assume that skb_dst will be valid.
Make a minimum effort to check for this:
- Don't call the targets eval function for non-ipv4 skbs.
- Don't call the targets eval function for POSTROUTING
emulation when the skb has no dst set.
v3: use skb_protocol helper (Davide Caratti)
Fixes: 1da177e4c3
("Linux-2.6.12-rc2")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
b4ee93380b
commit
b2dc32dcba
1 changed files with 33 additions and 0 deletions
|
@ -230,6 +230,26 @@ static int tcf_xt_init(struct net *net, struct nlattr *nla,
|
|||
a, &act_xt_ops, tp, flags);
|
||||
}
|
||||
|
||||
static bool tcf_ipt_act_check(struct sk_buff *skb)
|
||||
{
|
||||
const struct iphdr *iph;
|
||||
unsigned int nhoff, len;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
|
||||
return false;
|
||||
|
||||
nhoff = skb_network_offset(skb);
|
||||
iph = ip_hdr(skb);
|
||||
if (iph->ihl < 5 || iph->version != 4)
|
||||
return false;
|
||||
|
||||
len = skb_ip_totlen(skb);
|
||||
if (skb->len < nhoff + len || len < (iph->ihl * 4u))
|
||||
return false;
|
||||
|
||||
return pskb_may_pull(skb, iph->ihl * 4u);
|
||||
}
|
||||
|
||||
TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
|
||||
const struct tc_action *a,
|
||||
struct tcf_result *res)
|
||||
|
@ -244,9 +264,22 @@ TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
|
|||
.pf = NFPROTO_IPV4,
|
||||
};
|
||||
|
||||
if (skb_protocol(skb, false) != htons(ETH_P_IP))
|
||||
return TC_ACT_UNSPEC;
|
||||
|
||||
if (skb_unclone(skb, GFP_ATOMIC))
|
||||
return TC_ACT_UNSPEC;
|
||||
|
||||
if (!tcf_ipt_act_check(skb))
|
||||
return TC_ACT_UNSPEC;
|
||||
|
||||
if (state.hook == NF_INET_POST_ROUTING) {
|
||||
if (!skb_dst(skb))
|
||||
return TC_ACT_UNSPEC;
|
||||
|
||||
state.out = skb->dev;
|
||||
}
|
||||
|
||||
spin_lock(&ipt->tcf_lock);
|
||||
|
||||
tcf_lastuse_update(&ipt->tcf_tm);
|
||||
|
|
Loading…
Reference in a new issue