[SRU][Trusty][Zesty][PATCH v2 0/2] Fix for CVE-2017-7542

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[SRU][Trusty][Zesty][PATCH v2 0/2] Fix for CVE-2017-7542

Kleber Souza
Clean cherry-picks for Trusty and Zesty, the other supported series are
either not affected or have already been fixed.

v2:
  - Added the follow-up fix 3de33e1ba0506723ab25734e098cf280ecc34756 ("ipv6:
    accept 64k - 1 packet length in ip6_find_1stfragopt()") as pointed out by
    Thadeu.

Sabrina Dubroca (1):
  ipv6: avoid overflow of offset in ip6_find_1stfragopt

Stefano Brivio (1):
  ipv6: accept 64k - 1 packet length in ip6_find_1stfragopt()

 net/ipv6/output_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][Trusty][Zesty][PATCH v2 1/2] ipv6: avoid overflow of offset in ip6_find_1stfragopt

Kleber Souza
From: Sabrina Dubroca <[hidden email]>

In some cases, offset can overflow and can cause an infinite loop in
ip6_find_1stfragopt(). Make it unsigned int to prevent the overflow, and
cap it at IPV6_MAXPLEN, since packets larger than that should be invalid.

This problem has been here since before the beginning of git history.

Signed-off-by: Sabrina Dubroca <[hidden email]>
Acked-by: Hannes Frederic Sowa <[hidden email]>
Signed-off-by: David S. Miller <[hidden email]>

CVE-2017-7542
(cherry picked from commit 6399f1fae4ec29fab5ec76070435555e256ca3a6)
Signed-off-by: Kleber Sacilotto de Souza <[hidden email]>
---
 net/ipv6/output_core.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index 3764254f4523..cb80a45cd2d6 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
- u16 offset = sizeof(struct ipv6hdr);
+ unsigned int offset = sizeof(struct ipv6hdr);
  unsigned int packet_len = skb_tail_pointer(skb) -
  skb_network_header(skb);
  int found_rhdr = 0;
@@ -51,6 +51,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
  while (offset <= packet_len) {
  struct ipv6_opt_hdr *exthdr;
+ unsigned int len;
 
  switch (**nexthdr) {
 
@@ -76,7 +77,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
  exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
  offset);
- offset += ipv6_optlen(exthdr);
+ len = ipv6_optlen(exthdr);
+ if (len + offset >= IPV6_MAXPLEN)
+ return -EINVAL;
+ offset += len;
  *nexthdr = &exthdr->nexthdr;
  }
 
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[SRU][Trusty][Zesty][PATCH v2 2/2] ipv6: accept 64k - 1 packet length in ip6_find_1stfragopt()

Kleber Souza
In reply to this post by Kleber Souza
From: Stefano Brivio <[hidden email]>

A packet length of exactly IPV6_MAXPLEN is allowed, we should
refuse parsing options only if the size is 64KiB or more.

While at it, remove one extra variable and one assignment which
were also introduced by the commit that introduced the size
check. Checking the sum 'offset + len' and only later adding
'len' to 'offset' doesn't provide any advantage over directly
summing to 'offset' and checking it.

Fixes: 6399f1fae4ec ("ipv6: avoid overflow of offset in ip6_find_1stfragopt")
Signed-off-by: Stefano Brivio <[hidden email]>
Signed-off-by: David S. Miller <[hidden email]>

CVE-2017-7542
(cherry picked from commit 3de33e1ba0506723ab25734e098cf280ecc34756)
Signed-off-by: Kleber Sacilotto de Souza <[hidden email]>
---
 net/ipv6/output_core.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index cb80a45cd2d6..1b03fe190d97 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -51,7 +51,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
  while (offset <= packet_len) {
  struct ipv6_opt_hdr *exthdr;
- unsigned int len;
 
  switch (**nexthdr) {
 
@@ -77,10 +76,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 
  exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
  offset);
- len = ipv6_optlen(exthdr);
- if (len + offset >= IPV6_MAXPLEN)
+ offset += ipv6_optlen(exthdr);
+ if (offset > IPV6_MAXPLEN)
  return -EINVAL;
- offset += len;
  *nexthdr = &exthdr->nexthdr;
  }
 
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team