Files
nodejs10/CVE-2021-22918.patch

171 lines
4.5 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

commit 623fd1fcb557985bf452984856c1d0ce4fc096a7
Author: Ben Noordhuis <info@bnoordhuis.nl>
Date: Fri May 21 11:23:36 2021 +0200
deps: uv: cherry-pick 99c29c9c2c9b
Original commit message:
idna: fix OOB read in punycode decoder
Reported by Eric Sesterhenn in collaboration with
Cure53 and ExpressVPN.
Reported-By: Eric Sesterhenn <eric.sesterhenn@x41-dsec.de>
PR-URL: https://github.com/libuv/libuv-private/pull/1
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
CVE-ID: CVE-2021-22918
Refs: https://hackerone.com/reports/1209681
PR-URL: https://github.com/nodejs-private/node-private/pull/267
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Beth Griggs <bgriggs@redhat.com>
diff --git a/deps/uv/src/idna.c b/deps/uv/src/idna.c
index 13ffac6be8..b44cb16a1e 100644
--- a/deps/uv/src/idna.c
+++ b/deps/uv/src/idna.c
@@ -19,6 +19,7 @@
#include "uv.h"
#include "idna.h"
+#include <assert.h>
#include <string.h>
static unsigned uv__utf8_decode1_slow(const char** p,
@@ -32,7 +33,7 @@ static unsigned uv__utf8_decode1_slow(const char** p,
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(const char** p,
a = 0;
break;
}
+ /* Fall through. */
+ case 0:
return -1; /* Invalid continuation byte. */
}
@@ -88,6 +91,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
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, const char* pe) {
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 char* s, const char* se,
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 char* s, const char* se,
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 char* s, const char* se,
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 char* s, const char* se,
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 char* s, const char* se,
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, const char* se, char* d, char* de) {
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) /* */