From d916fc38b6386c59f3e405e2f3b35e1d505fd806 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 10 Mar 2012 16:53:01 +0100 Subject: [PATCH 1/3] Stop using MAX_PATH, it might not be defined This broke compilation on Hurd --- changes/bug5355 | 4 ++++ src/common/compat.c | 27 ++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 changes/bug5355 diff --git a/changes/bug5355 b/changes/bug5355 new file mode 100644 index 0000000000..f850fe1f1d --- /dev/null +++ b/changes/bug5355 @@ -0,0 +1,4 @@ + o Major bugfixes: + - Fix a compilation issue on GNU Hurd, which doesn't have PATH_MAX. Fixes + bug 5355; bugfix on 0.2.3.11-alpha. + diff --git a/src/common/compat.c b/src/common/compat.c index 30bde3d1ca..ec365c38a4 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1645,7 +1645,10 @@ make_path_absolute(char *fname) return absfname; #else - char path[PATH_MAX+1]; +/* 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; tor_assert(fname); @@ -1653,13 +1656,23 @@ make_path_absolute(char *fname) if (fname[0] == '/') { absfname = tor_strdup(fname); } else { - if (getcwd(path, PATH_MAX) != NULL) { - tor_asprintf(&absfname, "%s/%s", path, fname); - } else { - /* If getcwd failed, the best we can do here is keep using the - * relative path. (Perhaps / isn't readable by this UID/GID.) */ - absfname = tor_strdup(fname); + 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; + } } + errno = save_errno; + tor_asprintf(&absfname, "%s/%s", path, fname); + tor_free(path); } return absfname; From 57ed459b0d675d255ae452749bee9efa3c498a5b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 10 May 2012 14:20:15 -0400 Subject: [PATCH 2/3] 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 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/common/compat.c b/src/common/compat.c index ec365c38a4..6c833f163c 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 fname to an absolute path. * Return a newly allocated string, possibly equal to fname. */ 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 } From f998590e5b02ca7e0d2224c600a877c93a3ab2e9 Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 29 May 2012 15:38:03 +0200 Subject: [PATCH 3/3] Don't stomp on errno. --- src/common/compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/compat.c b/src/common/compat.c index 6c833f163c..c18b4177f9 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1654,7 +1654,8 @@ alloc_getcwd(void) path = tor_realloc(path, path_length); } else { tor_free(path); - return NULL; + path = NULL; + break; } } errno = saved_errno;