From c0e93ddff35e6b4d719eeef9331bb7744a37e869 Mon Sep 17 00:00:00 2001 From: Hirokazu MORIKAWA Date: Mon, 12 Jul 2021 15:13:13 +0900 Subject: [PATCH] libuv: fix CVE-2021-22918 idna: fix OOB read in punycode decoder libuv was vulnerable to out-of-bounds reads in the uv__idna_toascii() function which is used to convert strings to ASCII. This is called by the DNS resolution function and can lead to information disclosures or crashes. libuv/libuv@b7466e3 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=990561 https://nodejs.org/en/blog/vulnerability/july-2021-security-releases/ Signed-off-by: Hirokazu MORIKAWA --- libs/libuv/Makefile | 2 +- libs/libuv/patches/CVE-2021-22918.patch | 166 ++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 libs/libuv/patches/CVE-2021-22918.patch diff --git a/libs/libuv/Makefile b/libs/libuv/Makefile index dc50644a33..02850aac8b 100644 --- a/libs/libuv/Makefile +++ b/libs/libuv/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libuv PKG_VERSION:=1.40.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://dist.libuv.org/dist/v$(PKG_VERSION)/ diff --git a/libs/libuv/patches/CVE-2021-22918.patch b/libs/libuv/patches/CVE-2021-22918.patch new file mode 100644 index 0000000000..075800c2f6 --- /dev/null +++ b/libs/libuv/patches/CVE-2021-22918.patch @@ -0,0 +1,166 @@ +From b7466e31e4bee160d82a68fca11b1f61d46debae Mon Sep 17 00:00:00 2001 +From: Ben Noordhuis +Date: Fri, 21 May 2021 11:23:36 +0200 +Subject: [PATCH] idna: fix OOB read in punycode decoder + +libuv was vulnerable to out-of-bounds reads in the uv__idna_toascii() +function which is used to convert strings to ASCII. This is called by +the DNS resolution function and can lead to information disclosures or +crashes. + +Reported by Eric Sesterhenn in collaboration with Cure53 and ExpressVPN. + +Reported-By: Eric Sesterhenn +Fixes: https://github.com/libuv/libuv/issues/3147 +PR-URL: https://github.com/libuv/libuv-private/pull/1 +Refs: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22918 +Reviewed-By: Colin Ihrig +Reviewed-By: Richard Lau +--- + src/idna.c | 49 +++++++++++++++++++++++++++++++++++------------- + test/test-idna.c | 19 +++++++++++++++++++ + test/test-list.h | 2 ++ + 3 files changed, 57 insertions(+), 13 deletions(-) + +--- a/src/idna.c ++++ b/src/idna.c +@@ -19,6 +19,7 @@ + + #include "uv.h" + #include "idna.h" ++#include + #include + + static unsigned uv__utf8_decode1_slow(const char** p, +@@ -32,7 +33,7 @@ static unsigned uv__utf8_decode1_slow(co + if (a > 0xF7) + return -1; + +- switch (*p - pe) { ++ switch (pe - *p) { + default: + if (a > 0xEF) { + min = 0x10000; +@@ -62,6 +63,8 @@ static unsigned uv__utf8_decode1_slow(co + a = 0; + break; + } ++ /* Fall through. */ ++ case 0: + return -1; /* Invalid continuation byte. */ + } + +@@ -88,6 +91,8 @@ static unsigned uv__utf8_decode1_slow(co + unsigned uv__utf8_decode1(const char** p, const char* pe) { + unsigned a; + ++ assert(*p < pe); ++ + a = (unsigned char) *(*p)++; + + if (a < 128) +@@ -96,9 +101,6 @@ unsigned uv__utf8_decode1(const char** p + return uv__utf8_decode1_slow(p, pe, a); + } + +-#define foreach_codepoint(c, p, pe) \ +- for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;) +- + static int uv__idna_toascii_label(const char* s, const char* se, + char** d, char* de) { + static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789"; +@@ -121,15 +123,22 @@ static int uv__idna_toascii_label(const + ss = s; + todo = 0; + +- foreach_codepoint(c, &s, se) { ++ /* Note: after this loop we've visited all UTF-8 characters and know ++ * they're legal so we no longer need to check for decode errors. ++ */ ++ while (s < se) { ++ c = uv__utf8_decode1(&s, se); ++ ++ if (c == -1u) ++ return UV_EINVAL; ++ + if (c < 128) + h++; +- else if (c == (unsigned) -1) +- return UV_EINVAL; + else + todo++; + } + ++ /* Only write "xn--" when there are non-ASCII characters. */ + if (todo > 0) { + if (*d < de) *(*d)++ = 'x'; + if (*d < de) *(*d)++ = 'n'; +@@ -137,9 +146,13 @@ static int uv__idna_toascii_label(const + if (*d < de) *(*d)++ = '-'; + } + ++ /* Write ASCII characters. */ + x = 0; + s = ss; +- foreach_codepoint(c, &s, se) { ++ while (s < se) { ++ c = uv__utf8_decode1(&s, se); ++ assert(c != -1u); ++ + if (c > 127) + continue; + +@@ -166,10 +179,15 @@ static int uv__idna_toascii_label(const + while (todo > 0) { + m = -1; + s = ss; +- foreach_codepoint(c, &s, se) ++ ++ while (s < se) { ++ c = uv__utf8_decode1(&s, se); ++ assert(c != -1u); ++ + if (c >= n) + if (c < m) + m = c; ++ } + + x = m - n; + y = h + 1; +@@ -181,7 +199,10 @@ static int uv__idna_toascii_label(const + n = m; + + s = ss; +- foreach_codepoint(c, &s, se) { ++ while (s < se) { ++ c = uv__utf8_decode1(&s, se); ++ assert(c != -1u); ++ + if (c < n) + if (++delta == 0) + return UV_E2BIG; /* Overflow. */ +@@ -245,8 +266,6 @@ static int uv__idna_toascii_label(const + return 0; + } + +-#undef foreach_codepoint +- + long uv__idna_toascii(const char* s, const char* se, char* d, char* de) { + const char* si; + const char* st; +@@ -256,10 +275,14 @@ long uv__idna_toascii(const char* s, con + + ds = d; + +- for (si = s; si < se; /* empty */) { ++ si = s; ++ while (si < se) { + st = si; + c = uv__utf8_decode1(&si, se); + ++ if (c == -1u) ++ return UV_EINVAL; ++ + if (c != '.') + if (c != 0x3002) /* 。 */ + if (c != 0xFF0E) /* . */ -- 2.30.2