-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[compiler-rt][Fuchsia] Change GetMaxUserVirtualAddress to invoke syscall #153309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-compiler-rt-sanitizer Author: None (PiJoules) ChangesLSan was recently refactored to call GetMaxUserVirtualAddress for diagnostic purposes. This leads to failures for some of our downstream tests which only run with lsan. This occurs because GetMaxUserVirtualAddress depends on setting up shadow via a call to __sanitizer_shadow_bounds, but shadow bounds aren't set for standalone lsan because it doesn't use shadow. This updates the function to invoke the same syscall used by __sanitizer_shadow_bounds calls for getting the memory limit. Ideally this function would only be called once since we only need to get the bounds once. More context in https://fxbug.dev/437346226. Full diff: https://github.com/llvm/llvm-project/pull/153309.diff 2 Files Affected:
diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp
index 6876be1dca535..5bdf144723bc7 100644
--- a/compiler-rt/lib/asan/asan_fuchsia.cpp
+++ b/compiler-rt/lib/asan/asan_fuchsia.cpp
@@ -32,11 +32,9 @@ void EarlySanitizerInit() {}
namespace __asan {
-// The system already set up the shadow memory for us.
-// __sanitizer::GetMaxUserVirtualAddress has already been called by
-// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cpp).
-// Just do some additional sanity checks here.
void InitializeShadowMemory() {
+ InitShadowBounds();
+
if (Verbosity())
PrintAddressSpaceLayout();
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
index 625f30ceca1c2..c8250b8135f28 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
@@ -119,9 +119,20 @@ sanitizer_shadow_bounds_t ShadowBounds;
void InitShadowBounds() { ShadowBounds = __sanitizer_shadow_bounds(); }
+// TODO(leonardchan): It's not immediately clear from a user perspective if
+// `GetMaxUserVirtualAddress` should be called exatly once on runtime startup
+// or can be called multiple times. Currently it looks like most instances of
+// `GetMaxUserVirtualAddress` are meant to be called once, but if someone
+// decides to call this multiple times in the future, we should have a separate
+// function that's ok to call multiple times. Ideally we would just invoke this
+// syscall once. Also for Fuchsia, this syscall technically gets invoked twice
+// since `__sanitizer_shadow_bounds` also invokes this syscall under the hood.
uptr GetMaxUserVirtualAddress() {
- InitShadowBounds();
- return ShadowBounds.memory_limit - 1;
+ zx_info_vmar_t info;
+ zx_status_t status = _zx_object_get_info(
+ __zircon_vmar_root_self, ZX_INFO_VMAR, &info, sizeof(info), NULL, NULL);
+ CHECK_EQ(status, ZX_OK);
+ return info.base + info.len - 1;
}
uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); }
|
uptr GetMaxUserVirtualAddress() { | ||
InitShadowBounds(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now what calls InitShadowBounds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see it added above now for asan. As long as that is certainly early enough, this should be OK. It's far from obvious that this is the only place that needs to call this, however. Comments are appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments. This and hwasan are the only places that need this rn, but hwasan already calls this during its init path.
Please clarify in title that change is only for Fuchsia. (P.S. sorry for writing the culprit patch #152428!) |
return ShadowBounds.memory_limit - 1; | ||
zx_info_vmar_t info; | ||
zx_status_t status = _zx_object_get_info( | ||
__zircon_vmar_root_self, ZX_INFO_VMAR, &info, sizeof(info), NULL, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this symbol declared?
It's not part of the Fuchsia libc API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. This should be _zx_vmar_root_self()
.
41fb059
to
0f410ea
Compare
No worries. Updated title |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know any of the Zircon details but LGTM from my perspective on the sanitizers team since this is a Fuchsia-specific change.
LSan was recently refactored to call GetMaxUserVirtualAddress for diagnostic purposes. This leads to failures for some of our downstream tests which only run with lsan. This occurs because GetMaxUserVirtualAddress depends on setting up shadow via a call to __sanitizer_shadow_bounds, but shadow bounds aren't set for standalone lsan because it doesn't use shadow. This updates the function to invoke the same syscall used by __sanitizer_shadow_bounds calls for getting the memory limit. Ideally this function would only be called once since we only need to get the bounds once. More context in https://fxbug.dev/437346226.
@frobtech how does this patch look to you? |
LSan was recently refactored to call GetMaxUserVirtualAddress for diagnostic purposes. This leads to failures for some of our downstream tests which only run with lsan. This occurs because GetMaxUserVirtualAddress depends on setting up shadow via a call to __sanitizer_shadow_bounds, but shadow bounds aren't set for standalone lsan because it doesn't use shadow. This updates the function to invoke the same syscall used by __sanitizer_shadow_bounds calls for getting the memory limit. Ideally this function would only be called once since we only need to get the bounds once.
More context in https://fxbug.dev/437346226.