mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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.
This commit is contained in:
+19
-29
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,18 @@
|
||||
*/
|
||||
#define ANONMAP_NOINHERIT (1u<<1)
|
||||
|
||||
void *tor_mmap_anonymous(size_t sz, unsigned flags);
|
||||
/** 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
|
||||
|
||||
void *tor_mmap_anonymous(size_t sz, unsigned flags,
|
||||
unsigned *inherit_result_out);
|
||||
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) */
|
||||
|
||||
Reference in New Issue
Block a user