Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/jvm.cpp @ 11173:6b0fd0964b87
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 31 Jul 2013 11:00:54 +0200 |
parents | e376b764fdc7 ba9dacff9c9d |
children | e636d62005c3 |
comparison
equal
deleted
inserted
replaced
10912:4ea54634f03e | 11173:6b0fd0964b87 |
---|---|
1121 oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); | 1121 oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); |
1122 return (jobject) JNIHandles::make_local(env, pd); | 1122 return (jobject) JNIHandles::make_local(env, pd); |
1123 JVM_END | 1123 JVM_END |
1124 | 1124 |
1125 | 1125 |
1126 // Obsolete since 1.2 (Class.setProtectionDomain removed), although | 1126 static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) { |
1127 // still defined in core libraries as of 1.5. | 1127 // If there is a security manager and protection domain, check the access |
1128 JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) | 1128 // in the protection domain, otherwise it is authorized. |
1129 JVMWrapper("JVM_SetProtectionDomain"); | 1129 if (java_lang_System::has_security_manager()) { |
1130 if (JNIHandles::resolve(cls) == NULL) { | 1130 |
1131 THROW(vmSymbols::java_lang_NullPointerException()); | 1131 // For bootstrapping, if pd implies method isn't in the JDK, allow |
1132 } | 1132 // this context to revert to older behavior. |
1133 if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | 1133 // In this case the isAuthorized field in AccessControlContext is also not |
1134 // Call is ignored for primitive types | 1134 // present. |
1135 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); | 1135 if (Universe::protection_domain_implies_method() == NULL) { |
1136 | 1136 return true; |
1137 // cls won't be an array, as this called only from ClassLoader.defineClass | 1137 } |
1138 if (k->oop_is_instance()) { | 1138 |
1139 oop pd = JNIHandles::resolve(protection_domain); | 1139 // Whitelist certain access control contexts |
1140 assert(pd == NULL || pd->is_oop(), "just checking"); | 1140 if (java_security_AccessControlContext::is_authorized(context)) { |
1141 java_lang_Class::set_protection_domain(k->java_mirror(), pd); | 1141 return true; |
1142 } | 1142 } |
1143 } | 1143 |
1144 JVM_END | 1144 oop prot = klass->protection_domain(); |
1145 | 1145 if (prot != NULL) { |
1146 // Call pd.implies(new SecurityPermission("createAccessControlContext")) | |
1147 // in the new wrapper. | |
1148 methodHandle m(THREAD, Universe::protection_domain_implies_method()); | |
1149 Handle h_prot(THREAD, prot); | |
1150 JavaValue result(T_BOOLEAN); | |
1151 JavaCallArguments args(h_prot); | |
1152 JavaCalls::call(&result, m, &args, CHECK_false); | |
1153 return (result.get_jboolean() != 0); | |
1154 } | |
1155 } | |
1156 return true; | |
1157 } | |
1158 | |
1159 // Create an AccessControlContext with a protection domain with null codesource | |
1160 // and null permissions - which gives no permissions. | |
1161 oop create_dummy_access_control_context(TRAPS) { | |
1162 InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass()); | |
1163 // new ProtectionDomain(null,null); | |
1164 oop null_protection_domain = pd_klass->allocate_instance(CHECK_NULL); | |
1165 Handle null_pd(THREAD, null_protection_domain); | |
1166 | |
1167 // new ProtectionDomain[] {pd}; | |
1168 objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); | |
1169 context->obj_at_put(0, null_pd()); | |
1170 | |
1171 // new AccessControlContext(new ProtectionDomain[] {pd}) | |
1172 objArrayHandle h_context(THREAD, context); | |
1173 oop result = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); | |
1174 return result; | |
1175 } | |
1146 | 1176 |
1147 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) | 1177 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) |
1148 JVMWrapper("JVM_DoPrivileged"); | 1178 JVMWrapper("JVM_DoPrivileged"); |
1149 | 1179 |
1150 if (action == NULL) { | 1180 if (action == NULL) { |
1151 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); | 1181 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); |
1152 } | 1182 } |
1153 | 1183 |
1154 // Stack allocated list of privileged stack elements | 1184 // Compute the frame initiating the do privileged operation and setup the privileged stack |
1155 PrivilegedElement pi; | 1185 vframeStream vfst(thread); |
1186 vfst.security_get_caller_frame(1); | |
1187 | |
1188 if (vfst.at_end()) { | |
1189 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?"); | |
1190 } | |
1191 | |
1192 Method* method = vfst.method(); | |
1193 instanceKlassHandle klass (THREAD, method->method_holder()); | |
1194 | |
1195 // Check that action object understands "Object run()" | |
1196 Handle h_context; | |
1197 if (context != NULL) { | |
1198 h_context = Handle(THREAD, JNIHandles::resolve(context)); | |
1199 bool authorized = is_authorized(h_context, klass, CHECK_NULL); | |
1200 if (!authorized) { | |
1201 // Create an unprivileged access control object and call it's run function | |
1202 // instead. | |
1203 oop noprivs = create_dummy_access_control_context(CHECK_NULL); | |
1204 h_context = Handle(THREAD, noprivs); | |
1205 } | |
1206 } | |
1156 | 1207 |
1157 // Check that action object understands "Object run()" | 1208 // Check that action object understands "Object run()" |
1158 Handle object (THREAD, JNIHandles::resolve(action)); | 1209 Handle object (THREAD, JNIHandles::resolve(action)); |
1159 | 1210 |
1160 // get run() method | 1211 // get run() method |
1164 methodHandle m (THREAD, m_oop); | 1215 methodHandle m (THREAD, m_oop); |
1165 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { | 1216 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { |
1166 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); | 1217 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); |
1167 } | 1218 } |
1168 | 1219 |
1169 // Compute the frame initiating the do privileged operation and setup the privileged stack | 1220 // Stack allocated list of privileged stack elements |
1170 vframeStream vfst(thread); | 1221 PrivilegedElement pi; |
1171 vfst.security_get_caller_frame(1); | |
1172 | |
1173 if (!vfst.at_end()) { | 1222 if (!vfst.at_end()) { |
1174 pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL); | 1223 pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); |
1175 thread->set_privileged_stack_top(&pi); | 1224 thread->set_privileged_stack_top(&pi); |
1176 } | 1225 } |
1177 | 1226 |
1178 | 1227 |
1179 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type | 1228 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type |
3241 } | 3290 } |
3242 return NULL; | 3291 return NULL; |
3243 JVM_END | 3292 JVM_END |
3244 | 3293 |
3245 | 3294 |
3246 // Utility object for collecting method holders walking down the stack | |
3247 class KlassLink: public ResourceObj { | |
3248 public: | |
3249 KlassHandle klass; | |
3250 KlassLink* next; | |
3251 | |
3252 KlassLink(KlassHandle k) { klass = k; next = NULL; } | |
3253 }; | |
3254 | |
3255 | |
3256 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) | 3295 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) |
3257 JVMWrapper("JVM_GetClassContext"); | 3296 JVMWrapper("JVM_GetClassContext"); |
3258 ResourceMark rm(THREAD); | 3297 ResourceMark rm(THREAD); |
3259 JvmtiVMObjectAllocEventCollector oam; | 3298 JvmtiVMObjectAllocEventCollector oam; |
3260 // Collect linked list of (handles to) method holders | |
3261 KlassLink* first = NULL; | |
3262 KlassLink* last = NULL; | |
3263 int depth = 0; | |
3264 vframeStream vfst(thread); | 3299 vframeStream vfst(thread); |
3265 | 3300 |
3266 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { | 3301 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { |
3267 // This must only be called from SecurityManager.getClassContext | 3302 // This must only be called from SecurityManager.getClassContext |
3268 Method* m = vfst.method(); | 3303 Method* m = vfst.method(); |
3272 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); | 3307 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); |
3273 } | 3308 } |
3274 } | 3309 } |
3275 | 3310 |
3276 // Collect method holders | 3311 // Collect method holders |
3312 GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>(); | |
3277 for (; !vfst.at_end(); vfst.security_next()) { | 3313 for (; !vfst.at_end(); vfst.security_next()) { |
3278 Method* m = vfst.method(); | 3314 Method* m = vfst.method(); |
3279 // Native frames are not returned | 3315 // Native frames are not returned |
3280 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { | 3316 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { |
3281 Klass* holder = m->method_holder(); | 3317 Klass* holder = m->method_holder(); |
3282 assert(holder->is_klass(), "just checking"); | 3318 assert(holder->is_klass(), "just checking"); |
3283 depth++; | 3319 klass_array->append(holder); |
3284 KlassLink* l = new KlassLink(KlassHandle(thread, holder)); | |
3285 if (first == NULL) { | |
3286 first = last = l; | |
3287 } else { | |
3288 last->next = l; | |
3289 last = l; | |
3290 } | |
3291 } | 3320 } |
3292 } | 3321 } |
3293 | 3322 |
3294 // Create result array of type [Ljava/lang/Class; | 3323 // Create result array of type [Ljava/lang/Class; |
3295 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), depth, CHECK_NULL); | 3324 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL); |
3296 // Fill in mirrors corresponding to method holders | 3325 // Fill in mirrors corresponding to method holders |
3297 int index = 0; | 3326 for (int i = 0; i < klass_array->length(); i++) { |
3298 while (first != NULL) { | 3327 result->obj_at_put(i, klass_array->at(i)->java_mirror()); |
3299 result->obj_at_put(index++, first->klass()->java_mirror()); | 3328 } |
3300 first = first->next; | |
3301 } | |
3302 assert(index == depth, "just checking"); | |
3303 | 3329 |
3304 return (jobjectArray) JNIHandles::make_local(env, result); | 3330 return (jobjectArray) JNIHandles::make_local(env, result); |
3305 JVM_END | 3331 JVM_END |
3306 | 3332 |
3307 | 3333 |