src/hotspot/share/prims/jvm.cpp
branchdlong-java-do-priv-branch
changeset 56897 840ad2a9015a
parent 50951 b96466cdfc45
equal deleted inserted replaced
51715:13a63d4a3f8d 56897:840ad2a9015a
    53 #include "oops/oop.inline.hpp"
    53 #include "oops/oop.inline.hpp"
    54 #include "prims/jvm_misc.hpp"
    54 #include "prims/jvm_misc.hpp"
    55 #include "prims/jvmtiExport.hpp"
    55 #include "prims/jvmtiExport.hpp"
    56 #include "prims/jvmtiThreadState.hpp"
    56 #include "prims/jvmtiThreadState.hpp"
    57 #include "prims/nativeLookup.hpp"
    57 #include "prims/nativeLookup.hpp"
    58 #include "prims/privilegedStack.hpp"
       
    59 #include "prims/stackwalk.hpp"
    58 #include "prims/stackwalk.hpp"
    60 #include "runtime/arguments.hpp"
    59 #include "runtime/arguments.hpp"
    61 #include "runtime/atomic.hpp"
    60 #include "runtime/atomic.hpp"
    62 #include "runtime/handles.inline.hpp"
    61 #include "runtime/handles.inline.hpp"
    63 #include "runtime/init.hpp"
    62 #include "runtime/init.hpp"
  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(&reg_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)) {