[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Make map_anon expose the result of a noinherit attempt
commit 12205c3cbee4e71ded2b5710a57342b510e9d6df
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Wed Mar 6 10:35:02 2019 -0500
Make map_anon expose the result of a noinherit attempt
Previously we did this for tests only, but it's valuable for getting
proper fork behavior in rand_fast.
---
src/lib/crypt_ops/crypto_rand_fast.c | 4 +--
src/lib/malloc/map_anon.c | 48 ++++++++++++++----------------------
src/lib/malloc/map_anon.h | 17 +++++++++----
src/test/test_util.c | 21 +++++++++-------
4 files changed, 45 insertions(+), 45 deletions(-)
diff --git a/src/lib/crypt_ops/crypto_rand_fast.c b/src/lib/crypt_ops/crypto_rand_fast.c
index 760e1025e..f1acc9faf 100644
--- a/src/lib/crypt_ops/crypto_rand_fast.c
+++ b/src/lib/crypt_ops/crypto_rand_fast.c
@@ -134,8 +134,8 @@ crypto_fast_rng_new_from_seed(const uint8_t *seed)
* having it get dumped, swapped, or shared after fork.
*/
crypto_fast_rng_t *result = tor_mmap_anonymous(sizeof(*result),
- ANONMAP_PRIVATE | ANONMAP_NOINHERIT);
-
+ ANONMAP_PRIVATE | ANONMAP_NOINHERIT,
+ NULL);
memcpy(result->buf.seed, seed, SEED_LEN);
/* Causes an immediate refill once the user asks for data. */
result->bytes_left = 0;
diff --git a/src/lib/malloc/map_anon.c b/src/lib/malloc/map_anon.c
index 5dac5256a..bb0a3d574 100644
--- a/src/lib/malloc/map_anon.c
+++ b/src/lib/malloc/map_anon.c
@@ -107,54 +107,34 @@ nodump_mem(void *mem, size_t sz)
#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
* accessible in child processes -- ideally by having them set to 0 after a
* fork, and if that doesn't work, by having them unmapped after a fork.
* Return 0 on success or if the facility is not available on this OS; return
* -1 on failure.
+ *
+ * If we successfully make the memory uninheritable, adjust the value of
+ * *<b>inherit_result_out</b>.
*/
static int
-noinherit_mem(void *mem, size_t sz)
+noinherit_mem(void *mem, size_t sz, unsigned *inherit_result_out)
{
- set_last_anon_map_noinherit(0);
#ifdef FLAG_ZERO
int r = MINHERIT(mem, sz, FLAG_ZERO);
if (r == 0) {
- set_last_anon_map_noinherit(2);
+ *inherit_result_out = INHERIT_ZERO;
return 0;
}
#endif
#ifdef FLAG_NOINHERIT
int r2 = MINHERIT(mem, sz, FLAG_NOINHERIT);
if (r2 == 0) {
- set_last_anon_map_noinherit(1);
+ *inherit_result_out = INHERIT_DROP;
}
return r2;
#else
+ (void)inherit_result_out;
(void)mem;
(void)sz;
return 0;
@@ -174,14 +154,24 @@ noinherit_mem(void *mem, size_t sz)
* Memory returned from this function must be released with
* tor_munmap_anonymous().
*
+ * If <b>inherit_result_out</b> is non-NULL, set it to one of INHERIT_KEEP,
+ * INHERIT_DROP, and INHERIT_ZERO, depending on the properties of the returned
+ * memory.
+ *
* [Note: OS people use the word "anonymous" here to mean that the memory
* isn't associated with any file. This has *nothing* to do with the kind of
* anonymity that Tor is trying to provide.]
*/
void *
-tor_mmap_anonymous(size_t sz, unsigned flags)
+tor_mmap_anonymous(size_t sz, unsigned flags, unsigned *inherit_result_out)
{
void *ptr;
+ unsigned itmp=0;
+ if (inherit_result_out == NULL) {
+ inherit_result_out = &itmp;
+ }
+ *inherit_result_out = INHERIT_KEEP;
+
#if defined(_WIN32)
HANDLE mapping = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, /*attributes*/
@@ -214,7 +204,7 @@ tor_mmap_anonymous(size_t sz, unsigned flags)
}
if (flags & ANONMAP_NOINHERIT) {
- int noinherit_result = noinherit_mem(ptr, sz);
+ int noinherit_result = noinherit_mem(ptr, sz, inherit_result_out);
raw_assert(noinherit_result == 0);
}
diff --git a/src/lib/malloc/map_anon.h b/src/lib/malloc/map_anon.h
index 395145bd7..edd750082 100644
--- a/src/lib/malloc/map_anon.h
+++ b/src/lib/malloc/map_anon.h
@@ -31,11 +31,18 @@
*/
#define ANONMAP_NOINHERIT (1u<<1)
-void *tor_mmap_anonymous(size_t sz, unsigned flags);
-void tor_munmap_anonymous(void *mapping, size_t sz);
+/** Possible value for inherit_result_out: the memory will be kept
+ * by any child process. */
+#define INHERIT_KEEP 0
+/** Possible value for inherit_result_out: the memory will be dropped in
+ * the child process. Attempting to access it will likely cause a segfault. */
+#define INHERIT_DROP 1
+/** Possible value for inherit_result_out: the memory will be cleared in
+ * the child process. */
+#define INHERIT_ZERO 2
-#ifdef TOR_UNIT_TESTS
-unsigned get_last_anon_map_noinherit(void);
-#endif
+void *tor_mmap_anonymous(size_t sz, unsigned flags,
+ unsigned *inherit_result_out);
+void tor_munmap_anonymous(void *mapping, size_t sz);
#endif /* !defined(TOR_MAP_ANON_H) */
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 4990aa709..039fc435c 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -6130,10 +6130,12 @@ test_util_map_anon(void *arg)
(void)arg;
char *ptr = NULL;
size_t sz = 16384;
+ unsigned inherit=0;
/* Basic checks. */
- ptr = tor_mmap_anonymous(sz, 0);
+ ptr = tor_mmap_anonymous(sz, 0, &inherit);
tt_ptr_op(ptr, OP_NE, 0);
+ tt_int_op(inherit, OP_EQ, INHERIT_KEEP);
ptr[sz-1] = 3;
tt_int_op(ptr[0], OP_EQ, 0);
tt_int_op(ptr[sz-2], OP_EQ, 0);
@@ -6141,8 +6143,9 @@ test_util_map_anon(void *arg)
/* Try again, with a private (non-swappable) mapping. */
tor_munmap_anonymous(ptr, sz);
- ptr = tor_mmap_anonymous(sz, ANONMAP_PRIVATE);
+ ptr = tor_mmap_anonymous(sz, ANONMAP_PRIVATE, &inherit);
tt_ptr_op(ptr, OP_NE, 0);
+ tt_int_op(inherit, OP_EQ, INHERIT_KEEP);
ptr[sz-1] = 10;
tt_int_op(ptr[0], OP_EQ, 0);
tt_int_op(ptr[sz/2], OP_EQ, 0);
@@ -6150,7 +6153,7 @@ test_util_map_anon(void *arg)
/* Now let's test a drop-on-fork mapping. */
tor_munmap_anonymous(ptr, sz);
- ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT);
+ ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
tt_ptr_op(ptr, OP_NE, 0);
ptr[sz-1] = 10;
tt_int_op(ptr[0], OP_EQ, 0);
@@ -6179,10 +6182,10 @@ test_util_map_anon_nofork(void *arg)
char *ptr = NULL;
size_t sz = 16384;
int pipefd[2] = {-1, -1};
+ unsigned inherit=0;
tor_munmap_anonymous(ptr, sz);
- ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT);
- int outcome = get_last_anon_map_noinherit();
+ ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
tt_ptr_op(ptr, OP_NE, 0);
memset(ptr, 0xd0, sz);
@@ -6204,16 +6207,16 @@ test_util_map_anon_nofork(void *arg)
char buf[1];
ssize_t r = read(pipefd[0], buf, 1);
- if (outcome == 2) {
+ if (inherit == INHERIT_ZERO) {
// We should be seeing clear-on-fork behavior.
tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
tt_int_op(buf[0], OP_EQ, 0); // that byte should be zero.
- } else if (outcome == 1) {
+ } else if (inherit == INHERIT_DROP) {
// 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(inherit, OP_EQ, INHERIT_KEEP);
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.
}
@@ -6221,7 +6224,7 @@ test_util_map_anon_nofork(void *arg)
int ws;
waitpid(child, &ws, 0);
- if (outcome == 0) {
+ if (inherit == INHERIT_KEEP) {
/* Call this test "skipped", not "passed", since noinherit wasn't
* implemented. */
tt_skip();
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits