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