aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2019-05-29 09:33:24 -0400
committerNick Mathewson <nickm@torproject.org>2019-05-29 09:33:24 -0400
commit0d5a0b4f0ccc804913fbca20acf5fc62f52570b8 (patch)
tree41d8079c5f085e6170705271ea3be080e85f98b5
parent4e262196a88d2a7d3be059d075f53a6f182b2773 (diff)
downloadtor-0d5a0b4f0ccc804913fbca20acf5fc62f52570b8.tar.gz
tor-0d5a0b4f0ccc804913fbca20acf5fc62f52570b8.zip
Fixed tor_vasprintf on systems without vasprintf.
If tor is compiled on a system with neither vasprintf nor _vscprintf, the fallback implementation exposes a logic flaw which prevents proper usage of strings longer than 127 characters: * tor_vsnprintf returns -1 if supplied buffer is not large enough, but tor_vasprintf uses this function to retrieve required length * the result of tor_vsnprintf is not properly checked for negative return values Both aspects together could in theory lead to exposure of uninitialized stack memory in the resulting string. This requires an invalid format string or data that exceeds integer limitations. Fortunately tor is not even able to run with this implementation because it runs into asserts early on during startup. Also the unit tests fail during a "make check" run. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> [backported to 0.2.9 by nickm]
-rw-r--r--src/common/compat.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index 9758751122..d3bc2f5fec 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -558,10 +558,17 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
int len, r;
va_list tmp_args;
va_copy(tmp_args, args);
- /* vsnprintf() was properly checked but tor_vsnprintf() available so
- * why not use it? */
- len = tor_vsnprintf(buf, sizeof(buf), fmt, tmp_args);
+ /* Use vsnprintf to retrieve needed length. tor_vsnprintf() is not an option
+ * here because it will simply return -1 if buf is not large enough to hold the
+ * complete string.
+ */
+ len = vsnprintf(buf, sizeof(buf), fmt, tmp_args);
va_end(tmp_args);
+ buf[sizeof(buf) - 1] = '\0';
+ if (len < 0) {
+ *strp = NULL;
+ return -1;
+ }
if (len < (int)sizeof(buf)) {
*strp = tor_strdup(buf);
return len;