mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
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.
This commit is contained in:
parent
d916fc38b6
commit
57ed459b0d
@ -1630,6 +1630,38 @@ get_parent_directory(char *fname)
|
|||||||
return -1;
|
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.
|
/** Expand possibly relative path <b>fname</b> to an absolute path.
|
||||||
* Return a newly allocated string, possibly equal to <b>fname</b>. */
|
* Return a newly allocated string, possibly equal to <b>fname</b>. */
|
||||||
char *
|
char *
|
||||||
@ -1645,36 +1677,25 @@ make_path_absolute(char *fname)
|
|||||||
|
|
||||||
return absfname;
|
return absfname;
|
||||||
#else
|
#else
|
||||||
/* We use this as a starting path length. Not too large seems sane. */
|
char *absfname = NULL, *path = NULL;
|
||||||
#define START_PATH_LENGTH 100
|
|
||||||
size_t path_length = START_PATH_LENGTH;
|
|
||||||
char *path = tor_malloc(path_length);
|
|
||||||
char *absfname = NULL;
|
|
||||||
|
|
||||||
tor_assert(fname);
|
tor_assert(fname);
|
||||||
|
|
||||||
if (fname[0] == '/') {
|
if (fname[0] == '/') {
|
||||||
absfname = tor_strdup(fname);
|
absfname = tor_strdup(fname);
|
||||||
} else {
|
} else {
|
||||||
int save_errno = errno;
|
path = alloc_getcwd();
|
||||||
errno = 0;
|
if (path) {
|
||||||
while (getcwd(path, path_length) == NULL) {
|
tor_asprintf(&absfname, "%s/%s", path, fname);
|
||||||
if (errno == ERANGE) {
|
tor_free(path);
|
||||||
path_length*=2;
|
} else {
|
||||||
path = tor_realloc(path, path_length);
|
/* If getcwd failed, the best we can do here is keep using the
|
||||||
} else {
|
* relative path. (Perhaps / isn't readable by this UID/GID.) */
|
||||||
/* If getcwd failed with an error other than ERANGE, the best we can
|
log_warn(LD_GENERAL, "Unable to find current working directory: %s",
|
||||||
* do here is keep using the relative path. (Perhaps / isn't readable
|
strerror(errno));
|
||||||
* by this UID/GID.) */
|
absfname = tor_strdup(fname);
|
||||||
absfname = tor_strdup(fname);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
errno = save_errno;
|
|
||||||
tor_asprintf(&absfname, "%s/%s", path, fname);
|
|
||||||
tor_free(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return absfname;
|
return absfname;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user