< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
rev 52360 : 8212605: Pure-Java implementation of AccessController.doPrivileged

*** 53,63 **** #include "oops/oop.inline.hpp" #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" #include "prims/nativeLookup.hpp" - #include "prims/privilegedStack.hpp" #include "prims/stackwalk.hpp" #include "runtime/arguments.hpp" #include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" --- 53,62 ----
*** 1164,1322 **** oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); return (jobject) JNIHandles::make_local(env, pd); JVM_END - static bool is_authorized(Handle context, InstanceKlass* klass, TRAPS) { - // If there is a security manager and protection domain, check the access - // in the protection domain, otherwise it is authorized. - if (java_lang_System::has_security_manager()) { - - // For bootstrapping, if pd implies method isn't in the JDK, allow - // this context to revert to older behavior. - // In this case the isAuthorized field in AccessControlContext is also not - // present. - if (Universe::protection_domain_implies_method() == NULL) { - return true; - } - - // Whitelist certain access control contexts - if (java_security_AccessControlContext::is_authorized(context)) { - return true; - } - - oop prot = klass->protection_domain(); - if (prot != NULL) { - // Call pd.implies(new SecurityPermission("createAccessControlContext")) - // in the new wrapper. - methodHandle m(THREAD, Universe::protection_domain_implies_method()); - Handle h_prot(THREAD, prot); - JavaValue result(T_BOOLEAN); - JavaCallArguments args(h_prot); - JavaCalls::call(&result, m, &args, CHECK_false); - return (result.get_jboolean() != 0); - } - } - return true; - } - - // Create an AccessControlContext with a protection domain with null codesource - // and null permissions - which gives no permissions. - oop create_dummy_access_control_context(TRAPS) { - InstanceKlass* pd_klass = SystemDictionary::ProtectionDomain_klass(); - // Call constructor ProtectionDomain(null, null); - Handle obj = JavaCalls::construct_new_instance(pd_klass, - vmSymbols::codesource_permissioncollection_signature(), - Handle(), Handle(), CHECK_NULL); - - // new ProtectionDomain[] {pd}; - objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); - context->obj_at_put(0, obj()); - - // new AccessControlContext(new ProtectionDomain[] {pd}) - objArrayHandle h_context(THREAD, context); - oop acc = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); - return acc; - } - - JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) - JVMWrapper("JVM_DoPrivileged"); - - if (action == NULL) { - THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); - } - - // Compute the frame initiating the do privileged operation and setup the privileged stack - vframeStream vfst(thread); - vfst.security_get_caller_frame(1); - - if (vfst.at_end()) { - THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?"); - } - - Method* method = vfst.method(); - InstanceKlass* klass = method->method_holder(); - - // Check that action object understands "Object run()" - Handle h_context; - if (context != NULL) { - h_context = Handle(THREAD, JNIHandles::resolve(context)); - bool authorized = is_authorized(h_context, klass, CHECK_NULL); - if (!authorized) { - // Create an unprivileged access control object and call it's run function - // instead. - oop noprivs = create_dummy_access_control_context(CHECK_NULL); - h_context = Handle(THREAD, noprivs); - } - } - - // Check that action object understands "Object run()" - Handle object (THREAD, JNIHandles::resolve(action)); - - // get run() method - Method* m_oop = object->klass()->uncached_lookup_method( - vmSymbols::run_method_name(), - vmSymbols::void_object_signature(), - Klass::find_overpass); - - // See if there is a default method for "Object run()". - if (m_oop == NULL && object->klass()->is_instance_klass()) { - InstanceKlass* iklass = InstanceKlass::cast(object->klass()); - m_oop = iklass->lookup_method_in_ordered_interfaces( - vmSymbols::run_method_name(), - vmSymbols::void_object_signature()); - } - - methodHandle m (THREAD, m_oop); - if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static() || m()->is_abstract()) { - THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); - } - - // Stack allocated list of privileged stack elements - PrivilegedElement pi; - if (!vfst.at_end()) { - pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); - thread->set_privileged_stack_top(&pi); - } - - - // invoke the Object run() in the action object. We cannot use call_interface here, since the static type - // is not really known - it is either java.security.PrivilegedAction or java.security.PrivilegedExceptionAction - Handle pending_exception; - JavaValue result(T_OBJECT); - JavaCallArguments args(object); - JavaCalls::call(&result, m, &args, THREAD); - - // done with action, remove ourselves from the list - if (!vfst.at_end()) { - assert(thread->privileged_stack_top() != NULL && thread->privileged_stack_top() == &pi, "wrong top element"); - thread->set_privileged_stack_top(thread->privileged_stack_top()->next()); - } - - if (HAS_PENDING_EXCEPTION) { - pending_exception = Handle(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - // JVMTI has already reported the pending exception - // JVMTI internal flag reset is needed in order to report PrivilegedActionException - if (THREAD->is_Java_thread()) { - JvmtiExport::clear_detected_exception((JavaThread*) THREAD); - } - if ( pending_exception->is_a(SystemDictionary::Exception_klass()) && - !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { - // Throw a java.security.PrivilegedActionException(Exception e) exception - JavaCallArguments args(pending_exception); - THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(), - vmSymbols::exception_void_signature(), - &args); - } - } - - if (pending_exception.not_null()) THROW_OOP_0(pending_exception()); - return JNIHandles::make_local(env, (oop) result.get_jobject()); - JVM_END - - // Returns the inherited_access_control_context field of the running thread. JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)) JVMWrapper("JVM_GetInheritedAccessControlContext"); oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj()); return JNIHandles::make_local(env, result); --- 1163,1172 ----
*** 1347,1375 **** // count the protection domains on the execution stack. We collapse // duplicate consecutive protection domains into a single one, as // well as stopping when we hit a privileged frame. - // Use vframeStream to iterate through Java frames - vframeStream vfst(thread); - oop previous_protection_domain = NULL; Handle privileged_context(thread, NULL); bool is_privileged = false; oop protection_domain = NULL; ! for(; !vfst.at_end(); vfst.next()) { // get method of frame ! Method* method = vfst.method(); ! intptr_t* frame_id = vfst.frame_id(); ! // check the privileged frames to see if we have a match ! if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) { // this frame is privileged is_privileged = true; ! privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context()); ! protection_domain = thread->privileged_stack_top()->protection_domain(); } else { protection_domain = method->method_holder()->protection_domain(); } if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) { --- 1197,1235 ---- // count the protection domains on the execution stack. We collapse // duplicate consecutive protection domains into a single one, as // well as stopping when we hit a privileged frame. oop previous_protection_domain = NULL; Handle privileged_context(thread, NULL); bool is_privileged = false; oop protection_domain = NULL; ! // Iterate through Java frames ! RegisterMap reg_map(thread); ! javaVFrame *vf = thread->last_java_vframe(&reg_map); ! for (; vf != NULL; vf = vf->java_sender()) { // get method of frame ! Method* method = vf->method(); ! // stop at the first privileged frame ! if (method->method_holder() == SystemDictionary::AccessController_klass() && ! method->name() == vmSymbols::executePrivileged_name()) ! { // this frame is privileged is_privileged = true; ! ! javaVFrame *priv = vf; // executePrivileged ! javaVFrame *caller_fr = priv->java_sender(); // doPrivileged ! caller_fr = caller_fr->java_sender(); // caller ! ! StackValueCollection* locals = priv->locals(); ! privileged_context = locals->obj_at(1); ! Handle caller = locals->obj_at(2); ! ! Klass *caller_klass = java_lang_Class::as_Klass(caller()); ! protection_domain = caller_klass->protection_domain(); } else { protection_domain = method->method_holder()->protection_domain(); } if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) {
< prev index next >