Skip to content

Commit 7039773

Browse files
committed
Unbreak ASan runtime in the simulators.
Summary: 861b69f (rdar://problem/58789439) while fixing symbolization for TSan completely broke ASan's runtime for the simulators. The problem with the previous patch is that the memory passed to `putenv()` was poisoned and when passed to `putenv()` it tripped an interceptor for `strchr()` which saw the memory was poisoned and raised an ASan issue. The memory was poisoned because `AtosSymbolizerProcess` objects are created using ASan's internal allocator. Memory from this allocator gets poisoned with `kAsanInternalHeapMagic`. To workaround this, this patch makes the memory for the environment variable entry a global variable that isn't poisoned. This pass also adds a `DCHECK(getenv(K_ATOS_ENV_VAR))` because the following DCHECK would crash because `internal_strcmp()` doesn't work on nullptr. rdar://problem/62067724 Reviewers: kubamracek, yln Subscribers: #sanitizers, llvm-commits Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D78525
1 parent f0019d4 commit 7039773

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
5353

5454
#define K_ATOS_ENV_VAR "__check_mach_ports_lookup"
5555

56+
// This cannot live in `AtosSymbolizerProcess` because instances of that object
57+
// are allocated by the internal allocator which under ASan is poisoned with
58+
// kAsanInternalHeapMagic.
59+
static char kAtosMachPortEnvEntry[] = K_ATOS_ENV_VAR "=000000000000000";
60+
5661
class AtosSymbolizerProcess : public SymbolizerProcess {
5762
public:
5863
explicit AtosSymbolizerProcess(const char *path)
@@ -69,7 +74,7 @@ class AtosSymbolizerProcess : public SymbolizerProcess {
6974
// We use `putenv()` rather than `setenv()` so that we can later directly
7075
// write into the storage without LibC getting involved to change what the
7176
// variable is set to
72-
int result = putenv(mach_port_env_var_entry_);
77+
int result = putenv(kAtosMachPortEnvEntry);
7378
CHECK_EQ(result, 0);
7479
}
7580
}
@@ -95,12 +100,13 @@ class AtosSymbolizerProcess : public SymbolizerProcess {
95100
// for our task port. We can't call `setenv()` here because it might call
96101
// malloc/realloc. To avoid that we instead update the
97102
// `mach_port_env_var_entry_` variable with our current PID.
98-
uptr count = internal_snprintf(mach_port_env_var_entry_,
99-
sizeof(mach_port_env_var_entry_),
103+
uptr count = internal_snprintf(kAtosMachPortEnvEntry,
104+
sizeof(kAtosMachPortEnvEntry),
100105
K_ATOS_ENV_VAR "=%s", pid_str_);
101106
CHECK_GE(count, sizeof(K_ATOS_ENV_VAR) + internal_strlen(pid_str_));
102107
// Document our assumption but without calling `getenv()` in normal
103108
// builds.
109+
DCHECK(getenv(K_ATOS_ENV_VAR));
104110
DCHECK_EQ(internal_strcmp(getenv(K_ATOS_ENV_VAR), pid_str_), 0);
105111
}
106112

@@ -127,9 +133,10 @@ class AtosSymbolizerProcess : public SymbolizerProcess {
127133
}
128134

129135
char pid_str_[16];
130-
// Space for `\0` in `kAtosEnvVar_` is reused for `=`.
131-
char mach_port_env_var_entry_[sizeof(K_ATOS_ENV_VAR) + sizeof(pid_str_)] =
132-
K_ATOS_ENV_VAR "=0";
136+
// Space for `\0` in `K_ATOS_ENV_VAR` is reused for `=`.
137+
static_assert(sizeof(kAtosMachPortEnvEntry) ==
138+
(sizeof(K_ATOS_ENV_VAR) + sizeof(pid_str_)),
139+
"sizes should match");
133140
};
134141

135142
#undef K_ATOS_ENV_VAR

0 commit comments

Comments
 (0)