diff options
-rw-r--r-- | LICENSE | 30 | ||||
-rw-r--r-- | changes/bug26223 | 3 | ||||
-rw-r--r-- | configure.ac | 202 | ||||
-rw-r--r-- | src/ext/getdelim.c | 78 | ||||
-rw-r--r-- | src/ext/include.am | 2 | ||||
-rw-r--r-- | src/feature/dircache/dirserv.c | 35 | ||||
-rw-r--r-- | src/lib/fs/.may_include | 3 | ||||
-rw-r--r-- | src/lib/fs/files.c | 4 | ||||
-rw-r--r-- | src/lib/fs/files.h | 39 |
9 files changed, 280 insertions, 116 deletions
@@ -156,6 +156,36 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== +getdelim.c is distributed under this license: + + Copyright (c) 2011 The NetBSD Foundation, Inc. + All rights reserved. + + This code is derived from software contributed to The NetBSD Foundation + by Christos Zoulas. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +=============================================================================== src/config/geoip is licensed under the following license: OPEN DATA LICENSE (GeoLite Country and GeoLite City databases) diff --git a/changes/bug26223 b/changes/bug26223 new file mode 100644 index 0000000000..e17b0529e3 --- /dev/null +++ b/changes/bug26223 @@ -0,0 +1,3 @@ + o Minor features (directory authority): + - There is no longer an artificial upper limit on the length of bandwidth + lines. Closes ticket 26223. diff --git a/configure.ac b/configure.ac index 296591f025..532476672a 100644 --- a/configure.ac +++ b/configure.ac @@ -572,58 +572,60 @@ AM_CONDITIONAL(THREADS_WIN32, test "$bwin32" = "true") AM_CONDITIONAL(THREADS_PTHREADS, test "$bwin32" = "false") AC_CHECK_FUNCS( - _NSGetEnviron \ + _NSGetEnviron \ RtlSecureZeroMemory \ SecureZeroMemory \ - accept4 \ - backtrace \ - backtrace_symbols_fd \ + accept4 \ + backtrace \ + backtrace_symbols_fd \ eventfd \ explicit_bzero \ timingsafe_memcmp \ - flock \ - ftime \ - get_current_dir_name \ - getaddrinfo \ - getifaddrs \ - getpass \ - getrlimit \ - gettimeofday \ - gmtime_r \ + flock \ + ftime \ + get_current_dir_name \ + getaddrinfo \ + getdelim \ + getifaddrs \ + getline \ + getpass \ + getrlimit \ + gettimeofday \ + gmtime_r \ gnu_get_libc_version \ htonll \ - inet_aton \ - ioctl \ - issetugid \ - llround \ - localtime_r \ - lround \ + inet_aton \ + ioctl \ + issetugid \ + llround \ + localtime_r \ + lround \ mach_approximate_time \ - memmem \ - memset_s \ - mmap \ + memmem \ + memset_s \ + mmap \ pipe \ pipe2 \ - prctl \ + prctl \ readpassphrase \ - rint \ - sigaction \ - socketpair \ + rint \ + sigaction \ + socketpair \ statvfs \ - strncasecmp \ - strcasecmp \ - strlcat \ - strlcpy \ + strncasecmp \ + strcasecmp \ + strlcat \ + strlcpy \ strnlen \ - strptime \ - strtok_r \ - strtoull \ - sysconf \ + strptime \ + strtok_r \ + strtoull \ + sysconf \ sysctl \ truncate \ - uname \ + uname \ usleep \ - vasprintf \ + vasprintf \ _vscprintf ) @@ -1365,57 +1367,57 @@ dnl Make sure to enable support for large off_t if available. AC_SYS_LARGEFILE AC_CHECK_HEADERS([errno.h \ - fcntl.h \ - signal.h \ - string.h \ - sys/capability.h \ - sys/fcntl.h \ - sys/stat.h \ - sys/time.h \ - sys/types.h \ - time.h \ - unistd.h \ - arpa/inet.h \ - crt_externs.h \ - execinfo.h \ - gnu/libc-version.h \ - grp.h \ - ifaddrs.h \ - inttypes.h \ - limits.h \ - linux/types.h \ - machine/limits.h \ - malloc.h \ - malloc/malloc.h \ - malloc_np.h \ - netdb.h \ - netinet/in.h \ - netinet/in6.h \ - pwd.h \ - readpassphrase.h \ - stdatomic.h \ - sys/eventfd.h \ - sys/file.h \ - sys/ioctl.h \ - sys/limits.h \ - sys/mman.h \ - sys/param.h \ - sys/prctl.h \ + fcntl.h \ + signal.h \ + string.h \ + sys/capability.h \ + sys/fcntl.h \ + sys/stat.h \ + sys/time.h \ + sys/types.h \ + time.h \ + unistd.h \ + arpa/inet.h \ + crt_externs.h \ + execinfo.h \ + gnu/libc-version.h \ + grp.h \ + ifaddrs.h \ + inttypes.h \ + limits.h \ + linux/types.h \ + machine/limits.h \ + malloc.h \ + malloc/malloc.h \ + malloc_np.h \ + netdb.h \ + netinet/in.h \ + netinet/in6.h \ + pwd.h \ + readpassphrase.h \ + stdatomic.h \ + sys/eventfd.h \ + sys/file.h \ + sys/ioctl.h \ + sys/limits.h \ + sys/mman.h \ + sys/param.h \ + sys/prctl.h \ sys/random.h \ - sys/resource.h \ - sys/select.h \ - sys/socket.h \ - sys/statvfs.h \ - sys/syscall.h \ - sys/sysctl.h \ - sys/syslimits.h \ - sys/time.h \ - sys/types.h \ - sys/un.h \ - sys/utime.h \ - sys/wait.h \ - syslog.h \ - utime.h]) + sys/resource.h \ + sys/select.h \ + sys/socket.h \ + sys/statvfs.h \ + sys/syscall.h \ + sys/sysctl.h \ + sys/syslimits.h \ + sys/time.h \ + sys/types.h \ + sys/un.h \ + sys/utime.h \ + sys/wait.h \ + syslog.h \ + utime.h]) AC_CHECK_HEADERS(sys/param.h) @@ -2269,20 +2271,20 @@ fi CPPFLAGS="$CPPFLAGS $TOR_CPPFLAGS_libevent $TOR_CPPFLAGS_openssl $TOR_CPPFLAGS_zlib" AC_CONFIG_FILES([ - Doxyfile - Makefile - config.rust - link_rust.sh - contrib/dist/suse/tor.sh - contrib/operator-tools/tor.logrotate - contrib/dist/tor.sh - contrib/dist/torctl - contrib/dist/tor.service - src/config/torrc.sample - src/config/torrc.minimal - src/rust/.cargo/config - scripts/maint/checkOptionDocs.pl - scripts/maint/updateVersions.pl + Doxyfile + Makefile + config.rust + link_rust.sh + contrib/dist/suse/tor.sh + contrib/operator-tools/tor.logrotate + contrib/dist/tor.sh + contrib/dist/torctl + contrib/dist/tor.service + src/config/torrc.sample + src/config/torrc.minimal + src/rust/.cargo/config + scripts/maint/checkOptionDocs.pl + scripts/maint/updateVersions.pl ]) if test "x$asciidoc" = "xtrue" && test "$ASCIIDOC" = "none"; then diff --git a/src/ext/getdelim.c b/src/ext/getdelim.c new file mode 100644 index 0000000000..8254103ff9 --- /dev/null +++ b/src/ext/getdelim.c @@ -0,0 +1,78 @@ +/* $NetBSD: getdelim.c,v 1.2 2015/12/25 20:12:46 joerg Exp $ */ +/* NetBSD-src: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BUFSIZ +#define BUFSIZ 512 +#endif + +ssize_t +compat_getdelim_(char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + + if (*buf == NULL || *bufsiz == 0) { + *bufsiz = BUFSIZ; + if ((*buf = raw_malloc(*bufsiz)) == NULL) + return -1; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc(fp); + if (c == -1) { + if (feof(fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = raw_realloc(*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} diff --git a/src/ext/include.am b/src/ext/include.am index 7ec2e43312..6bdce2d79e 100644 --- a/src/ext/include.am +++ b/src/ext/include.am @@ -10,6 +10,7 @@ EXTHEADERS = \ src/ext/tor_readpassphrase.h \ src/ext/strlcat.c \ src/ext/strlcpy.c \ + src/ext/getdelim.c \ src/ext/tinytest_macros.h \ src/ext/tor_queue.h \ src/ext/siphash.h \ @@ -173,4 +174,3 @@ EXTRA_DIST += \ src/ext/timeouts/Makefile \ src/ext/timeouts/Rules.shrc \ src/ext/timeouts/test-timeout.c - diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index c5286b0cbf..1500467ec0 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -2606,7 +2606,6 @@ int dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses) { - char line[512]; FILE *fp = tor_fopen_cloexec(from_file, "r"); int applied_lines = 0; time_t file_time, now; @@ -2616,28 +2615,28 @@ dirserv_read_measured_bandwidths(const char *from_file, * if there are additional header lines, as introduced in Bandwidth List spec * version 1.1.0 */ int line_is_after_headers = 0; + int rv = -1; + char *line = NULL; + size_t n = 0; /* Initialise line, so that we can't possibly run off the end. */ - memset(line, 0, sizeof(line)); if (fp == NULL) { log_warn(LD_CONFIG, "Can't open bandwidth file at configured location: %s", from_file); - return -1; + goto err; } /* If fgets fails, line is either unmodified, or indeterminate. */ - if (!fgets(line, sizeof(line), fp)) { + if (tor_getline(&line,&n,fp) <= 0) { log_warn(LD_DIRSERV, "Empty bandwidth file"); - fclose(fp); - return -1; + goto err; } if (!strlen(line) || line[strlen(line)-1] != '\n') { log_warn(LD_DIRSERV, "Long or truncated time in bandwidth file: %s", escaped(line)); - fclose(fp); - return -1; + goto err; } line[strlen(line)-1] = '\0'; @@ -2645,16 +2644,14 @@ dirserv_read_measured_bandwidths(const char *from_file, if (!ok) { log_warn(LD_DIRSERV, "Non-integer time in bandwidth file: %s", escaped(line)); - fclose(fp); - return -1; + goto err; } now = time(NULL); if ((now - file_time) > MAX_MEASUREMENT_AGE) { log_warn(LD_DIRSERV, "Bandwidth measurement file stale. Age: %u", (unsigned)(time(NULL) - file_time)); - fclose(fp); - return -1; + goto err; } if (routerstatuses) @@ -2662,7 +2659,7 @@ dirserv_read_measured_bandwidths(const char *from_file, while (!feof(fp)) { measured_bw_line_t parsed_line; - if (fgets(line, sizeof(line), fp) && strlen(line)) { + if (tor_getline(&line, &n, fp) >= 0) { if (measured_bw_line_parse(&parsed_line, line, line_is_after_headers) != -1) { /* This condition will be true when the first complete valid bw line @@ -2679,11 +2676,19 @@ dirserv_read_measured_bandwidths(const char *from_file, /* Now would be a nice time to clean the cache, too */ dirserv_expire_measured_bw_cache(now); - fclose(fp); log_info(LD_DIRSERV, "Bandwidth measurement file successfully read. " "Applied %d measurements.", applied_lines); - return 0; + rv = 0; + + err: + if (line) { + // we need to raw_free this buffer because we got it from tor_getdelim() + raw_free(line); + } + if (fp) + fclose(fp); + return rv; } /** As dirserv_get_routerdescs(), but instead of getting signed_descriptor_t diff --git a/src/lib/fs/.may_include b/src/lib/fs/.may_include index 6c9ce6ca04..b1e49fc891 100644 --- a/src/lib/fs/.may_include +++ b/src/lib/fs/.may_include @@ -1,4 +1,7 @@ orconfig.h + +ext/getdelim.c + lib/cc/*.h lib/container/*.h lib/encoding/*.h diff --git a/src/lib/fs/files.c b/src/lib/fs/files.c index c71e4d2a37..43dcbad333 100644 --- a/src/lib/fs/files.c +++ b/src/lib/fs/files.c @@ -715,3 +715,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out)) return string; } + +#if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS) +#include "ext/getdelim.c" +#endif diff --git a/src/lib/fs/files.h b/src/lib/fs/files.h index 5a12eb8215..2ee1b20149 100644 --- a/src/lib/fs/files.h +++ b/src/lib/fs/files.h @@ -103,4 +103,43 @@ char *read_file_to_str_until_eof(int fd, size_t max_bytes_to_read, size_t *sz_out) ATTR_MALLOC; +#if !defined(HAVE_GETDELIM) || defined(TOR_UNIT_TESTS) +/** Internal back-end function to implement getdelim(): only exists when + * Tor is built for unit tests, or when Tor is built on an operating system + * without its own getdelim(). */ +ssize_t compat_getdelim_(char **lineptr, size_t *n, int delim, FILE *stream); +#endif + +#ifdef HAVE_GETDELIM +/** + * Cross-platform wrapper for getdelim(): behaves as the POSIX-standard + * getdelim() function. + * + * See `getdelim(3)` for more information. + * + * Note that this function will use the libc memory allocator -- so any memory + * passed to this function must come from raw_malloc(), and must be freed by + * raw_free() -- don't use tor_malloc() and tor_free() with this. + */ +#define tor_getdelim(lineptr, n, delim, stream) \ + getdelim((lineptr), (n), (delim), (stream)) +#else +#define tor_getdelim(lineptr, n, delim, stream) \ + compat_getdelim_((lineptr), (n), (delim), (stream)) +#endif + +#ifdef HAVE_GETLINE +/** + * Cross-platform wrapper for getline(): behaves as the POSIX-standard + * getline() function. + * + * See tor_getdelim() for usage notes. + */ +#define tor_getline(lineptr, n, stream) \ + getline((lineptr), (n), (stream)) +#else +#define tor_getline(lineptr, n, stream) \ + tor_getdelim((lineptr), (n), '\n', (stream)) +#endif + #endif |