summaryrefslogtreecommitdiff
path: root/runtime/fault_handler.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2021-11-12 16:27:10 +0000
committer Treehugger Robot <treehugger-gerrit@google.com> 2021-11-15 13:05:59 +0000
commit409d1db74af9605cb8361b1487dd829820473f0f (patch)
tree0d4592801e4f42e2699812a25be7ff95b30f1388 /runtime/fault_handler.cc
parent44a1dc73ad352cb19853cd59b709df82e259cdce (diff)
Add more checks in FaultHandler.
Make the code more robust when thinking it is dealing with an implicit null check. Test: test.py Bug: 170587281 Change-Id: I5e1177377fb2dcee687a9f84693831f7d2de4b67
Diffstat (limited to 'runtime/fault_handler.cc')
-rw-r--r--runtime/fault_handler.cc36
1 files changed, 36 insertions, 0 deletions
diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc
index bc6acec713..66fb3c7b5c 100644
--- a/runtime/fault_handler.cc
+++ b/runtime/fault_handler.cc
@@ -25,8 +25,11 @@
#include "base/safe_copy.h"
#include "base/stl_util.h"
#include "dex/dex_file_types.h"
+#include "jit/jit.h"
+#include "jit/jit_code_cache.h"
#include "mirror/class.h"
#include "mirror/object_reference.h"
+#include "oat_file.h"
#include "oat_quick_method_header.h"
#include "sigchain.h"
#include "thread-current-inl.h"
@@ -265,6 +268,34 @@ void FaultManager::RemoveHandler(FaultHandler* handler) {
LOG(FATAL) << "Attempted to remove non existent handler " << handler;
}
+static bool IsKnownPc(uintptr_t pc, ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
+ // Check whether the pc is within nterp range.
+ if (OatQuickMethodHeader::IsNterpPc(pc)) {
+ return true;
+ }
+
+ // Check whether the pc is in the JIT code cache.
+ jit::Jit* jit = Runtime::Current()->GetJit();
+ if (jit != nullptr && jit->GetCodeCache()->ContainsPc(reinterpret_cast<const void*>(pc))) {
+ return true;
+ }
+
+ if (method->IsObsolete()) {
+ // Obsolete methods never happen on AOT code.
+ return false;
+ }
+
+ // Note: at this point, we trust it's truly an ArtMethod we found at the bottom of the stack,
+ // and we can find its oat file through it.
+ const OatDexFile* oat_dex_file = method->GetDeclaringClass()->GetDexFile().GetOatDexFile();
+ if (oat_dex_file != nullptr &&
+ oat_dex_file->GetOatFile()->Contains(reinterpret_cast<const void*>(pc))) {
+ return true;
+ }
+
+ return false;
+}
+
// This function is called within the signal handler. It checks that
// the mutator_lock is held (shared). No annotalysis is done.
bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool check_dex_pc) {
@@ -329,6 +360,11 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che
return false;
}
+ if (!IsKnownPc(return_pc, method_obj)) {
+ VLOG(signals) << "PC not in Java code";
+ return false;
+ }
+
const OatQuickMethodHeader* method_header = method_obj->GetOatQuickMethodHeader(return_pc);
if (method_header == nullptr) {