1.1 --- a/src/share/vm/interpreter/linkResolver.cpp Mon Mar 27 08:21:39 2017 -0700 1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Mon Mar 27 11:31:27 2017 -0700 1.3 @@ -915,11 +915,11 @@ 1.4 } 1.5 1.6 1.7 -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, 1.8 +void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name, 1.9 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { 1.10 methodHandle resolved_method; 1.11 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 1.12 - runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); 1.13 + runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK); 1.14 } 1.15 1.16 // throws linktime exceptions 1.17 @@ -1018,7 +1018,7 @@ 1.18 1.19 // throws runtime exceptions 1.20 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, 1.21 - KlassHandle current_klass, bool check_access, TRAPS) { 1.22 + KlassHandle current_klass, Handle recv, bool check_access, TRAPS) { 1.23 1.24 // resolved method is selected method unless we have an old-style lookup 1.25 // for a superclass method 1.26 @@ -1026,21 +1026,19 @@ 1.27 // no checks for shadowing 1.28 methodHandle sel_method(THREAD, resolved_method()); 1.29 1.30 + if (check_access && 1.31 + // check if the method is not <init> 1.32 + resolved_method->name() != vmSymbols::object_initializer_name()) { 1.33 + 1.34 // check if this is an old-style super call and do a new lookup if so 1.35 - { KlassHandle method_klass = KlassHandle(THREAD, 1.36 - resolved_method->method_holder()); 1.37 - 1.38 - if (check_access && 1.39 // a) check if ACC_SUPER flag is set for the current class 1.40 - (current_klass->is_super() || !AllowNonVirtualCalls) && 1.41 + if ((current_klass->is_super() || !AllowNonVirtualCalls) && 1.42 // b) check if the class of the resolved_klass is a superclass 1.43 // (not supertype in order to exclude interface classes) of the current class. 1.44 // This check is not performed for super.invoke for interface methods 1.45 // in super interfaces. 1.46 current_klass->is_subclass_of(resolved_klass()) && 1.47 - current_klass() != resolved_klass() && 1.48 - // c) check if the method is not <init> 1.49 - resolved_method->name() != vmSymbols::object_initializer_name()) { 1.50 + current_klass() != resolved_klass()) { 1.51 // Lookup super method 1.52 KlassHandle super_klass(THREAD, current_klass->super()); 1.53 lookup_instance_method_in_klasses(sel_method, super_klass, 1.54 @@ -1055,6 +1053,27 @@ 1.55 resolved_method->signature())); 1.56 } 1.57 } 1.58 + 1.59 + // Check that the class of objectref (the receiver) is the current class or interface, 1.60 + // or a subtype of the current class or interface (the sender), otherwise invokespecial 1.61 + // throws IllegalAccessError. 1.62 + // The verifier checks that the sender is a subtype of the class in the I/MR operand. 1.63 + // The verifier also checks that the receiver is a subtype of the sender, if the sender is 1.64 + // a class. If the sender is an interface, the check has to be performed at runtime. 1.65 + InstanceKlass* sender = InstanceKlass::cast(current_klass()); 1.66 + sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender; 1.67 + if (sender->is_interface() && recv.not_null()) { 1.68 + Klass* receiver_klass = recv->klass(); 1.69 + if (!receiver_klass->is_subtype_of(sender)) { 1.70 + ResourceMark rm(THREAD); 1.71 + char buf[500]; 1.72 + jio_snprintf(buf, sizeof(buf), 1.73 + "Receiver class %s must be the current class or a subtype of interface %s", 1.74 + receiver_klass->name()->as_C_string(), 1.75 + sender->name()->as_C_string()); 1.76 + THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf); 1.77 + } 1.78 + } 1.79 } 1.80 1.81 // check if not static 1.82 @@ -1481,7 +1500,7 @@ 1.83 bool check_access) { 1.84 EXCEPTION_MARK; 1.85 CallInfo info; 1.86 - resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD); 1.87 + resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD); 1.88 if (HAS_PENDING_EXCEPTION) { 1.89 CLEAR_PENDING_EXCEPTION; 1.90 return methodHandle(); 1.91 @@ -1497,7 +1516,7 @@ 1.92 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { 1.93 switch (byte) { 1.94 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; 1.95 - case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; 1.96 + case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break; 1.97 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; 1.98 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break; 1.99 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; 1.100 @@ -1528,13 +1547,13 @@ 1.101 } 1.102 1.103 1.104 -void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { 1.105 +void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { 1.106 KlassHandle resolved_klass; 1.107 Symbol* method_name = NULL; 1.108 Symbol* method_signature = NULL; 1.109 KlassHandle current_klass; 1.110 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); 1.111 - resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.112 + resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK); 1.113 } 1.114 1.115