summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/address.c15
-rw-r--r--src/common/address.h1
-rw-r--r--src/common/compat.c85
-rw-r--r--src/common/compat.h4
-rw-r--r--src/common/memarea.c43
-rw-r--r--src/common/tortls.c17
-rw-r--r--src/common/util.c9
7 files changed, 122 insertions, 52 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 3ecc11b90f..cc3e31f65f 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1445,19 +1445,6 @@ get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr)
* XXXX024 IPv6 deprecate some of these.
*/
-/** Return true iff <b>ip</b> (in host order) is an IP reserved to localhost,
- * or reserved for local networks by RFC 1918.
- */
-int
-is_internal_IP(uint32_t ip, int for_listening)
-{
- tor_addr_t myaddr;
- myaddr.family = AF_INET;
- myaddr.addr.in_addr.s_addr = htonl(ip);
-
- return tor_addr_is_internal(&myaddr, for_listening);
-}
-
/** Given an address of the form "ip:port", try to divide it into its
* ip and port portions, setting *<b>address_out</b> to a newly
* allocated string holding the address portion and *<b>port_out</b>
@@ -1585,7 +1572,7 @@ addr_mask_get_bits(uint32_t mask)
return 0;
if (mask == 0xFFFFFFFFu)
return 32;
- for (i=0; i<=32; ++i) {
+ for (i=1; i<=32; ++i) {
if (mask == (uint32_t) ~((1u<<(32-i))-1)) {
return i;
}
diff --git a/src/common/address.h b/src/common/address.h
index d41c2f570f..61de3d2d96 100644
--- a/src/common/address.h
+++ b/src/common/address.h
@@ -215,7 +215,6 @@ int tor_addr_port_parse(int severity, const char *addrport,
int tor_addr_hostname_is_local(const char *name);
/* IPv4 helpers */
-int is_internal_IP(uint32_t ip, int for_listening);
int addr_port_lookup(int severity, const char *addrport, char **address,
uint32_t *addr, uint16_t *port_out);
int parse_port_range(const char *port, uint16_t *port_min_out,
diff --git a/src/common/compat.c b/src/common/compat.c
index 8e2619f846..135f2c9af6 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -35,6 +35,12 @@
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -178,9 +184,10 @@ tor_mmap_file(const char *filename)
{
int fd; /* router file */
char *string;
- int page_size;
+ int page_size, result;
tor_mmap_t *res;
size_t size, filesize;
+ struct stat st;
tor_assert(filename);
@@ -194,9 +201,22 @@ tor_mmap_file(const char *filename)
return NULL;
}
- /* XXXX why not just do fstat here? */
- size = filesize = (size_t) lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
+ /* Get the size of the file */
+ result = fstat(fd, &st);
+ if (result != 0) {
+ int save_errno = errno;
+ log_warn(LD_FS,
+ "Couldn't fstat opened descriptor for \"%s\" during mmap: %s",
+ filename, strerror(errno));
+ close(fd);
+ errno = save_errno;
+ return NULL;
+ }
+ size = filesize = (size_t)(st.st_size);
+ /*
+ * Should we check for weird crap like mmapping a named pipe here,
+ * or just wait for if (!size) below to fail?
+ */
/* ensure page alignment */
page_size = getpagesize();
size += (size%page_size) ? page_size-(size%page_size) : 0;
@@ -227,12 +247,27 @@ tor_mmap_file(const char *filename)
return res;
}
-/** Release storage held for a memory mapping. */
-void
+/** Release storage held for a memory mapping; returns 0 on success,
+ * or -1 on failure (and logs a warning). */
+int
tor_munmap_file(tor_mmap_t *handle)
{
- munmap((char*)handle->data, handle->mapping_size);
- tor_free(handle);
+ int res;
+
+ if (handle == NULL)
+ return 0;
+
+ res = munmap((char*)handle->data, handle->mapping_size);
+ if (res == 0) {
+ /* munmap() succeeded */
+ tor_free(handle);
+ } else {
+ log_warn(LD_FS, "Failed to munmap() in tor_munmap_file(): %s",
+ strerror(errno));
+ res = -1;
+ }
+
+ return res;
}
#elif defined(_WIN32)
tor_mmap_t *
@@ -314,17 +349,29 @@ tor_mmap_file(const char *filename)
tor_munmap_file(res);
return NULL;
}
-void
+
+/* Unmap the file, and return 0 for success or -1 for failure */
+int
tor_munmap_file(tor_mmap_t *handle)
{
- if (handle->data)
+ if (handle == NULL)
+ return 0;
+
+ if (handle->data) {
/* This is an ugly cast, but without it, "data" in struct tor_mmap_t would
have to be redefined as non-const. */
- UnmapViewOfFile( (LPVOID) handle->data);
+ BOOL ok = UnmapViewOfFile( (LPVOID) handle->data);
+ if (!ok) {
+ log_warn(LD_FS, "Failed to UnmapViewOfFile() in tor_munmap_file(): %d",
+ (int)GetLastError());
+ }
+ }
if (handle->mmap_handle != NULL)
CloseHandle(handle->mmap_handle);
tor_free(handle);
+
+ return 0;
}
#else
tor_mmap_t *
@@ -340,13 +387,25 @@ tor_mmap_file(const char *filename)
handle->size = st.st_size;
return handle;
}
-void
+
+/** Unmap the file mapped with tor_mmap_file(), and return 0 for success
+ * or -1 for failure.
+ */
+
+int
tor_munmap_file(tor_mmap_t *handle)
{
- char *d = (char*)handle->data;
+ char *d = NULL;
+ if (handle == NULL)
+ return 0;
+
+ d = (char*)handle->data;
tor_free(d);
memwipe(handle, 0, sizeof(tor_mmap_t));
tor_free(handle);
+
+ /* Can't fail in this mmap()/munmap()-free case */
+ return 0;
}
#endif
diff --git a/src/common/compat.h b/src/common/compat.h
index 32effa5c74..bb88818d82 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -292,7 +292,7 @@ typedef struct tor_mmap_t {
} tor_mmap_t;
tor_mmap_t *tor_mmap_file(const char *filename) ATTR_NONNULL((1));
-void tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1));
+int tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1));
int tor_snprintf(char *str, size_t size, const char *format, ...)
CHECK_PRINTF(3,4) ATTR_NONNULL((1,3));
@@ -321,7 +321,7 @@ tor_memstr(const void *haystack, size_t hlen, const char *needle)
extern const uint32_t TOR_##name##_TABLE[]; \
static INLINE int TOR_##name(char c) { \
uint8_t u = c; \
- return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
+ return !!(TOR_##name##_TABLE[(u >> 5) & 7] & (1u << (u & 31))); \
}
DECLARE_CTYPE_FN(ISALPHA)
DECLARE_CTYPE_FN(ISALNUM)
diff --git a/src/common/memarea.c b/src/common/memarea.c
index 0ae0ccca1d..e2d07fca9e 100644
--- a/src/common/memarea.c
+++ b/src/common/memarea.c
@@ -29,6 +29,13 @@
#error "void* is neither 4 nor 8 bytes long. I don't know how to align stuff."
#endif
+#if defined(__GNUC__) && defined(FLEXIBLE_ARRAY_MEMBER)
+#define USE_ALIGNED_ATTRIBUTE
+#define U_MEM mem
+#else
+#define U_MEM u.mem
+#endif
+
#ifdef USE_SENTINELS
/** Magic value that we stick at the end of a memarea so we can make sure
* there are no run-off-the-end bugs. */
@@ -39,12 +46,12 @@
* end, set those bytes. */
#define SET_SENTINEL(chunk) \
STMT_BEGIN \
- set_uint32( &(chunk)->u.mem[chunk->mem_size], SENTINEL_VAL ); \
+ set_uint32( &(chunk)->U_MEM[chunk->mem_size], SENTINEL_VAL ); \
STMT_END
/** Assert that the sentinel on a memarea is set correctly. */
#define CHECK_SENTINEL(chunk) \
STMT_BEGIN \
- uint32_t sent_val = get_uint32(&(chunk)->u.mem[chunk->mem_size]); \
+ uint32_t sent_val = get_uint32(&(chunk)->U_MEM[chunk->mem_size]); \
tor_assert(sent_val == SENTINEL_VAL); \
STMT_END
#else
@@ -71,19 +78,23 @@ realign_pointer(void *ptr)
typedef struct memarea_chunk_t {
/** Next chunk in this area. Only kept around so we can free it. */
struct memarea_chunk_t *next_chunk;
- size_t mem_size; /**< How much RAM is available in u.mem, total? */
- char *next_mem; /**< Next position in u.mem to allocate data at. If it's
+ size_t mem_size; /**< How much RAM is available in mem, total? */
+ char *next_mem; /**< Next position in mem to allocate data at. If it's
* greater than or equal to mem+mem_size, this chunk is
* full. */
+#ifdef USE_ALIGNED_ATTRIBUTE
+ char mem[FLEXIBLE_ARRAY_MEMBER] __attribute__((aligned(MEMAREA_ALIGN)));
+#else
union {
char mem[1]; /**< Memory space in this chunk. */
void *void_for_alignment_; /**< Dummy; used to make sure mem is aligned. */
} u;
+#endif
} memarea_chunk_t;
/** How many bytes are needed for overhead before we get to the memory part
* of a chunk? */
-#define CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, u)
+#define CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, U_MEM)
/** What's the smallest that we'll allocate a chunk? */
#define CHUNK_SIZE 4096
@@ -121,7 +132,7 @@ alloc_chunk(size_t sz, int freelist_ok)
res = tor_malloc(chunk_size);
res->next_chunk = NULL;
res->mem_size = chunk_size - CHUNK_HEADER_SIZE - SENTINEL_LEN;
- res->next_mem = res->u.mem;
+ res->next_mem = res->U_MEM;
tor_assert(res->next_mem+res->mem_size+SENTINEL_LEN ==
((char*)res)+chunk_size);
tor_assert(realign_pointer(res->next_mem) == res->next_mem);
@@ -140,7 +151,7 @@ chunk_free_unchecked(memarea_chunk_t *chunk)
++freelist_len;
chunk->next_chunk = freelist;
freelist = chunk;
- chunk->next_mem = chunk->u.mem;
+ chunk->next_mem = chunk->U_MEM;
} else {
tor_free(chunk);
}
@@ -183,7 +194,7 @@ memarea_clear(memarea_t *area)
}
area->first->next_chunk = NULL;
}
- area->first->next_mem = area->first->u.mem;
+ area->first->next_mem = area->first->U_MEM;
}
/** Remove all unused memarea chunks from the internal freelist. */
@@ -207,7 +218,7 @@ memarea_owns_ptr(const memarea_t *area, const void *p)
memarea_chunk_t *chunk;
const char *ptr = p;
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
- if (ptr >= chunk->u.mem && ptr < chunk->next_mem)
+ if (ptr >= chunk->U_MEM && ptr < chunk->next_mem)
return 1;
}
return 0;
@@ -226,7 +237,7 @@ memarea_alloc(memarea_t *area, size_t sz)
tor_assert(sz < SIZE_T_CEILING);
if (sz == 0)
sz = 1;
- if (chunk->next_mem+sz > chunk->u.mem+chunk->mem_size) {
+ if (chunk->next_mem+sz > chunk->U_MEM+chunk->mem_size) {
if (sz+CHUNK_HEADER_SIZE >= CHUNK_SIZE) {
/* This allocation is too big. Stick it in a special chunk, and put
* that chunk second in the list. */
@@ -244,8 +255,8 @@ memarea_alloc(memarea_t *area, size_t sz)
result = chunk->next_mem;
chunk->next_mem = chunk->next_mem + sz;
/* Reinstate these if bug 930 ever comes back
- tor_assert(chunk->next_mem >= chunk->u.mem);
- tor_assert(chunk->next_mem <= chunk->u.mem+chunk->mem_size);
+ tor_assert(chunk->next_mem >= chunk->U_MEM);
+ tor_assert(chunk->next_mem <= chunk->U_MEM+chunk->mem_size);
*/
chunk->next_mem = realign_pointer(chunk->next_mem);
return result;
@@ -304,8 +315,8 @@ memarea_get_stats(memarea_t *area, size_t *allocated_out, size_t *used_out)
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
CHECK_SENTINEL(chunk);
a += CHUNK_HEADER_SIZE + chunk->mem_size;
- tor_assert(chunk->next_mem >= chunk->u.mem);
- u += CHUNK_HEADER_SIZE + (chunk->next_mem - chunk->u.mem);
+ tor_assert(chunk->next_mem >= chunk->U_MEM);
+ u += CHUNK_HEADER_SIZE + (chunk->next_mem - chunk->U_MEM);
}
*allocated_out = a;
*used_out = u;
@@ -320,9 +331,9 @@ memarea_assert_ok(memarea_t *area)
for (chunk = area->first; chunk; chunk = chunk->next_chunk) {
CHECK_SENTINEL(chunk);
- tor_assert(chunk->next_mem >= chunk->u.mem);
+ tor_assert(chunk->next_mem >= chunk->U_MEM);
tor_assert(chunk->next_mem <=
- (char*) realign_pointer(chunk->u.mem+chunk->mem_size));
+ (char*) realign_pointer(chunk->U_MEM+chunk->mem_size));
}
}
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 8defab2adb..9ba8fd683e 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -2312,6 +2312,7 @@ log_cert_lifetime(int severity, const X509 *cert, const char *problem)
char mytime[33];
time_t now = time(NULL);
struct tm tm;
+ size_t n;
if (problem)
tor_log(severity, LD_GENERAL,
@@ -2337,11 +2338,17 @@ log_cert_lifetime(int severity, const X509 *cert, const char *problem)
BIO_get_mem_ptr(bio, &buf);
s2 = tor_strndup(buf->data, buf->length);
- strftime(mytime, 32, "%b %d %H:%M:%S %Y UTC", tor_gmtime_r(&now, &tm));
-
- tor_log(severity, LD_GENERAL,
- "(certificate lifetime runs from %s through %s. Your time is %s.)",
- s1,s2,mytime);
+ n = strftime(mytime, 32, "%b %d %H:%M:%S %Y UTC", tor_gmtime_r(&now, &tm));
+ if (n > 0) {
+ tor_log(severity, LD_GENERAL,
+ "(certificate lifetime runs from %s through %s. Your time is %s.)",
+ s1,s2,mytime);
+ } else {
+ tor_log(severity, LD_GENERAL,
+ "(certificate lifetime runs from %s through %s. "
+ "Couldn't get your time.)",
+ s1, s2);
+ }
end:
/* Not expected to get invoked */
diff --git a/src/common/util.c b/src/common/util.c
index a0adb15ffe..a50f2566db 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2141,6 +2141,7 @@ static int
finish_writing_to_file_impl(open_file_t *file_data, int abort_write)
{
int r = 0;
+
tor_assert(file_data && file_data->filename);
if (file_data->stdio_file) {
if (fclose(file_data->stdio_file)) {
@@ -2157,7 +2158,13 @@ finish_writing_to_file_impl(open_file_t *file_data, int abort_write)
if (file_data->rename_on_close) {
tor_assert(file_data->tempname && file_data->filename);
if (abort_write) {
- unlink(file_data->tempname);
+ int res = unlink(file_data->tempname);
+ if (res != 0) {
+ /* We couldn't unlink and we'll leave a mess behind */
+ log_warn(LD_FS, "Failed to unlink %s: %s",
+ file_data->tempname, strerror(errno));
+ r = -1;
+ }
} else {
tor_assert(strcmp(file_data->filename, file_data->tempname));
if (replace_file(file_data->tempname, file_data->filename)) {