Add capability checks to all functions.
Also ensure that we declare all capabilities we support.
Bug: 31684920
Bug: 31455788
Test: mma -j40 test-art-host
Change-Id: Ic3f251f451cf6dad9934109594652f23d228d0f4
diff --git a/runtime/openjdkjvmti/events.cc b/runtime/openjdkjvmti/events.cc
index 1da08a0..34492a9 100644
--- a/runtime/openjdkjvmti/events.cc
+++ b/runtime/openjdkjvmti/events.cc
@@ -302,6 +302,64 @@
}
}
+// Checks to see if the env has the capabilities associated with the given event.
+static bool HasAssociatedCapability(ArtJvmTiEnv* env,
+ ArtJvmtiEvent event) {
+ jvmtiCapabilities caps = env->capabilities;
+ switch (event) {
+ case ArtJvmtiEvent::kBreakpoint:
+ return caps.can_generate_breakpoint_events == 1;
+
+ case ArtJvmtiEvent::kCompiledMethodLoad:
+ case ArtJvmtiEvent::kCompiledMethodUnload:
+ return caps.can_generate_compiled_method_load_events == 1;
+
+ case ArtJvmtiEvent::kException:
+ case ArtJvmtiEvent::kExceptionCatch:
+ return caps.can_generate_exception_events == 1;
+
+ case ArtJvmtiEvent::kFieldAccess:
+ return caps.can_generate_field_access_events == 1;
+
+ case ArtJvmtiEvent::kFieldModification:
+ return caps.can_generate_field_modification_events == 1;
+
+ case ArtJvmtiEvent::kFramePop:
+ return caps.can_generate_frame_pop_events == 1;
+
+ case ArtJvmtiEvent::kGarbageCollectionStart:
+ case ArtJvmtiEvent::kGarbageCollectionFinish:
+ return caps.can_generate_garbage_collection_events == 1;
+
+ case ArtJvmtiEvent::kMethodEntry:
+ return caps.can_generate_method_entry_events == 1;
+
+ case ArtJvmtiEvent::kMethodExit:
+ return caps.can_generate_method_exit_events == 1;
+
+ case ArtJvmtiEvent::kMonitorContendedEnter:
+ case ArtJvmtiEvent::kMonitorContendedEntered:
+ case ArtJvmtiEvent::kMonitorWait:
+ case ArtJvmtiEvent::kMonitorWaited:
+ return caps.can_generate_monitor_events == 1;
+
+ case ArtJvmtiEvent::kNativeMethodBind:
+ return caps.can_generate_native_method_bind_events == 1;
+
+ case ArtJvmtiEvent::kObjectFree:
+ return caps.can_generate_object_free_events == 1;
+
+ case ArtJvmtiEvent::kSingleStep:
+ return caps.can_generate_single_step_events == 1;
+
+ case ArtJvmtiEvent::kVmObjectAlloc:
+ return caps.can_generate_vm_object_alloc_events == 1;
+
+ default:
+ return true;
+ }
+}
+
jvmtiError EventHandler::SetEvent(ArtJvmTiEnv* env,
art::Thread* thread,
ArtJvmtiEvent event,
@@ -318,8 +376,6 @@
}
}
- // TODO: Capability check.
-
if (mode != JVMTI_ENABLE && mode != JVMTI_DISABLE) {
return ERR(ILLEGAL_ARGUMENT);
}
@@ -328,6 +384,10 @@
return ERR(INVALID_EVENT_TYPE);
}
+ if (!HasAssociatedCapability(env, event)) {
+ return ERR(MUST_POSSESS_CAPABILITY);
+ }
+
bool old_state = global_mask.Test(event);
if (mode == JVMTI_ENABLE) {