diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 47 | ||||
-rw-r--r-- | src/common/compat.h | 38 | ||||
-rw-r--r-- | src/common/container.c | 13 | ||||
-rw-r--r-- | src/common/container.h | 4 | ||||
-rw-r--r-- | src/common/crypto.c | 19 | ||||
-rw-r--r-- | src/common/di_ops.c | 2 | ||||
-rw-r--r-- | src/common/log.c | 20 | ||||
-rw-r--r-- | src/common/sandbox.c | 162 | ||||
-rw-r--r-- | src/common/sandbox.h | 36 | ||||
-rw-r--r-- | src/common/torgzip.c | 68 | ||||
-rw-r--r-- | src/common/torgzip.h | 3 | ||||
-rw-r--r-- | src/common/torlog.h | 4 | ||||
-rw-r--r-- | src/common/tortls.c | 19 | ||||
-rw-r--r-- | src/common/util.c | 29 | ||||
-rw-r--r-- | src/common/util.h | 3 |
15 files changed, 203 insertions, 264 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index e25ecc462d..278e5c5241 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -981,14 +981,23 @@ tor_fd_getpos(int fd) #endif } -/** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success. */ +/** Move <b>fd</b> to the end of the file. Return -1 on error, 0 on success. + * If the file is a pipe, do nothing and succeed. + **/ int tor_fd_seekend(int fd) { #ifdef _WIN32 return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0; #else - return lseek(fd, 0, SEEK_END) < 0 ? -1 : 0; + off_t rc = lseek(fd, 0, SEEK_END) < 0 ? -1 : 0; +#ifdef ESPIPE + /* If we get an error and ESPIPE, then it's a pipe or a socket of a fifo: + * no need to worry. */ + if (rc < 0 && errno == ESPIPE) + rc = 0; +#endif + return (rc < 0) ? -1 : 0; #endif } @@ -1004,6 +1013,23 @@ tor_fd_setpos(int fd, off_t pos) #endif } +/** Replacement for ftruncate(fd, 0): move to the front of the file and remove + * all the rest of the file. Return -1 on error, 0 on success. */ +int +tor_ftruncate(int fd) +{ + /* Rumor has it that some versions of ftruncate do not move the file pointer. + */ + if (tor_fd_setpos(fd, 0) < 0) + return -1; + +#ifdef _WIN32 + return _chsize(fd, 0); +#else + return ftruncate(fd, 0); +#endif +} + #undef DEBUG_SOCKET_COUNTING #ifdef DEBUG_SOCKET_COUNTING /** A bitarray of all fds that should be passed to tor_socket_close(). Only @@ -1670,12 +1696,12 @@ log_credential_status(void) /* log supplementary groups */ sup_gids_size = 64; - sup_gids = tor_malloc(sizeof(gid_t) * 64); + sup_gids = tor_calloc(sizeof(gid_t), 64); while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 && errno == EINVAL && sup_gids_size < NGROUPS_MAX) { sup_gids_size *= 2; - sup_gids = tor_realloc(sup_gids, sizeof(gid_t) * sup_gids_size); + sup_gids = tor_reallocarray(sup_gids, sizeof(gid_t), sup_gids_size); } if (ngids < 0) { @@ -2485,14 +2511,12 @@ get_uname(void) "Unrecognized version of Windows [major=%d,minor=%d]", (int)info.dwMajorVersion,(int)info.dwMinorVersion); } -#if !defined (WINCE) #ifdef VER_NT_SERVER if (info.wProductType == VER_NT_SERVER || info.wProductType == VER_NT_DOMAIN_CONTROLLER) { strlcat(uname_result, " [server]", sizeof(uname_result)); } #endif -#endif #else strlcpy(uname_result, "Unknown platform", sizeof(uname_result)); #endif @@ -2697,15 +2721,8 @@ tor_gettimeofday(struct timeval *timeval) uint64_t ft_64; FILETIME ft_ft; } ft; -#if defined (WINCE) - /* wince do not have GetSystemTimeAsFileTime */ - SYSTEMTIME stime; - GetSystemTime(&stime); - SystemTimeToFileTime(&stime,&ft.ft_ft); -#else /* number of 100-nsec units since Jan 1, 1601 */ GetSystemTimeAsFileTime(&ft.ft_ft); -#endif if (ft.ft_64 < EPOCH_BIAS) { log_err(LD_GENERAL,"System time is before 1970; failing."); exit(1); @@ -2731,7 +2748,7 @@ tor_gettimeofday(struct timeval *timeval) return; } -#if defined(TOR_IS_MULTITHREADED) && !defined(_WIN32) +#if !defined(_WIN32) /** Defined iff we need to add locks when defining fake versions of reentrant * versions of time-related functions. */ #define TIME_FNS_NEED_LOCKS @@ -2991,7 +3008,6 @@ tor_get_thread_id(void) } #endif -#ifdef TOR_IS_MULTITHREADED /** Return a newly allocated, ready-for-use mutex. */ tor_mutex_t * tor_mutex_new(void) @@ -3009,7 +3025,6 @@ tor_mutex_free(tor_mutex_t *m) tor_mutex_uninit(m); tor_free(m); } -#endif /* Conditions. */ #ifdef USE_PTHREADS diff --git a/src/common/compat.h b/src/common/compat.h index ec7d2415ed..852a432187 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -56,21 +56,6 @@ #include <stdio.h> #include <errno.h> -#if defined (WINCE) -#include <fcntl.h> -#include <io.h> -#include <math.h> -#include <projects.h> -/* this is not exported as W .... */ -#define SHGetPathFromIDListW SHGetPathFromIDList -/* wcecompat has vasprintf */ -#define HAVE_VASPRINTF -/* no service here */ -#ifdef NT_SERVICE -#undef NT_SERVICE -#endif -#endif // WINCE - #ifndef NULL_REP_IS_ZERO_BYTES #error "It seems your platform does not represent NULL as zero. We can't cope." #endif @@ -423,6 +408,7 @@ void tor_lockfile_unlock(tor_lockfile_t *lockfile); off_t tor_fd_getpos(int fd); int tor_fd_setpos(int fd, off_t pos); int tor_fd_seekend(int fd); +int tor_ftruncate(int fd); #ifdef _WIN32 #define PATH_SEPARATOR "\\" @@ -648,15 +634,12 @@ int get_total_system_memory(size_t *mem_out); int spawn_func(void (*func)(void *), void *data); void spawn_exit(void) ATTR_NORETURN; -#if defined(ENABLE_THREADS) && defined(_WIN32) +#if defined(_WIN32) #define USE_WIN32_THREADS -#define TOR_IS_MULTITHREADED 1 -#elif (defined(ENABLE_THREADS) && defined(HAVE_PTHREAD_H) && \ - defined(HAVE_PTHREAD_CREATE)) +#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE) #define USE_PTHREADS -#define TOR_IS_MULTITHREADED 1 #else -#undef TOR_IS_MULTITHREADED +#error "No threading system was found" #endif int compute_num_cpus(void); @@ -682,7 +665,6 @@ typedef struct tor_mutex_t { int tor_mlockall(void); -#ifdef TOR_IS_MULTITHREADED tor_mutex_t *tor_mutex_new(void); void tor_mutex_init(tor_mutex_t *m); void tor_mutex_acquire(tor_mutex_t *m); @@ -691,21 +673,10 @@ void tor_mutex_free(tor_mutex_t *m); void tor_mutex_uninit(tor_mutex_t *m); unsigned long tor_get_thread_id(void); void tor_threads_init(void); -#else -#define tor_mutex_new() ((tor_mutex_t*)tor_malloc(sizeof(int))) -#define tor_mutex_init(m) STMT_NIL -#define tor_mutex_acquire(m) STMT_VOID(m) -#define tor_mutex_release(m) STMT_NIL -#define tor_mutex_free(m) STMT_BEGIN tor_free(m); STMT_END -#define tor_mutex_uninit(m) STMT_NIL -#define tor_get_thread_id() (1UL) -#define tor_threads_init() STMT_NIL -#endif void set_main_thread(void); int in_main_thread(void); -#ifdef TOR_IS_MULTITHREADED #if 0 typedef struct tor_cond_t tor_cond_t; tor_cond_t *tor_cond_new(void); @@ -714,7 +685,6 @@ int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex); void tor_cond_signal_one(tor_cond_t *cond); void tor_cond_signal_all(tor_cond_t *cond); #endif -#endif /** Macros for MIN/MAX. Never use these when the arguments could have * side-effects. diff --git a/src/common/container.c b/src/common/container.c index b937d544fc..7f02dec550 100644 --- a/src/common/container.c +++ b/src/common/container.c @@ -34,7 +34,7 @@ smartlist_new(void) smartlist_t *sl = tor_malloc(sizeof(smartlist_t)); sl->num_used = 0; sl->capacity = SMARTLIST_DEFAULT_CAPACITY; - sl->list = tor_malloc(sizeof(void *) * sl->capacity); + sl->list = tor_calloc(sizeof(void *), sl->capacity); return sl; } @@ -66,19 +66,28 @@ smartlist_ensure_capacity(smartlist_t *sl, int size) #define MAX_CAPACITY (INT_MAX) #else #define MAX_CAPACITY (int)((SIZE_MAX / (sizeof(void*)))) +#define ASSERT_CAPACITY #endif if (size > sl->capacity) { int higher = sl->capacity; if (PREDICT_UNLIKELY(size > MAX_CAPACITY/2)) { +#ifdef ASSERT_CAPACITY + /* We don't include this assertion when MAX_CAPACITY == INT_MAX, + * since int size; (size <= INT_MAX) makes analysis tools think we're + * doing something stupid. */ tor_assert(size <= MAX_CAPACITY); +#endif higher = MAX_CAPACITY; } else { while (size > higher) higher *= 2; } sl->capacity = higher; - sl->list = tor_realloc(sl->list, sizeof(void*)*((size_t)sl->capacity)); + sl->list = tor_reallocarray(sl->list, sizeof(void *), + ((size_t)sl->capacity)); } +#undef ASSERT_CAPACITY +#undef MAX_CAPACITY } /** Append element to the end of the list. */ diff --git a/src/common/container.h b/src/common/container.h index 0d31f2093b..08da34e07e 100644 --- a/src/common/container.h +++ b/src/common/container.h @@ -563,7 +563,7 @@ bitarray_init_zero(unsigned int n_bits) { /* round up to the next int. */ size_t sz = (n_bits+BITARRAY_MASK) >> BITARRAY_SHIFT; - return tor_malloc_zero(sz*sizeof(unsigned int)); + return tor_calloc(sz, sizeof(unsigned int)); } /** Expand <b>ba</b> from holding <b>n_bits_old</b> to <b>n_bits_new</b>, * clearing all new bits. Returns a possibly changed pointer to the @@ -577,7 +577,7 @@ bitarray_expand(bitarray_t *ba, char *ptr; if (sz_new <= sz_old) return ba; - ptr = tor_realloc(ba, sz_new*sizeof(unsigned int)); + ptr = tor_reallocarray(ba, sz_new, sizeof(unsigned int)); /* This memset does nothing to the older excess bytes. But they were * already set to 0 by bitarry_init_zero. */ memset(ptr+sz_old*sizeof(unsigned int), 0, diff --git a/src/common/crypto.c b/src/common/crypto.c index a247a87d48..014c83e850 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -75,12 +75,10 @@ /** Macro: is k a valid RSA private key? */ #define PRIVATE_KEY_OK(k) ((k) && (k)->key && (k)->key->p) -#ifdef TOR_IS_MULTITHREADED /** A number of preallocated mutexes for use by OpenSSL. */ static tor_mutex_t **openssl_mutexes_ = NULL; /** How many mutexes have we allocated for use by OpenSSL? */ static int n_openssl_mutexes_ = 0; -#endif /** A public key, or a public/private key-pair. */ struct crypto_pk_t @@ -1840,7 +1838,7 @@ crypto_store_dynamic_dh_modulus(const char *fname) goto done; } - base64_encoded_dh = tor_malloc_zero(len * 2); /* should be enough */ + base64_encoded_dh = tor_calloc(len, 2); /* should be enough */ new_len = base64_encode(base64_encoded_dh, len * 2, (char *)dh_string_repr, len); if (new_len < 0) { @@ -3090,8 +3088,6 @@ memwipe(void *mem, uint8_t byte, size_t sz) memset(mem, byte, sz); } -#ifdef TOR_IS_MULTITHREADED - #ifndef OPENSSL_THREADS #error OpenSSL has been built without thread support. Tor requires an \ OpenSSL library with thread support enabled. @@ -3168,7 +3164,7 @@ setup_openssl_threading(void) int i; int n = CRYPTO_num_locks(); n_openssl_mutexes_ = n; - openssl_mutexes_ = tor_malloc(n*sizeof(tor_mutex_t *)); + openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *)); for (i=0; i < n; ++i) openssl_mutexes_[i] = tor_mutex_new(); CRYPTO_set_locking_callback(openssl_locking_cb_); @@ -3178,13 +3174,6 @@ setup_openssl_threading(void) CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy_cb_); return 0; } -#else -static int -setup_openssl_threading(void) -{ - return 0; -} -#endif /** Uninitialize the crypto library. Return 0 on success, -1 on failure. */ @@ -3208,7 +3197,7 @@ crypto_global_cleanup(void) CONF_modules_unload(1); CRYPTO_cleanup_all_ex_data(); -#ifdef TOR_IS_MULTITHREADED + if (n_openssl_mutexes_) { int n = n_openssl_mutexes_; tor_mutex_t **ms = openssl_mutexes_; @@ -3220,7 +3209,7 @@ crypto_global_cleanup(void) } tor_free(ms); } -#endif + tor_free(crypto_openssl_version_str); tor_free(crypto_openssl_header_version_str); return 0; diff --git a/src/common/di_ops.c b/src/common/di_ops.c index 14a1443400..a8bfd02532 100644 --- a/src/common/di_ops.c +++ b/src/common/di_ops.c @@ -130,6 +130,7 @@ tor_memeq(const void *a, const void *b, size_t sz) * 1 & ((any_difference - 1) >> 8) == 0 */ + /*coverity[overflow]*/ return 1 & ((any_difference - 1) >> 8); } @@ -217,6 +218,7 @@ safe_mem_is_zero(const void *mem, size_t sz) total |= *ptr++; } + /*coverity[overflow]*/ return 1 & ((total - 1) >> 8); } diff --git a/src/common/log.c b/src/common/log.c index 517fa4faaa..2e51e5c578 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -1010,12 +1010,16 @@ mark_logs_temp(void) * logfile fails, -1 is returned and errno is set appropriately (by open(2)). */ int -add_file_log(const log_severity_list_t *severity, const char *filename) +add_file_log(const log_severity_list_t *severity, const char *filename, + const int truncate) { int fd; logfile_t *lf; - fd = tor_open_cloexec(filename, O_WRONLY|O_CREAT|O_APPEND, 0644); + int open_flags = O_WRONLY|O_CREAT; + open_flags |= truncate ? O_TRUNC : O_APPEND; + + fd = tor_open_cloexec(filename, open_flags, 0644); if (fd<0) return -1; if (tor_fd_seekend(fd)<0) { @@ -1297,3 +1301,15 @@ switch_logs_debug(void) UNLOCK_LOGS(); } +/** Truncate all the log files. */ +void +truncate_logs(void) +{ + logfile_t *lf; + for (lf = logfiles; lf; lf = lf->next) { + if (lf->fd >= 0) { + tor_ftruncate(lf->fd); + } + } +} + diff --git a/src/common/sandbox.c b/src/common/sandbox.c index 05b91be7be..b414e3184d 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -98,6 +98,8 @@ static sandbox_cfg_t *filter_dynamic = NULL; #undef SCMP_CMP #define SCMP_CMP(a,b,c) ((struct scmp_arg_cmp){(a),(b),(c),0}) +#define SCMP_CMP_STR(a,b,c) \ + ((struct scmp_arg_cmp) {(a),(b),(intptr_t)(void*)(c),0}) #define SCMP_CMP4(a,b,c,d) ((struct scmp_arg_cmp){(a),(b),(c),(d)}) /* We use a wrapper here because these masked comparisons seem to be pretty * verbose. Also, it's important to cast to scmp_datum_t before negating the @@ -252,7 +254,7 @@ sb_execve(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (param != NULL && param->prot == 1 && param->syscall == SCMP_SYS(execve)) { rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), - SCMP_CMP(0, SCMP_CMP_EQ, param->value)); + SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add execve syscall, received " "libseccomp error %d", rc); @@ -389,7 +391,7 @@ sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (param != NULL && param->prot == 1 && param->syscall == SCMP_SYS(open)) { rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), - SCMP_CMP(0, SCMP_CMP_EQ, param->value)); + SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " "libseccomp error %d", rc); @@ -444,8 +446,8 @@ sb_rename(scmp_filter_ctx ctx, sandbox_cfg_t *filter) param->syscall == SCMP_SYS(rename)) { rc = seccomp_rule_add_2(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rename), - SCMP_CMP(0, SCMP_CMP_EQ, param->value), - SCMP_CMP(1, SCMP_CMP_EQ, param->value2)); + SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value2)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add rename syscall, received " "libseccomp error %d", rc); @@ -475,7 +477,7 @@ sb_openat(scmp_filter_ctx ctx, sandbox_cfg_t *filter) == SCMP_SYS(openat)) { rc = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), SCMP_CMP(0, SCMP_CMP_EQ, AT_FDCWD), - SCMP_CMP(1, SCMP_CMP_EQ, param->value), + SCMP_CMP_STR(1, SCMP_CMP_EQ, param->value), SCMP_CMP(2, SCMP_CMP_EQ, O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY| O_CLOEXEC)); if (rc != 0) { @@ -884,7 +886,7 @@ sb_stat64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) if (param != NULL && param->prot == 1 && (param->syscall == SCMP_SYS(open) || param->syscall == SCMP_SYS(stat64))) { rc = seccomp_rule_add_1(ctx, SCMP_ACT_ALLOW, SCMP_SYS(stat64), - SCMP_CMP(0, SCMP_CMP_EQ, param->value)); + SCMP_CMP_STR(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " "libseccomp error %d", rc); @@ -967,7 +969,7 @@ static int prot_strings_helper(strmap_t *locations, char **pr_mem_next_p, size_t *pr_mem_left_p, - intptr_t *value_p) + char **value_p) { char *param_val; size_t param_size; @@ -983,7 +985,7 @@ prot_strings_helper(strmap_t *locations, if (location) { // We already interned this string. tor_free(param_val); - *value_p = (intptr_t) location; + *value_p = location; return 0; } else if (*pr_mem_left_p >= param_size) { // copy to protected @@ -992,7 +994,7 @@ prot_strings_helper(strmap_t *locations, // re-point el parameter to protected tor_free(param_val); - *value_p = (intptr_t) location; + *value_p = location; strmap_set(locations, location, location); /* good real estate advice */ @@ -1074,7 +1076,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base)); if (ret) { log_err(LD_BUG,"(Sandbox) mremap protected memory filter fail!"); - return ret; + goto out; } // no munmap of the protected base address @@ -1082,7 +1084,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) SCMP_CMP(0, SCMP_CMP_EQ, (intptr_t) pr_mem_base)); if (ret) { log_err(LD_BUG,"(Sandbox) munmap protected memory filter fail!"); - return ret; + goto out; } /* @@ -1101,7 +1103,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); if (ret) { log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (LT)!"); - return ret; + goto out; } ret = seccomp_rule_add_3(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), @@ -1111,7 +1113,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE)); if (ret) { log_err(LD_BUG,"(Sandbox) mprotect protected memory filter fail (GT)!"); - return ret; + goto out; } out: @@ -1126,7 +1128,7 @@ prot_strings(scmp_filter_ctx ctx, sandbox_cfg_t* cfg) * point. */ static sandbox_cfg_t* -new_element2(int syscall, intptr_t value, intptr_t value2) +new_element2(int syscall, char *value, char *value2) { smp_param_t *param = NULL; @@ -1142,9 +1144,9 @@ new_element2(int syscall, intptr_t value, intptr_t value2) } static sandbox_cfg_t* -new_element(int syscall, intptr_t value) +new_element(int syscall, char *value) { - return new_element2(syscall, value, 0); + return new_element2(syscall, value, NULL); } #ifdef __NR_stat64 @@ -1158,7 +1160,7 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) { sandbox_cfg_t *elem = NULL; - elem = new_element(SCMP_stat, (intptr_t)(void*) file); + elem = new_element(SCMP_stat, file); if (!elem) { log_err(LD_BUG,"(Sandbox) failed to register parameter!"); return -1; @@ -1171,33 +1173,11 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) } int -sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...) -{ - int rc = 0; - char *fn = NULL; - - va_list ap; - va_start(ap, cfg); - - while ((fn = va_arg(ap, char*)) != NULL) { - rc = sandbox_cfg_allow_stat_filename(cfg, fn); - if (rc) { - log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_stat_filename_array fail"); - goto end; - } - } - - end: - va_end(ap); - return 0; -} - -int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file) { sandbox_cfg_t *elem = NULL; - elem = new_element(SCMP_SYS(open), (intptr_t)(void *) file); + elem = new_element(SCMP_SYS(open), file); if (!elem) { log_err(LD_BUG,"(Sandbox) failed to register parameter!"); return -1; @@ -1214,9 +1194,7 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) { sandbox_cfg_t *elem = NULL; - elem = new_element2(SCMP_SYS(rename), - (intptr_t)(void *) file1, - (intptr_t)(void *) file2); + elem = new_element2(SCMP_SYS(rename), file1, file2); if (!elem) { log_err(LD_BUG,"(Sandbox) failed to register parameter!"); @@ -1230,33 +1208,11 @@ sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) } int -sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...) -{ - int rc = 0; - char *fn = NULL; - - va_list ap; - va_start(ap, cfg); - - while ((fn = va_arg(ap, char*)) != NULL) { - rc = sandbox_cfg_allow_open_filename(cfg, fn); - if (rc) { - log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_open_filename_array fail"); - goto end; - } - } - - end: - va_end(ap); - return 0; -} - -int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) { sandbox_cfg_t *elem = NULL; - elem = new_element(SCMP_SYS(openat), (intptr_t)(void *) file); + elem = new_element(SCMP_SYS(openat), file); if (!elem) { log_err(LD_BUG,"(Sandbox) failed to register parameter!"); return -1; @@ -1268,35 +1224,13 @@ sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) return 0; } -int -sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...) -{ - int rc = 0; - char *fn = NULL; - - va_list ap; - va_start(ap, cfg); - - while ((fn = va_arg(ap, char*)) != NULL) { - rc = sandbox_cfg_allow_openat_filename(cfg, fn); - if (rc) { - log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_openat_filename_array fail"); - goto end; - } - } - - end: - va_end(ap); - return 0; -} - #if 0 int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) { sandbox_cfg_t *elem = NULL; - elem = new_element(SCMP_SYS(execve), (intptr_t)(void *) com); + elem = new_element(SCMP_SYS(execve), com); if (!elem) { log_err(LD_BUG,"(Sandbox) failed to register parameter!"); return -1; @@ -1308,28 +1242,6 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) return 0; } -int -sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...) -{ - int rc = 0; - char *fn = NULL; - - va_list ap; - va_start(ap, cfg); - - while ((fn = va_arg(ap, char*)) != NULL) { - - rc = sandbox_cfg_allow_execve(cfg, fn); - if (rc) { - log_err(LD_BUG,"(Sandbox) sandbox_cfg_allow_execve_array failed"); - goto end; - } - } - - end: - va_end(ap); - return 0; -} #endif /** Cache entry for getaddrinfo results; used when sandboxing is implemented @@ -1772,26 +1684,12 @@ sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file) } int -sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...) -{ - (void)cfg; - return 0; -} - -int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file) { (void)cfg; (void)file; return 0; } -int -sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...) -{ - (void)cfg; - return 0; -} - #if 0 int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) @@ -1799,13 +1697,6 @@ sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com) (void)cfg; (void)com; return 0; } - -int -sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...) -{ - (void)cfg; - return 0; -} #endif int @@ -1816,13 +1707,6 @@ sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file) } int -sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...) -{ - (void)cfg; - return 0; -} - -int sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2) { (void)cfg; (void)file1; (void)file2; diff --git a/src/common/sandbox.h b/src/common/sandbox.h index 20d5d5080c..095d8d47f4 100644 --- a/src/common/sandbox.h +++ b/src/common/sandbox.h @@ -66,9 +66,9 @@ typedef struct smp_param { int syscall; /** parameter value. */ - intptr_t value; + char *value; /** parameter value, second argument. */ - intptr_t value2; + char *value2; /** parameter flag (0 = not protected, 1 = protected). */ int prot; @@ -149,14 +149,6 @@ int sandbox_cfg_allow_open_filename(sandbox_cfg_t **cfg, char *file); /**DOCDOC*/ int sandbox_cfg_allow_rename(sandbox_cfg_t **cfg, char *file1, char *file2); -/** Function used to add a series of open allowed filenames to a supplied - * configuration. - * @param cfg sandbox configuration. - * @param ... a list of stealable pointers to permitted files. The last - * one must be NULL. -*/ -int sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...); - /** * Function used to add a openat allowed filename to a supplied configuration. * The (char*) specifies the path to the allowed file; we steal the pointer to @@ -164,28 +156,12 @@ int sandbox_cfg_allow_open_filename_array(sandbox_cfg_t **cfg, ...); */ int sandbox_cfg_allow_openat_filename(sandbox_cfg_t **cfg, char *file); -/** Function used to add a series of openat allowed filenames to a supplied - * configuration. - * @param cfg sandbox configuration. - * @param ... a list of stealable pointers to permitted files. The last - * one must be NULL. - */ -int sandbox_cfg_allow_openat_filename_array(sandbox_cfg_t **cfg, ...); - #if 0 /** * Function used to add a execve allowed filename to a supplied configuration. * The (char*) specifies the path to the allowed file; that pointer is stolen. */ int sandbox_cfg_allow_execve(sandbox_cfg_t **cfg, const char *com); - -/** Function used to add a series of execve allowed filenames to a supplied - * configuration. - * @param cfg sandbox configuration. - * @param ... an array of stealable pointers to permitted files. The last - * one must be NULL. - */ -int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...); #endif /** @@ -194,14 +170,6 @@ int sandbox_cfg_allow_execve_array(sandbox_cfg_t **cfg, ...); */ int sandbox_cfg_allow_stat_filename(sandbox_cfg_t **cfg, char *file); -/** Function used to add a series of stat64 allowed filenames to a supplied - * configuration. - * @param cfg sandbox configuration. - * @param ... an array of stealable pointers to permitted files. The last - * one must be NULL. - */ -int sandbox_cfg_allow_stat_filename_array(sandbox_cfg_t **cfg, ...); - /** Function used to initialise a sandbox configuration.*/ int sandbox_init(sandbox_cfg_t* cfg); diff --git a/src/common/torgzip.c b/src/common/torgzip.c index 15451ee30d..b4688bf9d8 100644 --- a/src/common/torgzip.c +++ b/src/common/torgzip.c @@ -46,6 +46,12 @@ #include <zlib.h> +static size_t tor_zlib_state_size_precalc(int inflate, + int windowbits, int memlevel); + +/** Total number of bytes allocated for zlib state */ +static size_t total_zlib_allocation = 0; + /** Set to 1 if zlib is a version that supports gzip; set to 0 if it doesn't; * set to -1 if we haven't checked yet. */ static int gzip_is_supported = -1; @@ -411,6 +417,9 @@ struct tor_zlib_state_t { size_t input_so_far; /** Number of bytes written so far. Used to detect zlib bombs. */ size_t output_so_far; + + /** Approximate number of bytes allocated for this object. */ + size_t allocation; }; /** Construct and return a tor_zlib_state_t object using <b>method</b>. If @@ -420,6 +429,7 @@ tor_zlib_state_t * tor_zlib_new(int compress, compress_method_t method) { tor_zlib_state_t *out; + int bits; if (method == GZIP_METHOD && !is_gzip_supported()) { /* Old zlib version don't support gzip in inflateInit2 */ @@ -432,14 +442,19 @@ tor_zlib_new(int compress, compress_method_t method) out->stream.zfree = Z_NULL; out->stream.opaque = NULL; out->compress = compress; + bits = method_bits(method); if (compress) { if (deflateInit2(&out->stream, Z_BEST_COMPRESSION, Z_DEFLATED, - method_bits(method), 8, Z_DEFAULT_STRATEGY) != Z_OK) + bits, 8, Z_DEFAULT_STRATEGY) != Z_OK) goto err; } else { - if (inflateInit2(&out->stream, method_bits(method)) != Z_OK) + if (inflateInit2(&out->stream, bits) != Z_OK) goto err; } + out->allocation = tor_zlib_state_size_precalc(!compress, bits, 8); + + total_zlib_allocation += out->allocation; + return out; err: @@ -472,7 +487,7 @@ tor_zlib_process(tor_zlib_state_t *state, state->stream.avail_out = (unsigned int)*out_len; if (state->compress) { - err = deflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); + err = deflate(&state->stream, finish ? Z_FINISH : Z_NO_FLUSH); } else { err = inflate(&state->stream, finish ? Z_FINISH : Z_SYNC_FLUSH); } @@ -517,6 +532,8 @@ tor_zlib_free(tor_zlib_state_t *state) if (!state) return; + total_zlib_allocation -= state->allocation; + if (state->compress) deflateEnd(&state->stream); else @@ -525,3 +542,48 @@ tor_zlib_free(tor_zlib_state_t *state) tor_free(state); } +/** Return an approximate number of bytes used in RAM to hold a state with + * window bits <b>windowBits</b> and compression level 'memlevel' */ +static size_t +tor_zlib_state_size_precalc(int inflate, int windowbits, int memlevel) +{ + windowbits &= 15; + +#define A_FEW_KILOBYTES 2048 + + if (inflate) { + /* From zconf.h: + + "The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects." + */ + return sizeof(tor_zlib_state_t) + sizeof(struct z_stream_s) + + (1 << 15) + A_FEW_KILOBYTES; + } else { + /* Also from zconf.h: + + "The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + ... plus a few kilobytes for small objects." + */ + return sizeof(tor_zlib_state_t) + sizeof(struct z_stream_s) + + (1 << (windowbits + 2)) + (1 << (memlevel + 9)) + A_FEW_KILOBYTES; + } +#undef A_FEW_KILOBYTES +} + +/** Return the approximate number of bytes allocated for <b>state</b>. */ +size_t +tor_zlib_state_size(const tor_zlib_state_t *state) +{ + return state->allocation; +} + +/** Return the approximate number of bytes allocated for all zlib states. */ +size_t +tor_zlib_get_total_allocation(void) +{ + return total_zlib_allocation; +} + diff --git a/src/common/torgzip.h b/src/common/torgzip.h index 5db03fe6e0..d407bf48c6 100644 --- a/src/common/torgzip.h +++ b/src/common/torgzip.h @@ -55,5 +55,8 @@ tor_zlib_output_t tor_zlib_process(tor_zlib_state_t *state, int finish); void tor_zlib_free(tor_zlib_state_t *state); +size_t tor_zlib_state_size(const tor_zlib_state_t *state); +size_t tor_zlib_get_total_allocation(void); + #endif diff --git a/src/common/torlog.h b/src/common/torlog.h index 34f70f3c00..34e39b4b94 100644 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@ -130,7 +130,8 @@ void set_log_severity_config(int minSeverity, int maxSeverity, log_severity_list_t *severity_out); void add_stream_log(const log_severity_list_t *severity, const char *name, int fd); -int add_file_log(const log_severity_list_t *severity, const char *filename); +int add_file_log(const log_severity_list_t *severity, const char *filename, + const int truncate); #ifdef HAVE_SYSLOG_H int add_syslog_log(const log_severity_list_t *severity); #endif @@ -148,6 +149,7 @@ void change_callback_log_severity(int loglevelMin, int loglevelMax, void flush_pending_log_callbacks(void); void log_set_application_name(const char *name); void set_log_time_granularity(int granularity_msec); +void truncate_logs(void); void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) CHECK_PRINTF(3,4); diff --git a/src/common/tortls.c b/src/common/tortls.c index 4fd9bba380..eda10bbe2e 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -16,10 +16,6 @@ #include "orconfig.h" -#if defined (WINCE) -#include <WinSock2.h> -#endif - #include <assert.h> #ifdef _WIN32 /*wrkard for dtls1.h >= 0.9.8m of "#include <winsock.h>"*/ #ifndef _WIN32_WINNT @@ -786,8 +782,7 @@ static const cipher_info_t CLIENT_CIPHER_INFO_LIST[] = { }; /** The length of CLIENT_CIPHER_INFO_LIST and CLIENT_CIPHER_DUMMIES. */ -static const int N_CLIENT_CIPHERS = - sizeof(CLIENT_CIPHER_INFO_LIST)/sizeof(CLIENT_CIPHER_INFO_LIST[0]); +static const int N_CLIENT_CIPHERS = ARRAY_LENGTH(CLIENT_CIPHER_INFO_LIST); #endif #ifndef V2_HANDSHAKE_CLIENT @@ -2615,16 +2610,20 @@ check_no_tls_errors_(const char *fname, int line) int tor_tls_used_v1_handshake(tor_tls_t *tls) { +#if defined(V2_HANDSHAKE_SERVER) && defined(V2_HANDSHAKE_CLIENT) + return ! tls->wasV2Handshake; +#else if (tls->isServer) { -#ifdef V2_HANDSHAKE_SERVER +# ifdef V2_HANDSHAKE_SERVER return ! tls->wasV2Handshake; -#endif +# endif } else { -#ifdef V2_HANDSHAKE_CLIENT +# ifdef V2_HANDSHAKE_CLIENT return ! tls->wasV2Handshake; -#endif +# endif } return 1; +#endif } /** Return true iff <b>name</b> is a DN of a kind that could only diff --git a/src/common/util.c b/src/common/util.c index 2d7893b38a..16ff8e3a80 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -244,6 +244,20 @@ tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS) return result; } +/** + * Try to realloc <b>ptr</b> so that it takes up sz1 * sz2 bytes. Check for + * overflow. Unlike other allocation functions, return NULL on overflow. + */ +void * +tor_reallocarray_(void *ptr, size_t sz1, size_t sz2 DMALLOC_PARAMS) +{ + /* XXXX we can make this return 0, but we would need to check all the + * reallocarray users. */ + tor_assert(sz2 == 0 || sz1 < SIZE_T_CEILING / sz2); + + return tor_realloc(ptr, (sz1 * sz2) DMALLOC_FN_ARGS); +} + /** Return a newly allocated copy of the NUL-terminated string s. On * error, log and terminate. (Like strdup(s), but never returns * NULL.) @@ -1893,7 +1907,7 @@ check_private_dir(const char *dirname, cpd_check_t check, } if (check & CPD_CREATE) { log_info(LD_GENERAL, "Creating directory %s", dirname); -#if defined (_WIN32) && !defined (WINCE) +#if defined (_WIN32) r = mkdir(dirname); #else r = mkdir(dirname, 0700); @@ -3378,8 +3392,8 @@ format_win_cmdline_argument(const char *arg) smartlist_add(arg_chars, (void*)&backslash); /* Allocate space for argument, quotes (if needed), and terminator */ - formatted_arg = tor_malloc(sizeof(char) * - (smartlist_len(arg_chars) + (need_quotes?2:0) + 1)); + formatted_arg = tor_calloc(sizeof(char), + (smartlist_len(arg_chars) + (need_quotes ? 2 : 0) + 1)); /* Add leading quote */ i=0; @@ -4038,8 +4052,11 @@ tor_spawn_background(const char *const filename, const char **argv, status = process_handle->status = PROCESS_STATUS_RUNNING; /* Set stdout/stderr pipes to be non-blocking */ - fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK); - fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK); + if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 || + fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0) { + log_warn(LD_GENERAL, "Failed to set stderror/stdout pipes nonblocking " + "in parent process: %s", strerror(errno)); + } /* Open the buffered IO streams */ process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r"); process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r"); @@ -5008,7 +5025,7 @@ tor_check_port_forwarding(const char *filename, for each smartlist element (one for "-p" and one for the ports), and one for the final NULL. */ args_n = 1 + 2*smartlist_len(ports_to_forward) + 1; - argv = tor_malloc_zero(sizeof(char*)*args_n); + argv = tor_calloc(sizeof(char *), args_n); argv[argv_index++] = filename; SMARTLIST_FOREACH_BEGIN(ports_to_forward, const char *, port) { diff --git a/src/common/util.h b/src/common/util.h index 97367a9a7b..61bb05f016 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -79,6 +79,7 @@ void *tor_malloc_(size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *tor_malloc_zero_(size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *tor_calloc_(size_t nmemb, size_t size DMALLOC_PARAMS) ATTR_MALLOC; void *tor_realloc_(void *ptr, size_t size DMALLOC_PARAMS); +void *tor_reallocarray_(void *ptr, size_t size1, size_t size2 DMALLOC_PARAMS); char *tor_strdup_(const char *s DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1)); char *tor_strndup_(const char *s, size_t n DMALLOC_PARAMS) ATTR_MALLOC ATTR_NONNULL((1)); @@ -116,6 +117,8 @@ extern int dmalloc_free(const char *file, const int line, void *pnt, #define tor_malloc_zero(size) tor_malloc_zero_(size DMALLOC_ARGS) #define tor_calloc(nmemb,size) tor_calloc_(nmemb, size DMALLOC_ARGS) #define tor_realloc(ptr, size) tor_realloc_(ptr, size DMALLOC_ARGS) +#define tor_reallocarray(ptr, sz1, sz2) \ + tor_reallocarray_((ptr), (sz1), (sz2) DMALLOC_ARGS) #define tor_strdup(s) tor_strdup_(s DMALLOC_ARGS) #define tor_strndup(s, n) tor_strndup_(s, n DMALLOC_ARGS) #define tor_memdup(s, n) tor_memdup_(s, n DMALLOC_ARGS) |