diff --git a/src/common/util.c b/src/common/util.c index 3f3fb8b6a6..11c592ca96 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -838,35 +838,42 @@ write_str_to_file(const char *fname, const char *str, int bin) int write_bytes_to_file(const char *fname, const char *str, size_t len, int bin) { - char tempname[1024]; + size_t tempname_len; + char *tempname; int fd; int result; - if ((strlcpy(tempname,fname,1024) >= 1024) || - (strlcat(tempname,".tmp",1024) >= 1024)) { - log(LOG_WARN, "Filename %s.tmp too long (>1024 chars)", fname); - return -1; + tempname_len = strlen(fname)+16; + tor_assert(tempname_len > strlen(fname)); /*check for overflow*/ + tempname = tor_malloc(tempname_len); + if (tor_snprintf(tempname, tempname_len, "%s.tmp", fname)<0) { + log(LOG_WARN, "Failed to generate filename"); + goto err; } if ((fd = open(tempname, O_WRONLY|O_CREAT|O_TRUNC|(bin?O_BINARY:O_TEXT), 0600)) < 0) { log(LOG_WARN, "Couldn't open %s for writing: %s", tempname, strerror(errno)); - return -1; + goto err; } result = write_all(fd, str, len, 0); if (result < 0 || (size_t)result != len) { log(LOG_WARN, "Error writing to %s: %s", tempname, strerror(errno)); close(fd); - return -1; + goto err; } if (close(fd)) { log(LOG_WARN,"Error flushing to %s: %s", tempname, strerror(errno)); - return -1; + goto err; } if (replace_file(tempname, fname)) { log(LOG_WARN, "Error replacing %s: %s", fname, strerror(errno)); - return -1; + goto err; } + tor_free(tempname); return 0; + err: + tor_free(tempname); + return -1; } /** Read the contents of filename into a newly allocated string; return the diff --git a/src/or/config.c b/src/or/config.c index 47b292e465..aeaa538177 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -2307,7 +2307,6 @@ validate_data_directory(or_options_t *options) { static int write_configuration_file(const char *fname, or_options_t *options) { - char fn_tmp[1024]; char *old_val=NULL, *new_val=NULL, *new_conf=NULL; int rename_old = 0, r; size_t len; @@ -2340,9 +2339,14 @@ write_configuration_file(const char *fname, or_options_t *options) if (rename_old) { int i = 1; + size_t fn_tmp_len = strlen(fname)+32; + char *fn_tmp; + tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/ + fn_tmp = tor_malloc(fn_tmp_len); while (1) { - if (tor_snprintf(fn_tmp, sizeof(fn_tmp), "%s.orig.%d", fname, i)<0) { - log_fn(LOG_WARN, "Filename too long"); + if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) { + log_fn(LOG_WARN, "tor_snprintf failed inexplicably"); + tor_free(fn_tmp); goto err; } if (file_status(fn_tmp) == FN_NOENT) @@ -2351,6 +2355,7 @@ write_configuration_file(const char *fname, or_options_t *options) } log_fn(LOG_NOTICE, "Renaming old configuration file to %s", fn_tmp); rename(fname, fn_tmp); + tor_free(fn_tmp); } write_str_to_file(fname, new_val, 0);