diff options
author | Xin Long <lucien.xin@gmail.com> | 2019-10-28 11:19:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-10-29 20:36:42 -0400 |
commit | 2eb8d6d2910cfe3dc67dc056f26f3dd9c63d47cd (patch) | |
tree | 5490ad73490d3235a4da373fe744a0a9f8087951 | |
parent | e56bd641ca61beb92b135298d5046905f920b734 (diff) |
erspan: fix the tun_info options_len check for erspan
The check for !md doens't really work for ip_tunnel_info_opts(info) which
only does info + 1. Also to avoid out-of-bounds access on info, it should
ensure options_len is not less than erspan_metadata in both erspan_xmit()
and ip6erspan_tunnel_xmit().
Fixes: 1a66a836da ("gre: add collect_md mode to ERSPAN tunnel")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/ip_gre.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_gre.c | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 52690bb3e40f..10636fb6093e 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -509,9 +509,9 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) | |||
509 | key = &tun_info->key; | 509 | key = &tun_info->key; |
510 | if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) | 510 | if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) |
511 | goto err_free_skb; | 511 | goto err_free_skb; |
512 | md = ip_tunnel_info_opts(tun_info); | 512 | if (tun_info->options_len < sizeof(*md)) |
513 | if (!md) | ||
514 | goto err_free_skb; | 513 | goto err_free_skb; |
514 | md = ip_tunnel_info_opts(tun_info); | ||
515 | 515 | ||
516 | /* ERSPAN has fixed 8 byte GRE header */ | 516 | /* ERSPAN has fixed 8 byte GRE header */ |
517 | version = md->version; | 517 | version = md->version; |
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 787d9f2a6e99..923034c52ce4 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -980,9 +980,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, | |||
980 | dsfield = key->tos; | 980 | dsfield = key->tos; |
981 | if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) | 981 | if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) |
982 | goto tx_err; | 982 | goto tx_err; |
983 | md = ip_tunnel_info_opts(tun_info); | 983 | if (tun_info->options_len < sizeof(*md)) |
984 | if (!md) | ||
985 | goto tx_err; | 984 | goto tx_err; |
985 | md = ip_tunnel_info_opts(tun_info); | ||
986 | 986 | ||
987 | tun_id = tunnel_id_to_key32(key->tun_id); | 987 | tun_id = tunnel_id_to_key32(key->tun_id); |
988 | if (md->version == 1) { | 988 | if (md->version == 1) { |