aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorteor <teor2345@gmail.com>2015-01-10 16:34:10 +1100
committerteor <teor2345@gmail.com>2015-01-10 16:34:10 +1100
commitc200ab46b85cece87a4bcdbaacd41bc6539d1671 (patch)
treef17e2c59dd076a73cce9787ecad3f8eeec88f705 /src/common
parentfd7e9e9030cee9d8e863cea3f3f90226ae66fdfe (diff)
parent6a9cae2e1dafb756b30fda541e8b5d68cfd45f89 (diff)
downloadtor-c200ab46b85cece87a4bcdbaacd41bc6539d1671.tar.gz
tor-c200ab46b85cece87a4bcdbaacd41bc6539d1671.zip
Merge branch 'bug14001-clang-warning' into bug13111-empty-key-files-fn-empty
Conflicts: src/or/router.c Choose newer comment. Merge changes to comment and function invocation.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/address.c8
-rw-r--r--src/common/compat.c2
-rw-r--r--src/common/compat.h9
-rw-r--r--src/common/compat_libevent.c6
-rw-r--r--src/common/compat_libevent.h2
-rw-r--r--src/common/crypto.c2
-rw-r--r--src/common/log.c2
-rw-r--r--src/common/torlog.h4
-rw-r--r--src/common/util.c150
-rw-r--r--src/common/util.h7
10 files changed, 148 insertions, 44 deletions
diff --git a/src/common/address.c b/src/common/address.c
index de5d3a6ff7..0b475fc9fd 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -723,6 +723,11 @@ tor_addr_parse_mask_ports(const char *s,
/* XXXX_IP6 is this really what we want? */
bits = 96 + bits%32; /* map v4-mapped masks onto 96-128 bits */
}
+ if (any_flag) {
+ log_warn(LD_GENERAL,
+ "Found bit prefix with wildcard address; rejecting");
+ goto err;
+ }
} else { /* pick an appropriate mask, as none was given */
if (any_flag)
bits = 0; /* This is okay whether it's V6 or V4 (FIX V4-mapped V6!) */
@@ -1114,7 +1119,8 @@ fmt_addr32(uint32_t addr)
int
tor_addr_parse(tor_addr_t *addr, const char *src)
{
- char *tmp = NULL; /* Holds substring if we got a dotted quad. */
+ /* Holds substring of IPv6 address after removing square brackets */
+ char *tmp = NULL;
int result;
struct in_addr in_tmp;
struct in6_addr in6_tmp;
diff --git a/src/common/compat.c b/src/common/compat.c
index b28790f0e4..404f4f189f 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1698,7 +1698,7 @@ log_credential_status(void)
/* log supplementary groups */
sup_gids_size = 64;
- sup_gids = tor_calloc(sizeof(gid_t), 64);
+ sup_gids = tor_calloc(64, sizeof(gid_t));
while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 &&
errno == EINVAL &&
sup_gids_size < NGROUPS_MAX) {
diff --git a/src/common/compat.h b/src/common/compat.h
index f2eef5b6e7..7001361af3 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -203,6 +203,15 @@ extern INLINE double U64_TO_DBL(uint64_t x) {
#define STMT_END } while (0)
#endif
+/* Some tools (like coccinelle) don't like to see operators as macro
+ * arguments. */
+#define OP_LT <
+#define OP_GT >
+#define OP_GE >=
+#define OP_LE <=
+#define OP_EQ ==
+#define OP_NE !=
+
/* ===== String compatibility */
#ifdef _WIN32
/* Windows names string functions differently from most other platforms. */
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index 33672f07d8..85ed58456e 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -283,8 +283,8 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
}
/** Return the current Libevent event base that we're set up to use. */
-struct event_base *
-tor_libevent_get_base(void)
+MOCK_IMPL(struct event_base *,
+tor_libevent_get_base, (void))
{
return the_event_base;
}
@@ -717,7 +717,7 @@ tor_gettimeofday_cached_monotonic(struct timeval *tv)
struct timeval last_tv = { 0, 0 };
tor_gettimeofday_cached(tv);
- if (timercmp(tv, &last_tv, <)) {
+ if (timercmp(tv, &last_tv, OP_LT)) {
memcpy(tv, &last_tv, sizeof(struct timeval));
} else {
memcpy(&last_tv, tv, sizeof(struct timeval));
diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h
index c5c78b822d..57d0c4da1b 100644
--- a/src/common/compat_libevent.h
+++ b/src/common/compat_libevent.h
@@ -72,7 +72,7 @@ typedef struct tor_libevent_cfg {
} tor_libevent_cfg;
void tor_libevent_initialize(tor_libevent_cfg *cfg);
-struct event_base *tor_libevent_get_base(void);
+MOCK_DECL(struct event_base *, tor_libevent_get_base, (void));
const char *tor_libevent_get_method(void);
void tor_check_libevent_version(const char *m, int server,
const char **badness_out);
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 90a16fab1a..7138ba003e 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1012,7 +1012,7 @@ crypto_pk_public_checksig(crypto_pk_t *env, char *to,
env->key, RSA_PKCS1_PADDING);
if (r<0) {
- crypto_log_errors(LOG_WARN, "checking RSA signature");
+ crypto_log_errors(LOG_INFO, "checking RSA signature");
return -1;
}
return r;
diff --git a/src/common/log.c b/src/common/log.c
index ad0da7da6b..0a21ffbd44 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -451,7 +451,7 @@ MOCK_IMPL(STATIC void,
logv,(int severity, log_domain_mask_t domain, const char *funcname,
const char *suffix, const char *format, va_list ap))
{
- char buf[10024];
+ char buf[10240];
size_t msg_len = 0;
int formatted = 0;
logfile_t *lf;
diff --git a/src/common/torlog.h b/src/common/torlog.h
index fa7266c199..483a97935f 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -97,8 +97,10 @@
#define LD_HEARTBEAT (1u<<20)
/** Abstract channel_t code */
#define LD_CHANNEL (1u<<21)
+/** Scheduler */
+#define LD_SCHED (1u<<22)
/** Number of logging domains in the code. */
-#define N_LOGGING_DOMAINS 22
+#define N_LOGGING_DOMAINS 23
/** This log message is not safe to send to a callback-based logger
* immediately. Used as a flag, not a log domain. */
diff --git a/src/common/util.c b/src/common/util.c
index 1c35338eef..2f01a83974 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -195,33 +195,40 @@ tor_malloc_zero_(size_t size DMALLOC_PARAMS)
return result;
}
+/* The square root of SIZE_MAX + 1. If a is less than this, and b is less
+ * than this, then a*b is less than SIZE_MAX. (For example, if size_t is
+ * 32 bits, then SIZE_MAX is 0xffffffff and this value is 0x10000. If a and
+ * b are less than this, then their product is at most (65535*65535) ==
+ * 0xfffe0001. */
+#define SQRT_SIZE_MAX_P1 (((size_t)1) << (sizeof(size_t)*4))
+
+/** Return non-zero if and only if the product of the arguments is exact. */
+static INLINE int
+size_mul_check(const size_t x, const size_t y)
+{
+ /* This first check is equivalent to
+ (x < SQRT_SIZE_MAX_P1 && y < SQRT_SIZE_MAX_P1)
+
+ Rationale: if either one of x or y is >= SQRT_SIZE_MAX_P1, then it
+ will have some bit set in its most significant half.
+ */
+ return ((x|y) < SQRT_SIZE_MAX_P1 ||
+ y == 0 ||
+ x <= SIZE_MAX / y);
+}
+
/** Allocate a chunk of <b>nmemb</b>*<b>size</b> bytes of memory, fill
* the memory with zero bytes, and return a pointer to the result.
* Log and terminate the process on error. (Same as
* calloc(<b>nmemb</b>,<b>size</b>), but never returns NULL.)
- *
- * XXXX This implementation probably asserts in cases where it could
- * work, because it only tries dividing SIZE_MAX by size (according to
- * the calloc(3) man page, the size of an element of the nmemb-element
- * array to be allocated), not by nmemb (which could in theory be
- * smaller than size). Don't do that then.
+ * The second argument (<b>size</b>) should preferably be non-zero
+ * and a compile-time constant.
*/
void *
tor_calloc_(size_t nmemb, size_t size DMALLOC_PARAMS)
{
- /* You may ask yourself, "wouldn't it be smart to use calloc instead of
- * malloc+memset? Perhaps libc's calloc knows some nifty optimization trick
- * we don't!" Indeed it does, but its optimizations are only a big win when
- * we're allocating something very big (it knows if it just got the memory
- * from the OS in a pre-zeroed state). We don't want to use tor_malloc_zero
- * for big stuff, so we don't bother with calloc. */
- void *result;
- size_t max_nmemb = (size == 0) ? SIZE_MAX : SIZE_MAX/size;
-
- tor_assert(nmemb < max_nmemb);
-
- result = tor_malloc_zero_((nmemb * size) DMALLOC_FN_ARGS);
- return result;
+ tor_assert(size_mul_check(nmemb, size));
+ return tor_malloc_zero_((nmemb * size) DMALLOC_FN_ARGS);
}
/** Change the size of the memory block pointed to by <b>ptr</b> to <b>size</b>
@@ -264,7 +271,7 @@ 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);
+ tor_assert(size_mul_check(sz1, sz2));
return tor_realloc(ptr, (sz1 * sz2) DMALLOC_FN_ARGS);
}
@@ -957,6 +964,68 @@ string_is_key_value(int severity, const char *string)
return 1;
}
+/** Return true if <b>string</b> represents a valid IPv4 adddress in
+ * 'a.b.c.d' form.
+ */
+int
+string_is_valid_ipv4_address(const char *string)
+{
+ struct in_addr addr;
+
+ return (tor_inet_pton(AF_INET,string,&addr) == 1);
+}
+
+/** Return true if <b>string</b> represents a valid IPv6 address in
+ * a form that inet_pton() can parse.
+ */
+int
+string_is_valid_ipv6_address(const char *string)
+{
+ struct in6_addr addr;
+
+ return (tor_inet_pton(AF_INET6,string,&addr) == 1);
+}
+
+/** Return true iff <b>string</b> matches a pattern of DNS names
+ * that we allow Tor clients to connect to.
+ */
+int
+string_is_valid_hostname(const char *string)
+{
+ int result = 1;
+ smartlist_t *components;
+
+ components = smartlist_new();
+
+ smartlist_split_string(components,string,".",0,0);
+
+ SMARTLIST_FOREACH_BEGIN(components, char *, c) {
+ if (c[0] == '-') {
+ result = 0;
+ break;
+ }
+
+ do {
+ if ((*c >= 'a' && *c <= 'z') ||
+ (*c >= 'A' && *c <= 'Z') ||
+ (*c >= '0' && *c <= '9') ||
+ (*c == '-'))
+ c++;
+ else
+ result = 0;
+ } while (result && *c);
+
+ } SMARTLIST_FOREACH_END(c);
+
+ SMARTLIST_FOREACH_BEGIN(components, char *, c) {
+ tor_free(c);
+ } SMARTLIST_FOREACH_END(c);
+
+ smartlist_free(components);
+
+ return result;
+}
+
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
int
tor_digest256_is_zero(const char *digest)
@@ -1942,8 +2011,12 @@ file_status(const char *fname)
* <b>check</b>&CPD_CHECK, and we think we can create it, return 0. Else
* return -1. If CPD_GROUP_OK is set, then it's okay if the directory
* is group-readable, but in all cases we create the directory mode 0700.
- * If CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions
- * if they are too permissive: we just return -1.
+ * If CPD_GROUP_READ is set, existing directory behaves as CPD_GROUP_OK and
+ * if the directory is created it will use mode 0750 with group read
+ * permission. Group read privileges also assume execute permission
+ * as norm for directories. If CPD_CHECK_MODE_ONLY is set, then we don't
+ * alter the directory permissions if they are too permissive:
+ * we just return -1.
* When effective_user is not NULL, check permissions against the given user
* and its primary group.
*/
@@ -1955,7 +2028,7 @@ check_private_dir(const char *dirname, cpd_check_t check,
struct stat st;
char *f;
#ifndef _WIN32
- int mask;
+ unsigned unwanted_bits = 0;
const struct passwd *pw = NULL;
uid_t running_uid;
gid_t running_gid;
@@ -1980,7 +2053,11 @@ check_private_dir(const char *dirname, cpd_check_t check,
#if defined (_WIN32)
r = mkdir(dirname);
#else
- r = mkdir(dirname, 0700);
+ if (check & CPD_GROUP_READ) {
+ r = mkdir(dirname, 0750);
+ } else {
+ r = mkdir(dirname, 0700);
+ }
#endif
if (r) {
log_warn(LD_FS, "Error creating directory %s: %s", dirname,
@@ -2033,7 +2110,8 @@ check_private_dir(const char *dirname, cpd_check_t check,
tor_free(process_ownername);
return -1;
}
- if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
+ if ( (check & (CPD_GROUP_OK|CPD_GROUP_READ))
+ && (st.st_gid != running_gid) ) {
struct group *gr;
char *process_groupname = NULL;
gr = getgrgid(running_gid);
@@ -2048,12 +2126,12 @@ check_private_dir(const char *dirname, cpd_check_t check,
tor_free(process_groupname);
return -1;
}
- if (check & CPD_GROUP_OK) {
- mask = 0027;
+ if (check & (CPD_GROUP_OK|CPD_GROUP_READ)) {
+ unwanted_bits = 0027;
} else {
- mask = 0077;
+ unwanted_bits = 0077;
}
- if (st.st_mode & mask) {
+ if ((st.st_mode & unwanted_bits) != 0) {
unsigned new_mode;
if (check & CPD_CHECK_MODE_ONLY) {
log_warn(LD_FS, "Permissions on directory %s are too permissive.",
@@ -2063,10 +2141,13 @@ check_private_dir(const char *dirname, cpd_check_t check,
log_warn(LD_FS, "Fixing permissions on directory %s", dirname);
new_mode = st.st_mode;
new_mode |= 0700; /* Owner should have rwx */
- new_mode &= ~mask; /* Clear the other bits that we didn't want set...*/
+ if (check & CPD_GROUP_READ) {
+ new_mode |= 0050; /* Group should have rx */
+ }
+ new_mode &= ~unwanted_bits; /* Clear the bits that we didn't want set...*/
if (chmod(dirname, new_mode)) {
log_warn(LD_FS, "Could not chmod directory %s: %s", dirname,
- strerror(errno));
+ strerror(errno));
return -1;
} else {
return 0;
@@ -3474,8 +3555,9 @@ 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_calloc(sizeof(char),
- (smartlist_len(arg_chars) + (need_quotes ? 2 : 0) + 1));
+ const size_t formatted_arg_len = smartlist_len(arg_chars) +
+ (need_quotes ? 2 : 0) + 1;
+ formatted_arg = tor_malloc_zero(formatted_arg_len);
/* Add leading quote */
i=0;
@@ -5113,7 +5195,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_calloc(sizeof(char *), args_n);
+ argv = tor_calloc(args_n, sizeof(char *));
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 c5471ff9f2..d45dd06741 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -227,6 +227,9 @@ const char *find_str_at_start_of_line(const char *haystack,
const char *needle);
int string_is_C_identifier(const char *string);
int string_is_key_value(int severity, const char *string);
+int string_is_valid_hostname(const char *string);
+int string_is_valid_ipv4_address(const char *string);
+int string_is_valid_ipv6_address(const char *string);
int tor_mem_is_zero(const char *mem, size_t len);
int tor_digest_is_zero(const char *digest);
@@ -344,9 +347,11 @@ typedef unsigned int cpd_check_t;
#define CPD_CREATE 1
#define CPD_CHECK 2
#define CPD_GROUP_OK 4
-#define CPD_CHECK_MODE_ONLY 8
+#define CPD_GROUP_READ 8
+#define CPD_CHECK_MODE_ONLY 16
int check_private_dir(const char *dirname, cpd_check_t check,
const char *effective_user);
+
#define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC)
#define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND)
#define OPEN_FLAGS_DONT_REPLACE (O_CREAT|O_EXCL|O_APPEND|O_WRONLY)