1.1 --- a/src/share/vm/classfile/verifier.cpp Sat Nov 23 12:25:13 2013 +0100 1.2 +++ b/src/share/vm/classfile/verifier.cpp Tue Nov 26 09:52:22 2013 -0500 1.3 @@ -2302,6 +2302,24 @@ 1.4 } 1.5 } 1.6 1.7 +bool ClassVerifier::is_same_or_direct_interface( 1.8 + instanceKlassHandle klass, 1.9 + VerificationType klass_type, 1.10 + VerificationType ref_class_type) { 1.11 + if (ref_class_type.equals(klass_type)) return true; 1.12 + Array<Klass*>* local_interfaces = klass->local_interfaces(); 1.13 + if (local_interfaces != NULL) { 1.14 + for (int x = 0; x < local_interfaces->length(); x++) { 1.15 + Klass* k = local_interfaces->at(x); 1.16 + assert (k != NULL && k->is_interface(), "invalid interface"); 1.17 + if (ref_class_type.equals(VerificationType::reference_type(k->name()))) { 1.18 + return true; 1.19 + } 1.20 + } 1.21 + } 1.22 + return false; 1.23 +} 1.24 + 1.25 void ClassVerifier::verify_invoke_instructions( 1.26 RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, 1.27 bool *this_uninit, VerificationType return_type, 1.28 @@ -2432,23 +2450,38 @@ 1.29 return; 1.30 } 1.31 } else if (opcode == Bytecodes::_invokespecial 1.32 - && !ref_class_type.equals(current_type()) 1.33 + && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) 1.34 && !ref_class_type.equals(VerificationType::reference_type( 1.35 current_class()->super()->name()))) { 1.36 bool subtype = false; 1.37 + bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; 1.38 if (!current_class()->is_anonymous()) { 1.39 subtype = ref_class_type.is_assignable_from( 1.40 current_type(), this, CHECK_VERIFY(this)); 1.41 } else { 1.42 - subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( 1.43 - current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); 1.44 + VerificationType host_klass_type = 1.45 + VerificationType::reference_type(current_class()->host_klass()->name()); 1.46 + subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this)); 1.47 + 1.48 + // If invokespecial of IMR, need to recheck for same or 1.49 + // direct interface relative to the host class 1.50 + have_imr_indirect = (have_imr_indirect && 1.51 + !is_same_or_direct_interface( 1.52 + InstanceKlass::cast(current_class()->host_klass()), 1.53 + host_klass_type, ref_class_type)); 1.54 } 1.55 if (!subtype) { 1.56 verify_error(ErrorContext::bad_code(bci), 1.57 "Bad invokespecial instruction: " 1.58 "current class isn't assignable to reference class."); 1.59 return; 1.60 + } else if (have_imr_indirect) { 1.61 + verify_error(ErrorContext::bad_code(bci), 1.62 + "Bad invokespecial instruction: " 1.63 + "interface method reference is in an indirect superinterface."); 1.64 + return; 1.65 } 1.66 + 1.67 } 1.68 // Match method descriptor with operand stack 1.69 for (int i = nargs - 1; i >= 0; i--) { // Run backwards