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