1 /* 2 * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "cds/cdsConfig.hpp" 26 #include "classfile/symbolTable.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "classfile/systemDictionaryShared.hpp" 29 #include "classfile/verificationType.hpp" 30 #include "classfile/verifier.hpp" 31 #include "classfile/vmClasses.hpp" 32 #include "classfile/vmSymbols.hpp" 33 #include "logging/log.hpp" 34 #include "oops/klass.inline.hpp" 35 #include "runtime/handles.inline.hpp" 36 37 VerificationType VerificationType::from_tag(u1 tag) { 38 switch (tag) { 39 case ITEM_Top: return bogus_type(); 40 case ITEM_Integer: return integer_type(); 41 case ITEM_Float: return float_type(); 42 case ITEM_Double: return double_type(); 43 case ITEM_Long: return long_type(); 44 case ITEM_Null: return null_type(); 45 default: 46 ShouldNotReachHere(); 47 return bogus_type(); 48 } 49 } 50 51 // Potentially resolve the target class and from class, and check whether the from class is assignable 52 // to the target class. The current_klass is the class being verified - it could also be the target in some 53 // cases, and otherwise is needed to obtain the correct classloader for resolving the other classes. 54 bool VerificationType::resolve_and_check_assignability(InstanceKlass* current_klass, Symbol* target_name, Symbol* from_name, 55 bool from_field_is_protected, bool from_is_array, 56 bool from_is_object, bool* target_is_interface, TRAPS) { 57 HandleMark hm(THREAD); 58 Klass* target_klass; 59 if (current_klass->is_hidden() && current_klass->name() == target_name) { 60 target_klass = current_klass; 61 } else { 62 target_klass = SystemDictionary::resolve_or_fail( 63 target_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false); 64 if (log_is_enabled(Debug, class, resolve)) { 65 Verifier::trace_class_resolution(target_klass, current_klass); 66 } 67 } 68 69 // Need to do this check when called from CDS. 70 // if (this_class->access_flags().is_primitive_class()) { 71 // Klass* from_class = SystemDictionary::resolve_or_fail( 72 // from_name, Handle(THREAD, klass->class_loader()), 73 // Handle(THREAD, klass->protection_domain()), true, CHECK_false); 74 // return from_class == this_class; 75 // } 76 bool is_intf = target_klass->is_interface(); 77 if (target_is_interface != nullptr) { 78 *target_is_interface = is_intf; 79 } 80 81 if (is_intf && (!from_field_is_protected || 82 from_name != vmSymbols::java_lang_Object())) { 83 // If we are not trying to access a protected field or method in 84 // java.lang.Object then, for arrays, we only allow assignability 85 // to interfaces java.lang.Cloneable and java.io.Serializable 86 // Otherwise, we treat interfaces as java.lang.Object. 87 return !from_is_array || 88 target_klass == vmClasses::Cloneable_klass() || 89 target_klass == vmClasses::Serializable_klass(); 90 } else if (from_is_object) { 91 Klass* from_klass; 92 if (current_klass->is_hidden() && current_klass->name() == from_name) { 93 from_klass = current_klass; 94 } else { 95 from_klass = SystemDictionary::resolve_or_fail( 96 from_name, Handle(THREAD, current_klass->class_loader()), true, CHECK_false); 97 if (log_is_enabled(Debug, class, resolve)) { 98 Verifier::trace_class_resolution(from_klass, current_klass); 99 } 100 } 101 return from_klass->is_subclass_of(target_klass); 102 } 103 104 return false; 105 } 106 107 bool VerificationType::is_reference_assignable_from( 108 const VerificationType& from, ClassVerifier* context, 109 bool from_field_is_protected, bool* this_is_interface, TRAPS) const { 110 111 if (from.is_null()) { 112 // null is assignable to any reference 113 return true; 114 } else if (is_null()) { 115 return false; 116 } else if (name() == from.name()) { 117 return true; 118 } else if (is_object()) { 119 // We need check the class hierarchy to check assignability 120 if (name() == vmSymbols::java_lang_Object()) { 121 // any object or array is assignable to java.lang.Object 122 return true; 123 } 124 125 #if INCLUDE_CDS 126 if (CDSConfig::is_dumping_archive()) { 127 bool skip_assignability_check = false; 128 SystemDictionaryShared::add_verification_constraint(context->current_class(), 129 name(), from.name(), from_field_is_protected, from.is_array(), 130 from.is_object(), &skip_assignability_check); 131 if (skip_assignability_check) { 132 // We are not able to resolve name() or from.name(). The actual assignability check 133 // will be delayed until runtime. 134 return true; 135 } 136 } 137 #endif 138 return resolve_and_check_assignability(context->current_class(), name(), from.name(), 139 from_field_is_protected, from.is_array(), 140 from.is_object(), this_is_interface, THREAD); 141 } else if (is_array() && from.is_array()) { 142 VerificationType comp_this = get_component(context); 143 VerificationType comp_from = from.get_component(context); 144 145 if (!comp_this.is_bogus() && !comp_from.is_bogus()) { 146 return comp_this.is_component_assignable_from(comp_from, context, 147 from_field_is_protected, THREAD); 148 } 149 } 150 return false; 151 } 152 153 VerificationType VerificationType::get_component(ClassVerifier *context) const { 154 assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array"); 155 SignatureStream ss(name(), false); 156 ss.skip_array_prefix(1); 157 switch (ss.type()) { 158 case T_BOOLEAN: return VerificationType(Boolean); 159 case T_BYTE: return VerificationType(Byte); 160 case T_CHAR: return VerificationType(Char); 161 case T_SHORT: return VerificationType(Short); 162 case T_INT: return VerificationType(Integer); 163 case T_LONG: return VerificationType(Long); 164 case T_FLOAT: return VerificationType(Float); 165 case T_DOUBLE: return VerificationType(Double); 166 case T_ARRAY: 167 case T_OBJECT: { 168 guarantee(ss.is_reference(), "unchecked verifier input?"); 169 Symbol* component = ss.as_symbol(); 170 // Create another symbol to save as signature stream unreferences this symbol. 171 Symbol* component_copy = context->create_temporary_symbol(component); 172 assert(component_copy == component, "symbols don't match"); 173 return VerificationType::reference_type(component_copy); 174 } 175 default: 176 // Met an invalid type signature, e.g. [X 177 return VerificationType::bogus_type(); 178 } 179 } 180 181 void VerificationType::print_on(outputStream* st) const { 182 switch (_u._data) { 183 case Bogus: st->print("top"); break; 184 case Category1: st->print("category1"); break; 185 case Category2: st->print("category2"); break; 186 case Category2_2nd: st->print("category2_2nd"); break; 187 case Boolean: st->print("boolean"); break; 188 case Byte: st->print("byte"); break; 189 case Short: st->print("short"); break; 190 case Char: st->print("char"); break; 191 case Integer: st->print("integer"); break; 192 case Float: st->print("float"); break; 193 case Long: st->print("long"); break; 194 case Double: st->print("double"); break; 195 case Long_2nd: st->print("long_2nd"); break; 196 case Double_2nd: st->print("double_2nd"); break; 197 case Null: st->print("null"); break; 198 case ReferenceQuery: st->print("reference type"); break; 199 case Category1Query: st->print("category1 type"); break; 200 case Category2Query: st->print("category2 type"); break; 201 case Category2_2ndQuery: st->print("category2_2nd type"); break; 202 default: 203 if (is_uninitialized_this()) { 204 st->print("uninitializedThis"); 205 } else if (is_uninitialized()) { 206 st->print("uninitialized %d", bci()); 207 } else { 208 if (name() != nullptr) { 209 name()->print_value_on(st); 210 } else { 211 st->print_cr("null"); 212 } 213 } 214 } 215 }