diff options
author | Eric Dumazet <edumazet@google.com> | 2016-11-09 19:04:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-12 23:41:53 -0500 |
commit | 34fad54c2537f7c99d07375e50cb30aa3c23bd83 (patch) | |
tree | a63fc00dc48c8673830e2930aed819ccfb2f9632 | |
parent | 79774d6bfacb40699ecd5a343e5d4ac5a9cdd173 (diff) |
net: __skb_flow_dissect() must cap its return value
After Tom patch, thoff field could point past the end of the buffer,
this could fool some callers.
If an skb was provided, skb->len should be the upper limit.
If not, hlen is supposed to be the upper limit.
Fixes: a6e544b0a88b ("flow_dissector: Jump to exit code in __skb_flow_dissect")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Yibin Yang <yibyang@cisco.com
Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Willem de Bruijn <willemb@google.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/flow_dissector.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index ab193e5def07..69e4463a4b1b 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -122,7 +122,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, | |||
122 | struct flow_dissector_key_keyid *key_keyid; | 122 | struct flow_dissector_key_keyid *key_keyid; |
123 | bool skip_vlan = false; | 123 | bool skip_vlan = false; |
124 | u8 ip_proto = 0; | 124 | u8 ip_proto = 0; |
125 | bool ret = false; | 125 | bool ret; |
126 | 126 | ||
127 | if (!data) { | 127 | if (!data) { |
128 | data = skb->data; | 128 | data = skb->data; |
@@ -549,12 +549,17 @@ ip_proto_again: | |||
549 | out_good: | 549 | out_good: |
550 | ret = true; | 550 | ret = true; |
551 | 551 | ||
552 | out_bad: | 552 | key_control->thoff = (u16)nhoff; |
553 | out: | ||
553 | key_basic->n_proto = proto; | 554 | key_basic->n_proto = proto; |
554 | key_basic->ip_proto = ip_proto; | 555 | key_basic->ip_proto = ip_proto; |
555 | key_control->thoff = (u16)nhoff; | ||
556 | 556 | ||
557 | return ret; | 557 | return ret; |
558 | |||
559 | out_bad: | ||
560 | ret = false; | ||
561 | key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen); | ||
562 | goto out; | ||
558 | } | 563 | } |
559 | EXPORT_SYMBOL(__skb_flow_dissect); | 564 | EXPORT_SYMBOL(__skb_flow_dissect); |
560 | 565 | ||