summaryrefslogtreecommitdiffstats
path: root/runtime/reflection.cc
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2014-03-26 15:08:20 -0700
committerJeff Hao <jeffhao@google.com>2014-03-28 14:27:55 -0700
commit11d5d8fffe41cc7daadbfa2ca98ecb978f3029af (patch)
treefae2cf974b502420a942043d135d301aa75967e7 /runtime/reflection.cc
parenta708e32a9f764a48175e705ec4bcd2201c84f492 (diff)
downloadart-11d5d8fffe41cc7daadbfa2ca98ecb978f3029af.zip
art-11d5d8fffe41cc7daadbfa2ca98ecb978f3029af.tar.gz
art-11d5d8fffe41cc7daadbfa2ca98ecb978f3029af.tar.bz2
Add access checks to Method and Field reflection.
Art side of this change. Has a corresponding libcore change. Bug: 13620925 Change-Id: Ie67f802a2a400e8212b489b9a261b7028422d8ba
Diffstat (limited to 'runtime/reflection.cc')
-rw-r--r--runtime/reflection.cc36
1 files changed, 35 insertions, 1 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 7f39e70..b38f9b4 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -26,6 +26,7 @@
#include "mirror/class-inl.h"
#include "mirror/object_array.h"
#include "mirror/object_array-inl.h"
+#include "nth_caller_visitor.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "stack.h"
@@ -461,7 +462,7 @@ void InvokeWithShadowFrame(Thread* self, ShadowFrame* shadow_frame, uint16_t arg
}
jobject InvokeMethod(const ScopedObjectAccess& soa, jobject javaMethod,
- jobject javaReceiver, jobject javaArgs) {
+ jobject javaReceiver, jobject javaArgs, bool accessible) {
mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);
mirror::Class* declaring_class = m->GetDeclaringClass();
@@ -499,6 +500,13 @@ jobject InvokeMethod(const ScopedObjectAccess& soa, jobject javaMethod,
return NULL;
}
+ // Validate access.
+ if (!accessible && !ValidateAccess(receiver, declaring_class, m->GetAccessFlags())) {
+ ThrowIllegalAccessException(nullptr, StringPrintf("Cannot access method: %s",
+ PrettyMethod(m).c_str()).c_str());
+ return nullptr;
+ }
+
// Invoke the method.
JValue result;
ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
@@ -786,4 +794,30 @@ bool UnboxPrimitiveForResult(const ThrowLocation& throw_location, mirror::Object
return UnboxPrimitive(&throw_location, o, dst_class, nullptr, unboxed_value);
}
+bool ValidateAccess(mirror::Object* obj, mirror::Class* declaring_class, uint32_t access_flags) {
+ NthCallerVisitor visitor(Thread::Current(), 2);
+ visitor.WalkStack();
+ mirror::Class* caller_class = visitor.caller->GetDeclaringClass();
+
+ if (((access_flags & kAccPublic) && declaring_class->IsPublic()) ||
+ caller_class == declaring_class) {
+ return true;
+ }
+ if (access_flags & kAccPrivate) {
+ return false;
+ }
+ if (access_flags & kAccProtected) {
+ if (obj != nullptr && !obj->InstanceOf(caller_class) &&
+ !declaring_class->IsInSamePackage(caller_class)) {
+ return false;
+ } else if (declaring_class->IsAssignableFrom(caller_class)) {
+ return true;
+ }
+ }
+ if (!declaring_class->IsInSamePackage(caller_class)) {
+ return false;
+ }
+ return true;
+}
+
} // namespace art