1164 oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); |
1163 oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); |
1165 return (jobject) JNIHandles::make_local(env, pd); |
1164 return (jobject) JNIHandles::make_local(env, pd); |
1166 JVM_END |
1165 JVM_END |
1167 |
1166 |
1168 |
1167 |
1169 static bool is_authorized(Handle context, InstanceKlass* klass, TRAPS) { |
|
1170 // If there is a security manager and protection domain, check the access |
|
1171 // in the protection domain, otherwise it is authorized. |
|
1172 if (java_lang_System::has_security_manager()) { |
|
1173 |
|
1174 // For bootstrapping, if pd implies method isn't in the JDK, allow |
|
1175 // this context to revert to older behavior. |
|
1176 // In this case the isAuthorized field in AccessControlContext is also not |
|
1177 // present. |
|
1178 if (Universe::protection_domain_implies_method() == NULL) { |
|
1179 return true; |
|
1180 } |
|
1181 |
|
1182 // Whitelist certain access control contexts |
|
1183 if (java_security_AccessControlContext::is_authorized(context)) { |
|
1184 return true; |
|
1185 } |
|
1186 |
|
1187 oop prot = klass->protection_domain(); |
|
1188 if (prot != NULL) { |
|
1189 // Call pd.implies(new SecurityPermission("createAccessControlContext")) |
|
1190 // in the new wrapper. |
|
1191 methodHandle m(THREAD, Universe::protection_domain_implies_method()); |
|
1192 Handle h_prot(THREAD, prot); |
|
1193 JavaValue result(T_BOOLEAN); |
|
1194 JavaCallArguments args(h_prot); |
|
1195 JavaCalls::call(&result, m, &args, CHECK_false); |
|
1196 return (result.get_jboolean() != 0); |
|
1197 } |
|
1198 } |
|
1199 return true; |
|
1200 } |
|
1201 |
|
1202 // Create an AccessControlContext with a protection domain with null codesource |
|
1203 // and null permissions - which gives no permissions. |
|
1204 oop create_dummy_access_control_context(TRAPS) { |
|
1205 InstanceKlass* pd_klass = SystemDictionary::ProtectionDomain_klass(); |
|
1206 // Call constructor ProtectionDomain(null, null); |
|
1207 Handle obj = JavaCalls::construct_new_instance(pd_klass, |
|
1208 vmSymbols::codesource_permissioncollection_signature(), |
|
1209 Handle(), Handle(), CHECK_NULL); |
|
1210 |
|
1211 // new ProtectionDomain[] {pd}; |
|
1212 objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL); |
|
1213 context->obj_at_put(0, obj()); |
|
1214 |
|
1215 // new AccessControlContext(new ProtectionDomain[] {pd}) |
|
1216 objArrayHandle h_context(THREAD, context); |
|
1217 oop acc = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL); |
|
1218 return acc; |
|
1219 } |
|
1220 |
|
1221 JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException)) |
|
1222 JVMWrapper("JVM_DoPrivileged"); |
|
1223 |
|
1224 if (action == NULL) { |
|
1225 THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action"); |
|
1226 } |
|
1227 |
|
1228 // Compute the frame initiating the do privileged operation and setup the privileged stack |
|
1229 vframeStream vfst(thread); |
|
1230 vfst.security_get_caller_frame(1); |
|
1231 |
|
1232 if (vfst.at_end()) { |
|
1233 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?"); |
|
1234 } |
|
1235 |
|
1236 Method* method = vfst.method(); |
|
1237 InstanceKlass* klass = method->method_holder(); |
|
1238 |
|
1239 // Check that action object understands "Object run()" |
|
1240 Handle h_context; |
|
1241 if (context != NULL) { |
|
1242 h_context = Handle(THREAD, JNIHandles::resolve(context)); |
|
1243 bool authorized = is_authorized(h_context, klass, CHECK_NULL); |
|
1244 if (!authorized) { |
|
1245 // Create an unprivileged access control object and call it's run function |
|
1246 // instead. |
|
1247 oop noprivs = create_dummy_access_control_context(CHECK_NULL); |
|
1248 h_context = Handle(THREAD, noprivs); |
|
1249 } |
|
1250 } |
|
1251 |
|
1252 // Check that action object understands "Object run()" |
|
1253 Handle object (THREAD, JNIHandles::resolve(action)); |
|
1254 |
|
1255 // get run() method |
|
1256 Method* m_oop = object->klass()->uncached_lookup_method( |
|
1257 vmSymbols::run_method_name(), |
|
1258 vmSymbols::void_object_signature(), |
|
1259 Klass::find_overpass); |
|
1260 |
|
1261 // See if there is a default method for "Object run()". |
|
1262 if (m_oop == NULL && object->klass()->is_instance_klass()) { |
|
1263 InstanceKlass* iklass = InstanceKlass::cast(object->klass()); |
|
1264 m_oop = iklass->lookup_method_in_ordered_interfaces( |
|
1265 vmSymbols::run_method_name(), |
|
1266 vmSymbols::void_object_signature()); |
|
1267 } |
|
1268 |
|
1269 methodHandle m (THREAD, m_oop); |
|
1270 if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static() || m()->is_abstract()) { |
|
1271 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method"); |
|
1272 } |
|
1273 |
|
1274 // Stack allocated list of privileged stack elements |
|
1275 PrivilegedElement pi; |
|
1276 if (!vfst.at_end()) { |
|
1277 pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL); |
|
1278 thread->set_privileged_stack_top(&pi); |
|
1279 } |
|
1280 |
|
1281 |
|
1282 // invoke the Object run() in the action object. We cannot use call_interface here, since the static type |
|
1283 // is not really known - it is either java.security.PrivilegedAction or java.security.PrivilegedExceptionAction |
|
1284 Handle pending_exception; |
|
1285 JavaValue result(T_OBJECT); |
|
1286 JavaCallArguments args(object); |
|
1287 JavaCalls::call(&result, m, &args, THREAD); |
|
1288 |
|
1289 // done with action, remove ourselves from the list |
|
1290 if (!vfst.at_end()) { |
|
1291 assert(thread->privileged_stack_top() != NULL && thread->privileged_stack_top() == &pi, "wrong top element"); |
|
1292 thread->set_privileged_stack_top(thread->privileged_stack_top()->next()); |
|
1293 } |
|
1294 |
|
1295 if (HAS_PENDING_EXCEPTION) { |
|
1296 pending_exception = Handle(THREAD, PENDING_EXCEPTION); |
|
1297 CLEAR_PENDING_EXCEPTION; |
|
1298 // JVMTI has already reported the pending exception |
|
1299 // JVMTI internal flag reset is needed in order to report PrivilegedActionException |
|
1300 if (THREAD->is_Java_thread()) { |
|
1301 JvmtiExport::clear_detected_exception((JavaThread*) THREAD); |
|
1302 } |
|
1303 if ( pending_exception->is_a(SystemDictionary::Exception_klass()) && |
|
1304 !pending_exception->is_a(SystemDictionary::RuntimeException_klass())) { |
|
1305 // Throw a java.security.PrivilegedActionException(Exception e) exception |
|
1306 JavaCallArguments args(pending_exception); |
|
1307 THROW_ARG_0(vmSymbols::java_security_PrivilegedActionException(), |
|
1308 vmSymbols::exception_void_signature(), |
|
1309 &args); |
|
1310 } |
|
1311 } |
|
1312 |
|
1313 if (pending_exception.not_null()) THROW_OOP_0(pending_exception()); |
|
1314 return JNIHandles::make_local(env, (oop) result.get_jobject()); |
|
1315 JVM_END |
|
1316 |
|
1317 |
|
1318 // Returns the inherited_access_control_context field of the running thread. |
1168 // Returns the inherited_access_control_context field of the running thread. |
1319 JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)) |
1169 JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)) |
1320 JVMWrapper("JVM_GetInheritedAccessControlContext"); |
1170 JVMWrapper("JVM_GetInheritedAccessControlContext"); |
1321 oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj()); |
1171 oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj()); |
1322 return JNIHandles::make_local(env, result); |
1172 return JNIHandles::make_local(env, result); |
1347 |
1197 |
1348 // count the protection domains on the execution stack. We collapse |
1198 // count the protection domains on the execution stack. We collapse |
1349 // duplicate consecutive protection domains into a single one, as |
1199 // duplicate consecutive protection domains into a single one, as |
1350 // well as stopping when we hit a privileged frame. |
1200 // well as stopping when we hit a privileged frame. |
1351 |
1201 |
1352 // Use vframeStream to iterate through Java frames |
|
1353 vframeStream vfst(thread); |
|
1354 |
|
1355 oop previous_protection_domain = NULL; |
1202 oop previous_protection_domain = NULL; |
1356 Handle privileged_context(thread, NULL); |
1203 Handle privileged_context(thread, NULL); |
1357 bool is_privileged = false; |
1204 bool is_privileged = false; |
1358 oop protection_domain = NULL; |
1205 oop protection_domain = NULL; |
1359 |
1206 |
1360 for(; !vfst.at_end(); vfst.next()) { |
1207 // Iterate through Java frames |
|
1208 RegisterMap reg_map(thread); |
|
1209 javaVFrame *vf = thread->last_java_vframe(®_map); |
|
1210 for (; vf != NULL; vf = vf->java_sender()) { |
1361 // get method of frame |
1211 // get method of frame |
1362 Method* method = vfst.method(); |
1212 Method* method = vf->method(); |
1363 intptr_t* frame_id = vfst.frame_id(); |
1213 |
1364 |
1214 // stop at the first privileged frame |
1365 // check the privileged frames to see if we have a match |
1215 if (method->method_holder()->name() == vmSymbols::java_security_AccessController() && |
1366 if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) { |
1216 method->name() == vmSymbols::executePrivileged_name()) |
|
1217 { |
1367 // this frame is privileged |
1218 // this frame is privileged |
1368 is_privileged = true; |
1219 is_privileged = true; |
1369 privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context()); |
1220 |
1370 protection_domain = thread->privileged_stack_top()->protection_domain(); |
1221 javaVFrame *priv = vf; // executePrivileged |
|
1222 javaVFrame *caller_fr = priv->java_sender(); // doPrivileged |
|
1223 caller_fr = caller_fr->java_sender(); // caller |
|
1224 |
|
1225 StackValueCollection* locals = priv->locals(); |
|
1226 privileged_context = locals->obj_at(1); |
|
1227 Handle caller = locals->obj_at(2); |
|
1228 |
|
1229 Klass *caller_klass = java_lang_Class::as_Klass(caller()); |
|
1230 #if 0 |
|
1231 // TODO: If we want to get the caller from the stackwalk, rather than |
|
1232 // passing it in, we need to mimic Reflection.getCallerClass() |
|
1233 // behavior and skip reflection frames. |
|
1234 assert(caller_klass == caller_fr->method()->method_holder(), "!"); |
|
1235 #endif |
|
1236 protection_domain = caller_klass->protection_domain(); |
1371 } else { |
1237 } else { |
1372 protection_domain = method->method_holder()->protection_domain(); |
1238 protection_domain = method->method_holder()->protection_domain(); |
1373 } |
1239 } |
1374 |
1240 |
1375 if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) { |
1241 if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) { |