Merge branch 'disable_memory_sentinels_squashed'

This commit is contained in:
Nick Mathewson 2017-02-27 16:25:25 -05:00
commit c0aa7ac5ac
5 changed files with 121 additions and 1 deletions

7
changes/bug21439 Normal file
View File

@ -0,0 +1,7 @@
o Minor features (testing):
- Add a "--disable-memory-sentinels" feature to help with fuzzing.
When Tor is compiled with this option, we disable a number of
redundant memory-safety failsafes that are intended to stop
bugs from becoming security issues. This makes it easier to hunt
for bugs that would be security issues without the failsafes
turned on. Closes ticket 21439.

View File

@ -53,6 +53,8 @@ AC_ARG_ENABLE(libfuzzer,
AS_HELP_STRING(--enable-libfuzzer, [build extra fuzzers based on 'libfuzzer']))
AC_ARG_ENABLE(oss-fuzz,
AS_HELP_STRING(--enable-oss-fuzz, [build extra fuzzers based on 'oss-fuzz' environment]))
AC_ARG_ENABLE(memory-sentinels,
AS_HELP_STRING(--disable-memory-sentinels, [disable code that tries to prevent some kinds of memory access bugs. For fuzzing only.]))
if test "x$enable_coverage" != "xyes" -a "x$enable_asserts_in_tests" = "xno" ; then
AC_MSG_ERROR([Can't disable assertions outside of coverage build])
@ -76,6 +78,11 @@ if test "$enable_system_torrc" = "no"; then
[Defined if we're not going to look for a torrc in SYSCONF])
fi
if test "$enable_memory_sentinels" = "no"; then
AC_DEFINE(DISABLE_MEMORY_SENTINELS, 1,
[Defined if we're turning off memory safety code to look for bugs])
fi
AM_CONDITIONAL(USE_OPENBSD_MALLOC, test "x$enable_openbsd_malloc" = "xyes")
AC_ARG_ENABLE(asciidoc,

View File

@ -12,6 +12,9 @@
#include "util.h"
#include "compat.h"
#include "torlog.h"
#include "container.h"
#ifndef DISABLE_MEMORY_SENTINELS
/** If true, we try to detect any attempts to write beyond the length of a
* memarea. */
@ -304,3 +307,91 @@ memarea_assert_ok(memarea_t *area)
}
}
#else
struct memarea_t {
smartlist_t *pieces;
};
memarea_t *
memarea_new(void)
{
memarea_t *ma = tor_malloc_zero(sizeof(memarea_t));
ma->pieces = smartlist_new();
return ma;
}
void
memarea_drop_all(memarea_t *area)
{
memarea_clear(area);
smartlist_free(area->pieces);
tor_free(area);
}
void
memarea_clear(memarea_t *area)
{
SMARTLIST_FOREACH(area->pieces, void *, p, tor_free_(p));
smartlist_clear(area->pieces);
}
int
memarea_owns_ptr(const memarea_t *area, const void *ptr)
{
SMARTLIST_FOREACH(area->pieces, const void *, p, if (ptr == p) return 1;);
return 0;
}
void *
memarea_alloc(memarea_t *area, size_t sz)
{
void *result = tor_malloc(sz);
smartlist_add(area->pieces, result);
return result;
}
void *
memarea_alloc_zero(memarea_t *area, size_t sz)
{
void *result = tor_malloc_zero(sz);
smartlist_add(area->pieces, result);
return result;
}
void *
memarea_memdup(memarea_t *area, const void *s, size_t n)
{
void *r = memarea_alloc(area, n);
memcpy(r, s, n);
return r;
}
char *
memarea_strdup(memarea_t *area, const char *s)
{
size_t n = strlen(s);
char *r = memarea_alloc(area, n+1);
memcpy(r, s, n);
r[n] = 0;
return r;
}
char *
memarea_strndup(memarea_t *area, const char *s, size_t n)
{
size_t ln = strnlen(s, n);
char *r = memarea_alloc(area, ln+1);
memcpy(r, s, ln);
r[ln] = 0;
return r;
}
void
memarea_get_stats(memarea_t *area,
size_t *allocated_out, size_t *used_out)
{
(void)area;
*allocated_out = *used_out = 128;
}
void
memarea_assert_ok(memarea_t *area)
{
(void)area;
}
#endif

View File

@ -83,7 +83,11 @@ static int parse_socks_client(const uint8_t *data, size_t datalen,
#define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0])
/* We leave this many NUL bytes at the end of the buffer. */
#ifdef DISABLE_MEMORY_SENTINELS
#define SENTINEL_LEN 0
#else
#define SENTINEL_LEN 4
#endif
/* Header size plus NUL bytes at the end */
#define CHUNK_OVERHEAD (CHUNK_HEADER_LEN + SENTINEL_LEN)
@ -97,18 +101,22 @@ static int parse_socks_client(const uint8_t *data, size_t datalen,
#define DEBUG_SENTINEL
#ifdef DEBUG_SENTINEL
#if defined(DEBUG_SENTINEL) && !defined(DISABLE_MEMORY_SENTINELS)
#define DBG_S(s) s
#else
#define DBG_S(s) (void)0
#endif
#ifdef DISABLE_MEMORY_SENTINELS
#define CHUNK_SET_SENTINEL(chunk, alloclen) STMT_NIL
#else
#define CHUNK_SET_SENTINEL(chunk, alloclen) do { \
uint8_t *a = (uint8_t*) &(chunk)->mem[(chunk)->memlen]; \
DBG_S(uint8_t *b = &((uint8_t*)(chunk))[(alloclen)-SENTINEL_LEN]); \
DBG_S(tor_assert(a == b)); \
memset(a,0,SENTINEL_LEN); \
} while (0)
#endif
/** Return the next character in <b>chunk</b> onto which data can be appended.
* If the chunk is full, this might be off the end of chunk->mem. */

View File

@ -3340,6 +3340,13 @@ test_util_memarea(void *arg)
void *malloced_ptr = NULL;
int i;
#ifdef DISABLE_MEMORY_SENTINELS
/* If memory sentinels are disabled, this whole module is just an alias for
malloc(), which is free to lay out memory most any way it wants. */
if (1)
tt_skip();
#endif
(void)arg;
tt_assert(area);