< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
rev 52360 : 8212605: Pure-Java implementation of AccessController.doPrivileged


  38 #include "gc/shared/collectedHeap.inline.hpp"
  39 #include "interpreter/bytecode.hpp"
  40 #include "jfr/jfrEvents.hpp"
  41 #include "logging/log.hpp"
  42 #include "memory/heapShared.hpp"
  43 #include "memory/oopFactory.hpp"
  44 #include "memory/referenceType.hpp"
  45 #include "memory/resourceArea.hpp"
  46 #include "memory/universe.hpp"
  47 #include "oops/access.inline.hpp"
  48 #include "oops/fieldStreams.hpp"
  49 #include "oops/instanceKlass.hpp"
  50 #include "oops/method.hpp"
  51 #include "oops/objArrayKlass.hpp"
  52 #include "oops/objArrayOop.inline.hpp"
  53 #include "oops/oop.inline.hpp"
  54 #include "prims/jvm_misc.hpp"
  55 #include "prims/jvmtiExport.hpp"
  56 #include "prims/jvmtiThreadState.hpp"
  57 #include "prims/nativeLookup.hpp"
  58 #include "prims/privilegedStack.hpp"
  59 #include "prims/stackwalk.hpp"
  60 #include "runtime/arguments.hpp"
  61 #include "runtime/atomic.hpp"
  62 #include "runtime/handles.inline.hpp"
  63 #include "runtime/init.hpp"
  64 #include "runtime/interfaceSupport.inline.hpp"
  65 #include "runtime/java.hpp"
  66 #include "runtime/javaCalls.hpp"
  67 #include "runtime/jfieldIDWorkaround.hpp"
  68 #include "runtime/jniHandles.inline.hpp"
  69 #include "runtime/orderAccess.hpp"
  70 #include "runtime/os.inline.hpp"
  71 #include "runtime/perfData.hpp"
  72 #include "runtime/reflection.hpp"
  73 #include "runtime/thread.inline.hpp"
  74 #include "runtime/threadSMR.hpp"
  75 #include "runtime/vframe.inline.hpp"
  76 #include "runtime/vm_operations.hpp"
  77 #include "runtime/vm_version.hpp"
  78 #include "services/attachListener.hpp"


1149   }
1150 JVM_END
1151 
1152 
1153 JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
1154   JVMWrapper("JVM_GetProtectionDomain");
1155   if (JNIHandles::resolve(cls) == NULL) {
1156     THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
1157   }
1158 
1159   if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
1160     // Primitive types does not have a protection domain.
1161     return NULL;
1162   }
1163 
1164   oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
1165   return (jobject) JNIHandles::make_local(env, pd);
1166 JVM_END
1167 
1168 
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.
1319 JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls))
1320   JVMWrapper("JVM_GetInheritedAccessControlContext");
1321   oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj());
1322   return JNIHandles::make_local(env, result);
1323 JVM_END
1324 
1325 class RegisterArrayForGC {
1326  private:
1327   JavaThread *_thread;
1328  public:
1329   RegisterArrayForGC(JavaThread *thread, GrowableArray<oop>* array)  {
1330     _thread = thread;
1331     _thread->register_array_for_gc(array);
1332   }
1333 
1334   ~RegisterArrayForGC() {
1335     _thread->register_array_for_gc(NULL);
1336   }
1337 };
1338 
1339 
1340 JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
1341   JVMWrapper("JVM_GetStackAccessControlContext");
1342   if (!UsePrivilegedStack) return NULL;
1343 
1344   ResourceMark rm(THREAD);
1345   GrowableArray<oop>* local_array = new GrowableArray<oop>(12);
1346   JvmtiVMObjectAllocEventCollector oam;
1347 
1348   // count the protection domains on the execution stack. We collapse
1349   // duplicate consecutive protection domains into a single one, as
1350   // well as stopping when we hit a privileged frame.
1351 
1352   // Use vframeStream to iterate through Java frames
1353   vframeStream vfst(thread);
1354 
1355   oop previous_protection_domain = NULL;
1356   Handle privileged_context(thread, NULL);
1357   bool is_privileged = false;
1358   oop protection_domain = NULL;
1359 
1360   for(; !vfst.at_end(); vfst.next()) {



1361     // get method of frame
1362     Method* method = vfst.method();
1363     intptr_t* frame_id   = vfst.frame_id();
1364 
1365     // check the privileged frames to see if we have a match
1366     if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) {


1367       // this frame is privileged
1368       is_privileged = true;
1369       privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context());
1370       protection_domain  = thread->privileged_stack_top()->protection_domain();









1371     } else {
1372       protection_domain = method->method_holder()->protection_domain();
1373     }
1374 
1375     if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) {
1376       local_array->push(protection_domain);
1377       previous_protection_domain = protection_domain;
1378     }
1379 
1380     if (is_privileged) break;
1381   }
1382 
1383 
1384   // either all the domains on the stack were system domains, or
1385   // we had a privileged system domain
1386   if (local_array->is_empty()) {
1387     if (is_privileged && privileged_context.is_null()) return NULL;
1388 
1389     oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
1390     return JNIHandles::make_local(env, result);




  38 #include "gc/shared/collectedHeap.inline.hpp"
  39 #include "interpreter/bytecode.hpp"
  40 #include "jfr/jfrEvents.hpp"
  41 #include "logging/log.hpp"
  42 #include "memory/heapShared.hpp"
  43 #include "memory/oopFactory.hpp"
  44 #include "memory/referenceType.hpp"
  45 #include "memory/resourceArea.hpp"
  46 #include "memory/universe.hpp"
  47 #include "oops/access.inline.hpp"
  48 #include "oops/fieldStreams.hpp"
  49 #include "oops/instanceKlass.hpp"
  50 #include "oops/method.hpp"
  51 #include "oops/objArrayKlass.hpp"
  52 #include "oops/objArrayOop.inline.hpp"
  53 #include "oops/oop.inline.hpp"
  54 #include "prims/jvm_misc.hpp"
  55 #include "prims/jvmtiExport.hpp"
  56 #include "prims/jvmtiThreadState.hpp"
  57 #include "prims/nativeLookup.hpp"

  58 #include "prims/stackwalk.hpp"
  59 #include "runtime/arguments.hpp"
  60 #include "runtime/atomic.hpp"
  61 #include "runtime/handles.inline.hpp"
  62 #include "runtime/init.hpp"
  63 #include "runtime/interfaceSupport.inline.hpp"
  64 #include "runtime/java.hpp"
  65 #include "runtime/javaCalls.hpp"
  66 #include "runtime/jfieldIDWorkaround.hpp"
  67 #include "runtime/jniHandles.inline.hpp"
  68 #include "runtime/orderAccess.hpp"
  69 #include "runtime/os.inline.hpp"
  70 #include "runtime/perfData.hpp"
  71 #include "runtime/reflection.hpp"
  72 #include "runtime/thread.inline.hpp"
  73 #include "runtime/threadSMR.hpp"
  74 #include "runtime/vframe.inline.hpp"
  75 #include "runtime/vm_operations.hpp"
  76 #include "runtime/vm_version.hpp"
  77 #include "services/attachListener.hpp"


1148   }
1149 JVM_END
1150 
1151 
1152 JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
1153   JVMWrapper("JVM_GetProtectionDomain");
1154   if (JNIHandles::resolve(cls) == NULL) {
1155     THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
1156   }
1157 
1158   if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
1159     // Primitive types does not have a protection domain.
1160     return NULL;
1161   }
1162 
1163   oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
1164   return (jobject) JNIHandles::make_local(env, pd);
1165 JVM_END
1166 
1167 





















































































































































1168 // Returns the inherited_access_control_context field of the running thread.
1169 JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls))
1170   JVMWrapper("JVM_GetInheritedAccessControlContext");
1171   oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj());
1172   return JNIHandles::make_local(env, result);
1173 JVM_END
1174 
1175 class RegisterArrayForGC {
1176  private:
1177   JavaThread *_thread;
1178  public:
1179   RegisterArrayForGC(JavaThread *thread, GrowableArray<oop>* array)  {
1180     _thread = thread;
1181     _thread->register_array_for_gc(array);
1182   }
1183 
1184   ~RegisterArrayForGC() {
1185     _thread->register_array_for_gc(NULL);
1186   }
1187 };
1188 
1189 
1190 JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
1191   JVMWrapper("JVM_GetStackAccessControlContext");
1192   if (!UsePrivilegedStack) return NULL;
1193 
1194   ResourceMark rm(THREAD);
1195   GrowableArray<oop>* local_array = new GrowableArray<oop>(12);
1196   JvmtiVMObjectAllocEventCollector oam;
1197 
1198   // count the protection domains on the execution stack. We collapse
1199   // duplicate consecutive protection domains into a single one, as
1200   // well as stopping when we hit a privileged frame.
1201 



1202   oop previous_protection_domain = NULL;
1203   Handle privileged_context(thread, NULL);
1204   bool is_privileged = false;
1205   oop protection_domain = NULL;
1206 
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()) {
1211     // get method of frame
1212     Method* method = vf->method();

1213 
1214     // stop at the first privileged frame
1215     if (method->method_holder() == SystemDictionary::AccessController_klass() &&
1216       method->name() == vmSymbols::executePrivileged_name())
1217     {
1218       // this frame is privileged
1219       is_privileged = true;
1220 
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       protection_domain  = caller_klass->protection_domain();
1231     } else {
1232       protection_domain = method->method_holder()->protection_domain();
1233     }
1234 
1235     if ((!oopDesc::equals(previous_protection_domain, protection_domain)) && (protection_domain != NULL)) {
1236       local_array->push(protection_domain);
1237       previous_protection_domain = protection_domain;
1238     }
1239 
1240     if (is_privileged) break;
1241   }
1242 
1243 
1244   // either all the domains on the stack were system domains, or
1245   // we had a privileged system domain
1246   if (local_array->is_empty()) {
1247     if (is_privileged && privileged_context.is_null()) return NULL;
1248 
1249     oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
1250     return JNIHandles::make_local(env, result);


< prev index next >