[tor-commits] [tor/master] Refactor new getcwd code

nickm at torproject.org nickm at torproject.org
Thu May 31 16:38:21 UTC 2012


commit 57ed459b0d675d255ae452749bee9efa3c498a5b
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu May 10 14:20:15 2012 -0400

    Refactor new getcwd code
    
    Make sure that the "path_length *= 2" statement can't overflow.
    
    Move the "malloc and getcwd" loop into its own function.
---
 src/common/compat.c |   65 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/src/common/compat.c b/src/common/compat.c
index ec365c3..6c833f1 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1630,6 +1630,38 @@ get_parent_directory(char *fname)
   return -1;
 }
 
+#ifndef _WIN32
+/** Return a newly allocated string containing the output of getcwd(). Return
+ * NULL on failure. (We can't just use getcwd() into a PATH_MAX buffer, since
+ * Hurd hasn't got a PATH_MAX.)
+ */
+static char *
+alloc_getcwd(void)
+{
+    int saved_errno = errno;
+/* We use this as a starting path length. Not too large seems sane. */
+#define START_PATH_LENGTH 128
+/* Nobody has a maxpath longer than this, as far as I know.  And if they
+ * do, they shouldn't. */
+#define MAX_SANE_PATH_LENGTH 4096
+    size_t path_length = START_PATH_LENGTH;
+    char *path = tor_malloc(path_length);
+
+    errno = 0;
+    while (getcwd(path, path_length) == NULL) {
+      if (errno == ERANGE && path_length < MAX_SANE_PATH_LENGTH) {
+        path_length*=2;
+        path = tor_realloc(path, path_length);
+      } else {
+        tor_free(path);
+        return NULL;
+      }
+    }
+    errno = saved_errno;
+    return path;
+}
+#endif
+
 /** Expand possibly relative path <b>fname</b> to an absolute path.
  * Return a newly allocated string, possibly equal to <b>fname</b>. */
 char *
@@ -1645,36 +1677,25 @@ make_path_absolute(char *fname)
 
   return absfname;
 #else
-/* We use this as a starting path length. Not too large seems sane. */
-#define START_PATH_LENGTH 100
-  size_t path_length = START_PATH_LENGTH;
-  char *path = tor_malloc(path_length);
-  char *absfname = NULL;
+  char *absfname = NULL, *path = NULL;
 
   tor_assert(fname);
 
   if (fname[0] == '/') {
     absfname = tor_strdup(fname);
   } else {
-    int save_errno = errno;
-    errno = 0;
-    while (getcwd(path, path_length) == NULL) {
-      if (errno == ERANGE) {
-        path_length*=2;
-        path = tor_realloc(path, path_length);
-      } else {
-        /* If getcwd failed with an error other than ERANGE, the best we can
-         * do here is keep using the relative path.  (Perhaps / isn't readable
-         * by this UID/GID.) */
-        absfname = tor_strdup(fname);
-        break;
-      }
+    path = alloc_getcwd();
+    if (path) {
+      tor_asprintf(&absfname, "%s/%s", path, fname);
+      tor_free(path);
+    } else {
+      /* If getcwd failed, the best we can do here is keep using the
+       * relative path.  (Perhaps / isn't readable by this UID/GID.) */
+      log_warn(LD_GENERAL, "Unable to find current working directory: %s",
+               strerror(errno));
+      absfname = tor_strdup(fname);
     }
-    errno = save_errno;
-    tor_asprintf(&absfname, "%s/%s", path, fname);
-    tor_free(path);
   }
-
   return absfname;
 #endif
 }





More information about the tor-commits mailing list