Merge branch 'tor-github/pr/723'

This commit is contained in:
George Kadianakis 2019-03-04 18:55:28 +02:00
commit c5da1f1cd5
3 changed files with 61 additions and 11 deletions

View File

@ -107,6 +107,29 @@ nodump_mem(void *mem, size_t sz)
#endif #endif
} }
#ifdef TOR_UNIT_TESTS
static unsigned last_anon_map_noinherit = ~0;
/* Testing helper: return the outcome of the last call to noinherit_mem():
* 0 if it did no good; 1 if it caused the memory not to be inherited, and
* 2 if it caused the memory to be cleared on fork */
unsigned
get_last_anon_map_noinherit(void)
{
return last_anon_map_noinherit;
}
static void
set_last_anon_map_noinherit(unsigned f)
{
last_anon_map_noinherit = f;
}
#else
static void
set_last_anon_map_noinherit(unsigned f)
{
(void)f;
}
#endif
/** /**
* Helper: try to prevent the <b>sz</b> bytes at <b>mem</b> from being * Helper: try to prevent the <b>sz</b> bytes at <b>mem</b> from being
* accessible in child processes -- ideally by having them set to 0 after a * accessible in child processes -- ideally by having them set to 0 after a
@ -117,13 +140,20 @@ nodump_mem(void *mem, size_t sz)
static int static int
noinherit_mem(void *mem, size_t sz) noinherit_mem(void *mem, size_t sz)
{ {
set_last_anon_map_noinherit(0);
#ifdef FLAG_ZERO #ifdef FLAG_ZERO
int r = MINHERIT(mem, sz, FLAG_ZERO); int r = MINHERIT(mem, sz, FLAG_ZERO);
if (r == 0) if (r == 0) {
set_last_anon_map_noinherit(2);
return 0; return 0;
}
#endif #endif
#ifdef FLAG_NOINHERIT #ifdef FLAG_NOINHERIT
return MINHERIT(mem, sz, FLAG_NOINHERIT); int r2 = MINHERIT(mem, sz, FLAG_NOINHERIT);
if (r2 == 0) {
set_last_anon_map_noinherit(1);
}
return r2;
#else #else
(void)mem; (void)mem;
(void)sz; (void)sz;

View File

@ -34,4 +34,8 @@
void *tor_mmap_anonymous(size_t sz, unsigned flags); void *tor_mmap_anonymous(size_t sz, unsigned flags);
void tor_munmap_anonymous(void *mapping, size_t sz); void tor_munmap_anonymous(void *mapping, size_t sz);
#ifdef TOR_UNIT_TESTS
unsigned get_last_anon_map_noinherit(void);
#endif
#endif /* !defined(TOR_MAP_ANON_H) */ #endif /* !defined(TOR_MAP_ANON_H) */

View File

@ -6165,8 +6165,8 @@ static void
test_util_map_anon_nofork(void *arg) test_util_map_anon_nofork(void *arg)
{ {
(void)arg; (void)arg;
#if !defined(HAVE_MADVISE) && !defined(HAVE_MINHERIT) #ifdef _WIN32
/* The operating system doesn't support this. */ /* The operating system doesn't support forking. */
tt_skip(); tt_skip();
done: done:
; ;
@ -6182,6 +6182,7 @@ test_util_map_anon_nofork(void *arg)
tor_munmap_anonymous(ptr, sz); tor_munmap_anonymous(ptr, sz);
ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT); ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT);
int outcome = get_last_anon_map_noinherit();
tt_ptr_op(ptr, OP_NE, 0); tt_ptr_op(ptr, OP_NE, 0);
memset(ptr, 0xd0, sz); memset(ptr, 0xd0, sz);
@ -6202,15 +6203,30 @@ test_util_map_anon_nofork(void *arg)
pipefd[1] = -1; pipefd[1] = -1;
char buf[1]; char buf[1];
ssize_t r = read(pipefd[0], buf, 1); ssize_t r = read(pipefd[0], buf, 1);
#if defined(INHERIT_ZERO) || defined(MADV_WIPEONFORK)
tt_int_op((int)r, OP_EQ, 1); // child should send us a byte. if (outcome == 2) {
tt_int_op(buf[0], OP_EQ, 0); // We should be seeing clear-on-fork behavior.
#else tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
tt_int_op(r, OP_LE, 0); // child said nothing; it should have crashed. tt_int_op(buf[0], OP_EQ, 0); // that byte should be zero.
#endif } else if (outcome == 1) {
// We should be seeing noinherit behavior.
tt_int_op(r, OP_LE, 0); // child said nothing; it should have crashed.
} else {
// noinherit isn't implemented.
tt_int_op(outcome, OP_EQ, 0);
tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
tt_int_op(buf[0], OP_EQ, 0xd0); // that byte should what we set it to.
}
int ws; int ws;
waitpid(child, &ws, 0); waitpid(child, &ws, 0);
if (outcome == 0) {
/* Call this test "skipped", not "passed", since noinherit wasn't
* implemented. */
tt_skip();
}
done: done:
tor_munmap_anonymous(ptr, sz); tor_munmap_anonymous(ptr, sz);
if (pipefd[0] >= 0) { if (pipefd[0] >= 0) {
@ -6360,6 +6376,6 @@ struct testcase_t util_tests[] = {
UTIL_TEST(get_unquoted_path, 0), UTIL_TEST(get_unquoted_path, 0),
UTIL_TEST(log_mallinfo, 0), UTIL_TEST(log_mallinfo, 0),
UTIL_TEST(map_anon, 0), UTIL_TEST(map_anon, 0),
UTIL_TEST(map_anon_nofork, TT_SKIP /* See bug #29535 */), UTIL_TEST(map_anon_nofork, 0),
END_OF_TESTCASES END_OF_TESTCASES
}; };