225 ResourceMark rm(THREAD); 226 char buf[200]; 227 CLEAR_PENDING_EXCEPTION; 228 jio_snprintf(buf, sizeof(buf), 229 "Unable to load nest-host class (%s) of %s", 230 _constants->klass_name_at(_nest_host_index)->as_C_string(), 231 this->external_name()); 232 log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); 233 THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); 234 } 235 // other exceptions pass through (OOME, StackOverflowError etc) 236 return NULL; 237 } 238 239 // A valid nest-host is an instance class in the current package that lists this 240 // class as a nest member. If any of these conditions are not met we post the 241 // requested exception type (if any) and return NULL 242 243 const char* error = NULL; 244 245 // Need to check we have an instance class first 246 if (k->is_instance_klass()) { 247 nest_host_k = InstanceKlass::cast(k); 248 249 // FIXME: an exception from this is perhaps impossible 250 bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); 251 if (is_member) { 252 // Finally check we're in the same package - as there could be collusion 253 // between untrusted types. 254 if (is_same_class_package(nest_host_k)) { 255 // save resolved nest-host value 256 _nest_host = nest_host_k; 257 258 if (log_is_enabled(Trace, class, nestmates)) { 259 ResourceMark rm(THREAD); 260 log_trace(class, nestmates)("Resolved nest-host of %s to %s", 261 this->external_name(), k->external_name()); 262 } 263 return nest_host_k; 264 } 265 else { 266 error = "types are in different packages"; 267 } 268 } 269 else { 270 error = "current type is not listed as a nest member"; 271 } 272 } 273 else { 274 error = "nest-host is not an instance class!"; 275 } 276 277 if (log_is_enabled(Trace, class, nestmates)) { 278 ResourceMark rm(THREAD); 279 log_trace(class, nestmates)("Type %s is not a nest member of resolved type %s: %s", 280 this->external_name(), 281 k->external_name(), 282 error); 283 } 284 285 if (validationException != NULL) { 286 ResourceMark rm(THREAD); 287 Exceptions::fthrow(THREAD_AND_LOCATION, 288 validationException, 289 "Type %s is not a nest member of %s: %s", 290 this->external_name(), 291 k->external_name(), 292 error 293 ); 294 } 297 else { 298 if (log_is_enabled(Trace, class, nestmates)) { 299 ResourceMark rm(THREAD); 300 log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", 301 this->external_name()); 302 } 303 // save resolved nest-host value 304 return (_nest_host = this); 305 } 306 } 307 return nest_host_k; 308 } 309 310 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, 311 // or we are k's nest_host - all of which is covered by comparing the two 312 // resolved_nest_hosts 313 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { 314 315 assert(this != k, "this should be handled by higher-level code"); 316 317 // Per the JVMS we first resolve and validate the current class, then 318 // the target class k. Resolution exceptions will be passed on by upper 319 // layers. IllegalAccessErrors from membership validation failures will 320 // also be passed through. 321 322 Symbol* iae = vmSymbols::java_lang_IllegalAccessError(); 323 InstanceKlass* cur_host = nest_host(iae, THREAD); 324 if (cur_host == NULL || HAS_PENDING_EXCEPTION) { 325 return false; 326 } 327 328 Klass* k_nest_host = k->nest_host(iae, THREAD); 329 if (k_nest_host == NULL || HAS_PENDING_EXCEPTION) { 330 return false; 331 } 332 333 bool access = (cur_host == k_nest_host); 334 335 if (log_is_enabled(Trace, class, nestmates)) { 336 ResourceMark rm(THREAD); 337 log_trace(class, nestmates)("Class %s does %shave nestmate accesss to %s", 338 this->external_name(), 339 access ? "" : "NOT ", 340 k->external_name()); 341 } 342 343 return access; 344 } 345 346 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { 347 const int size = InstanceKlass::size(parser.vtable_size(), 348 parser.itable_size(), | 225 ResourceMark rm(THREAD); 226 char buf[200]; 227 CLEAR_PENDING_EXCEPTION; 228 jio_snprintf(buf, sizeof(buf), 229 "Unable to load nest-host class (%s) of %s", 230 _constants->klass_name_at(_nest_host_index)->as_C_string(), 231 this->external_name()); 232 log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); 233 THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); 234 } 235 // other exceptions pass through (OOME, StackOverflowError etc) 236 return NULL; 237 } 238 239 // A valid nest-host is an instance class in the current package that lists this 240 // class as a nest member. If any of these conditions are not met we post the 241 // requested exception type (if any) and return NULL 242 243 const char* error = NULL; 244 245 // JVMS 5.4.4 indicates package check comes first 246 if (is_same_class_package(k)) { 247 248 // Now check actual membership. We can't be a member if our "host" is 249 // not an instance class. 250 if (k->is_instance_klass()) { 251 nest_host_k = InstanceKlass::cast(k); 252 253 // FIXME: an exception from this is perhaps impossible 254 bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); 255 if (is_member) { 256 // save resolved nest-host value 257 _nest_host = nest_host_k; 258 259 if (log_is_enabled(Trace, class, nestmates)) { 260 ResourceMark rm(THREAD); 261 log_trace(class, nestmates)("Resolved nest-host of %s to %s", 262 this->external_name(), k->external_name()); 263 } 264 return nest_host_k; 265 } 266 } 267 error = "current type is not listed as a nest member"; 268 } 269 else { 270 error = "types are in different packages"; 271 } 272 273 if (log_is_enabled(Trace, class, nestmates)) { 274 ResourceMark rm(THREAD); 275 log_trace(class, nestmates)("Type %s is not a nest member of resolved type %s: %s", 276 this->external_name(), 277 k->external_name(), 278 error); 279 } 280 281 if (validationException != NULL) { 282 ResourceMark rm(THREAD); 283 Exceptions::fthrow(THREAD_AND_LOCATION, 284 validationException, 285 "Type %s is not a nest member of %s: %s", 286 this->external_name(), 287 k->external_name(), 288 error 289 ); 290 } 293 else { 294 if (log_is_enabled(Trace, class, nestmates)) { 295 ResourceMark rm(THREAD); 296 log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", 297 this->external_name()); 298 } 299 // save resolved nest-host value 300 return (_nest_host = this); 301 } 302 } 303 return nest_host_k; 304 } 305 306 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, 307 // or we are k's nest_host - all of which is covered by comparing the two 308 // resolved_nest_hosts 309 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { 310 311 assert(this != k, "this should be handled by higher-level code"); 312 313 // Per JVMS 5.4.4 we first resolve and validate the current class, then 314 // the target class k. Resolution exceptions will be passed on by upper 315 // layers. IncompatibleClassChangeErrors from membership validation failures 316 // will also be passed through. 317 318 Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); 319 InstanceKlass* cur_host = nest_host(icce, THREAD); 320 if (cur_host == NULL || HAS_PENDING_EXCEPTION) { 321 return false; 322 } 323 324 Klass* k_nest_host = k->nest_host(icce, THREAD); 325 if (k_nest_host == NULL || HAS_PENDING_EXCEPTION) { 326 return false; 327 } 328 329 bool access = (cur_host == k_nest_host); 330 331 if (log_is_enabled(Trace, class, nestmates)) { 332 ResourceMark rm(THREAD); 333 log_trace(class, nestmates)("Class %s does %shave nestmate accesss to %s", 334 this->external_name(), 335 access ? "" : "NOT ", 336 k->external_name()); 337 } 338 339 return access; 340 } 341 342 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { 343 const int size = InstanceKlass::size(parser.vtable_size(), 344 parser.itable_size(), |