Mercurial > hg > truffle
diff src/share/vm/prims/jvm.cpp @ 11198:1e6d5dec4a4e
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 05 Aug 2013 13:20:06 +0200 |
parents | e636d62005c3 |
children | cefad50507d8 |
line wrap: on
line diff
--- a/src/share/vm/prims/jvm.cpp Thu Aug 01 21:34:57 2013 +0200 +++ b/src/share/vm/prims/jvm.cpp Mon Aug 05 13:20:06 2013 +0200 @@ -1122,27 +1122,68 @@ return (jobject) JNIHandles::make_local(env, pd); JVM_END - -// Obsolete since 1.2 (Class.setProtectionDomain removed), although -// still defined in core libraries as of 1.5. +// Preserved in Graal repo so that linking against a JDK7 libjava.so works JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) JVMWrapper("JVM_SetProtectionDomain"); - if (JNIHandles::resolve(cls) == NULL) { - THROW(vmSymbols::java_lang_NullPointerException()); - } - if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { - // Call is ignored for primitive types - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); - - // cls won't be an array, as this called only from ClassLoader.defineClass - if (k->oop_is_instance()) { - oop pd = JNIHandles::resolve(protection_domain); - assert(pd == NULL || pd->is_oop(), "just checking"); - java_lang_Class::set_protection_domain(k->java_mirror(), pd); + + ResourceMark rm(THREAD); + const char* msg = "Obsolete JVM_SetProtectionDomain function called"; + size_t buflen = strlen(msg); + char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); + jio_snprintf(buf, buflen, msg); + THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); +JVM_END + +static bool is_authorized(Handle context, instanceKlassHandle 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); } } -JVM_END - + 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 = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass()); + // new ProtectionDomain(null,null); + oop null_protection_domain = pd_klass->allocate_instance(CHECK_NULL); + Handle null_pd(THREAD, null_protection_domain); + + // new ProtectionDomain[] {pd}; + objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); + context->obj_at_put(0, null_pd()); + + // new AccessControlContext(new ProtectionDomain[] {pd}) + objArrayHandle h_context(THREAD, context); + oop result = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); + return result; +} JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) JVMWrapper("JVM_DoPrivileged"); @@ -1151,8 +1192,29 @@ THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); } - // Stack allocated list of privileged stack elements - PrivilegedElement pi; + // 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(); + instanceKlassHandle klass (THREAD, 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)); @@ -1166,12 +1228,10 @@ THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); } - // Compute the frame initiating the do privileged operation and setup the privileged stack - vframeStream vfst(thread); - vfst.security_get_caller_frame(1); - + // Stack allocated list of privileged stack elements + PrivilegedElement pi; if (!vfst.at_end()) { - pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL); + pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); thread->set_privileged_stack_top(&pi); } @@ -3243,24 +3303,10 @@ JVM_END -// Utility object for collecting method holders walking down the stack -class KlassLink: public ResourceObj { - public: - KlassHandle klass; - KlassLink* next; - - KlassLink(KlassHandle k) { klass = k; next = NULL; } -}; - - JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) JVMWrapper("JVM_GetClassContext"); ResourceMark rm(THREAD); JvmtiVMObjectAllocEventCollector oam; - // Collect linked list of (handles to) method holders - KlassLink* first = NULL; - KlassLink* last = NULL; - int depth = 0; vframeStream vfst(thread); if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { @@ -3274,32 +3320,23 @@ } // Collect method holders + GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>(); for (; !vfst.at_end(); vfst.security_next()) { Method* m = vfst.method(); // Native frames are not returned if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { Klass* holder = m->method_holder(); assert(holder->is_klass(), "just checking"); - depth++; - KlassLink* l = new KlassLink(KlassHandle(thread, holder)); - if (first == NULL) { - first = last = l; - } else { - last->next = l; - last = l; - } + klass_array->append(holder); } } // Create result array of type [Ljava/lang/Class; - objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), depth, CHECK_NULL); + objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL); // Fill in mirrors corresponding to method holders - int index = 0; - while (first != NULL) { - result->obj_at_put(index++, first->klass()->java_mirror()); - first = first->next; + for (int i = 0; i < klass_array->length(); i++) { + result->obj_at_put(i, klass_array->at(i)->java_mirror()); } - assert(index == depth, "just checking"); return (jobjectArray) JNIHandles::make_local(env, result); JVM_END