From 17458a87d73f605fe6a4bb3c23cf2de135eec99c Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Mon, 24 Jun 2019 22:08:49 +0200 Subject: [PATCH 1/2] Prevent UB on signed overflow. Overflowing a signed integer in C is an undefined behaviour. It is possible to trigger this undefined behaviour in tor_asprintf on Windows or systems lacking vasprintf. On these systems, eiter _vscprintf or vsnprintf is called to retrieve the required amount of bytes to hold the string. These functions can return INT_MAX. The easiest way to recreate this is the use of a specially crafted configuration file, e.g. containing the line: FirewallPorts AAAAA This line triggers the needed tor_asprintf call which eventually leads to an INT_MAX return value from _vscprintf or vsnprintf. The needed byte for \0 is added to the result, triggering the overflow and therefore the undefined behaviour. Casting the value to size_t before addition fixes the behaviour. Signed-off-by: Tobias Stoeckmann --- src/lib/string/printf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/string/printf.c b/src/lib/string/printf.c index 415d4ac4a7..00659337eb 100644 --- a/src/lib/string/printf.c +++ b/src/lib/string/printf.c @@ -117,8 +117,8 @@ tor_vasprintf(char **strp, const char *fmt, va_list args) *strp = NULL; return -1; } - strp_tmp = tor_malloc(len + 1); - r = _vsnprintf(strp_tmp, len+1, fmt, args); + strp_tmp = tor_malloc((size_t)len + 1); + r = _vsnprintf(strp_tmp, (size_t)len+1, fmt, args); if (r != len) { tor_free(strp_tmp); *strp = NULL; @@ -143,9 +143,9 @@ tor_vasprintf(char **strp, const char *fmt, va_list args) *strp = tor_strdup(buf); return len; } - strp_tmp = tor_malloc(len+1); + strp_tmp = tor_malloc((size_t)len+1); /* use of tor_vsnprintf() will ensure string is null terminated */ - r = tor_vsnprintf(strp_tmp, len+1, fmt, args); + r = tor_vsnprintf(strp_tmp, (size_t)len+1, fmt, args); if (r != len) { tor_free(strp_tmp); *strp = NULL; From 8bbec36b3b2dadbd23c7b3ffe2bccb7291aee1f0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 19 Jul 2019 09:21:08 -0400 Subject: [PATCH 2/2] Changes file for bug 31001 --- changes/ticket31001 | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changes/ticket31001 diff --git a/changes/ticket31001 b/changes/ticket31001 new file mode 100644 index 0000000000..2ce1cbdf34 --- /dev/null +++ b/changes/ticket31001 @@ -0,0 +1,6 @@ + o Minor bugfixes (compatibility, standards compliance): + - Fix a bug that would invoke undefined behavior on certain operating + systems when trying to asprintf() a string exactly INT_MAX bytes + long. We don't believe this is exploitable, but it's better + to fix it anyway. Fixes bug 31001; bugfix on 0.2.2.11-alpha. + Found and fixed by Tobias Stoeckmann.