diff options
author | Jeff Hao <jeffhao@google.com> | 2014-03-26 15:08:20 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2014-03-28 14:27:55 -0700 |
commit | 11d5d8fffe41cc7daadbfa2ca98ecb978f3029af (patch) | |
tree | fae2cf974b502420a942043d135d301aa75967e7 /runtime/reflection.cc | |
parent | a708e32a9f764a48175e705ec4bcd2201c84f492 (diff) | |
download | art-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.cc | 36 |
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 |