Browse Source

Merge branch 'ticket30561_029' into ticket30561_035

Nick Mathewson 5 years ago
parent
commit
8f0b29961e
2 changed files with 19 additions and 3 deletions
  1. 6 0
      changes/bug30561
  2. 13 3
      src/lib/string/printf.c

+ 6 - 0
changes/bug30561

@@ -0,0 +1,6 @@
+  o Minor bugfixes (portability):
+    - Avoid crashing in our tor_vasprintf() implementation on systems that
+      define neither vasprintf() nor _vscprintf(). (This bug has been here
+      long enough that we question whether people are running Tor on such
+      systems, but we're applying the fix out of caution.) Fixes bug 30561;
+      bugfix on 0.2.8.2-alpha. Found and fixed by Tobias Stoeckmann.

+ 13 - 3
src/lib/string/printf.c

@@ -131,14 +131,24 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
    * characters we need.  We give it a try on a short buffer first, since
    * it might be nice to avoid the second vsnprintf call.
    */
+  /* XXXX This code spent a number of years broken (see bug 30651). It is
+   * possible that no Tor users actually run on systems without vasprintf() or
+   * _vscprintf(). If so, we should consider removing this code. */
   char buf[128];
   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;