Mercurial > hg > truffle
comparison 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 |
comparison
equal
deleted
inserted
replaced
11197:3479ab380552 | 11198:1e6d5dec4a4e |
---|---|
1120 | 1120 |
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 // Preserved in Graal repo so that linking against a JDK7 libjava.so works |
1126 // Obsolete since 1.2 (Class.setProtectionDomain removed), although | |
1127 // still defined in core libraries as of 1.5. | |
1128 JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) | 1126 JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) |
1129 JVMWrapper("JVM_SetProtectionDomain"); | 1127 JVMWrapper("JVM_SetProtectionDomain"); |
1130 if (JNIHandles::resolve(cls) == NULL) { | 1128 |
1131 THROW(vmSymbols::java_lang_NullPointerException()); | 1129 ResourceMark rm(THREAD); |
1132 } | 1130 const char* msg = "Obsolete JVM_SetProtectionDomain function called"; |
1133 if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { | 1131 size_t buflen = strlen(msg); |
1134 // Call is ignored for primitive types | 1132 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
1135 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); | 1133 jio_snprintf(buf, buflen, msg); |
1136 | 1134 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
1137 // cls won't be an array, as this called only from ClassLoader.defineClass | 1135 JVM_END |
1138 if (k->oop_is_instance()) { | 1136 |
1139 oop pd = JNIHandles::resolve(protection_domain); | 1137 static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) { |
1140 assert(pd == NULL || pd->is_oop(), "just checking"); | 1138 // If there is a security manager and protection domain, check the access |
1141 java_lang_Class::set_protection_domain(k->java_mirror(), pd); | 1139 // in the protection domain, otherwise it is authorized. |
1142 } | 1140 if (java_lang_System::has_security_manager()) { |
1143 } | 1141 |
1144 JVM_END | 1142 // For bootstrapping, if pd implies method isn't in the JDK, allow |
1145 | 1143 // this context to revert to older behavior. |
1144 // In this case the isAuthorized field in AccessControlContext is also not | |
1145 // present. | |
1146 if (Universe::protection_domain_implies_method() == NULL) { | |
1147 return true; | |
1148 } | |
1149 | |
1150 // Whitelist certain access control contexts | |
1151 if (java_security_AccessControlContext::is_authorized(context)) { | |
1152 return true; | |
1153 } | |
1154 | |
1155 oop prot = klass->protection_domain(); | |
1156 if (prot != NULL) { | |
1157 // Call pd.implies(new SecurityPermission("createAccessControlContext")) | |
1158 // in the new wrapper. | |
1159 methodHandle m(THREAD, Universe::protection_domain_implies_method()); | |
1160 Handle h_prot(THREAD, prot); | |
1161 JavaValue result(T_BOOLEAN); | |
1162 JavaCallArguments args(h_prot); | |
1163 JavaCalls::call(&result, m, &args, CHECK_false); | |
1164 return (result.get_jboolean() != 0); | |
1165 } | |
1166 } | |
1167 return true; | |
1168 } | |
1169 | |
1170 // Create an AccessControlContext with a protection domain with null codesource | |
1171 // and null permissions - which gives no permissions. | |
1172 oop create_dummy_access_control_context(TRAPS) { | |
1173 InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass()); | |
1174 // new ProtectionDomain(null,null); | |
1175 oop null_protection_domain = pd_klass->allocate_instance(CHECK_NULL); | |
1176 Handle null_pd(THREAD, null_protection_domain); | |
1177 | |
1178 // new ProtectionDomain[] {pd}; | |
1179 objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); | |
1180 context->obj_at_put(0, null_pd()); | |
1181 | |
1182 // new AccessControlContext(new ProtectionDomain[] {pd}) | |
1183 objArrayHandle h_context(THREAD, context); | |
1184 oop result = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); | |
1185 return result; | |
1186 } | |
1146 | 1187 |
1147 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) | 1188 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) |
1148 JVMWrapper("JVM_DoPrivileged"); | 1189 JVMWrapper("JVM_DoPrivileged"); |
1149 | 1190 |
1150 if (action == NULL) { | 1191 if (action == NULL) { |
1151 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); | 1192 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); |
1152 } | 1193 } |
1153 | 1194 |
1154 // Stack allocated list of privileged stack elements | 1195 // Compute the frame initiating the do privileged operation and setup the privileged stack |
1155 PrivilegedElement pi; | 1196 vframeStream vfst(thread); |
1197 vfst.security_get_caller_frame(1); | |
1198 | |
1199 if (vfst.at_end()) { | |
1200 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?"); | |
1201 } | |
1202 | |
1203 Method* method = vfst.method(); | |
1204 instanceKlassHandle klass (THREAD, method->method_holder()); | |
1205 | |
1206 // Check that action object understands "Object run()" | |
1207 Handle h_context; | |
1208 if (context != NULL) { | |
1209 h_context = Handle(THREAD, JNIHandles::resolve(context)); | |
1210 bool authorized = is_authorized(h_context, klass, CHECK_NULL); | |
1211 if (!authorized) { | |
1212 // Create an unprivileged access control object and call it's run function | |
1213 // instead. | |
1214 oop noprivs = create_dummy_access_control_context(CHECK_NULL); | |
1215 h_context = Handle(THREAD, noprivs); | |
1216 } | |
1217 } | |
1156 | 1218 |
1157 // Check that action object understands "Object run()" | 1219 // Check that action object understands "Object run()" |
1158 Handle object (THREAD, JNIHandles::resolve(action)); | 1220 Handle object (THREAD, JNIHandles::resolve(action)); |
1159 | 1221 |
1160 // get run() method | 1222 // get run() method |
1164 methodHandle m (THREAD, m_oop); | 1226 methodHandle m (THREAD, m_oop); |
1165 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { | 1227 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) { |
1166 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); | 1228 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); |
1167 } | 1229 } |
1168 | 1230 |
1169 // Compute the frame initiating the do privileged operation and setup the privileged stack | 1231 // Stack allocated list of privileged stack elements |
1170 vframeStream vfst(thread); | 1232 PrivilegedElement pi; |
1171 vfst.security_get_caller_frame(1); | |
1172 | |
1173 if (!vfst.at_end()) { | 1233 if (!vfst.at_end()) { |
1174 pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL); | 1234 pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); |
1175 thread->set_privileged_stack_top(&pi); | 1235 thread->set_privileged_stack_top(&pi); |
1176 } | 1236 } |
1177 | 1237 |
1178 | 1238 |
1179 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type | 1239 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type |
3241 } | 3301 } |
3242 return NULL; | 3302 return NULL; |
3243 JVM_END | 3303 JVM_END |
3244 | 3304 |
3245 | 3305 |
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)) | 3306 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) |
3257 JVMWrapper("JVM_GetClassContext"); | 3307 JVMWrapper("JVM_GetClassContext"); |
3258 ResourceMark rm(THREAD); | 3308 ResourceMark rm(THREAD); |
3259 JvmtiVMObjectAllocEventCollector oam; | 3309 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); | 3310 vframeStream vfst(thread); |
3265 | 3311 |
3266 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { | 3312 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { |
3267 // This must only be called from SecurityManager.getClassContext | 3313 // This must only be called from SecurityManager.getClassContext |
3268 Method* m = vfst.method(); | 3314 Method* m = vfst.method(); |
3272 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); | 3318 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); |
3273 } | 3319 } |
3274 } | 3320 } |
3275 | 3321 |
3276 // Collect method holders | 3322 // Collect method holders |
3323 GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>(); | |
3277 for (; !vfst.at_end(); vfst.security_next()) { | 3324 for (; !vfst.at_end(); vfst.security_next()) { |
3278 Method* m = vfst.method(); | 3325 Method* m = vfst.method(); |
3279 // Native frames are not returned | 3326 // Native frames are not returned |
3280 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { | 3327 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { |
3281 Klass* holder = m->method_holder(); | 3328 Klass* holder = m->method_holder(); |
3282 assert(holder->is_klass(), "just checking"); | 3329 assert(holder->is_klass(), "just checking"); |
3283 depth++; | 3330 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 } | 3331 } |
3292 } | 3332 } |
3293 | 3333 |
3294 // Create result array of type [Ljava/lang/Class; | 3334 // Create result array of type [Ljava/lang/Class; |
3295 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), depth, CHECK_NULL); | 3335 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL); |
3296 // Fill in mirrors corresponding to method holders | 3336 // Fill in mirrors corresponding to method holders |
3297 int index = 0; | 3337 for (int i = 0; i < klass_array->length(); i++) { |
3298 while (first != NULL) { | 3338 result->obj_at_put(i, klass_array->at(i)->java_mirror()); |
3299 result->obj_at_put(index++, first->klass()->java_mirror()); | 3339 } |
3300 first = first->next; | |
3301 } | |
3302 assert(index == depth, "just checking"); | |
3303 | 3340 |
3304 return (jobjectArray) JNIHandles::make_local(env, result); | 3341 return (jobjectArray) JNIHandles::make_local(env, result); |
3305 JVM_END | 3342 JVM_END |
3306 | 3343 |
3307 | 3344 |