# HG changeset patch # User hseigel # Date 1395319601 14400 # Node ID 6406d31bdc1a5c176fb71918a6b9f9c3645c12d6 # Parent 9d49f34481140beb58460844ab28f633957a8288 8034985: Better form for Lambda Forms Summary: Only allow classes loaded by boot or extensions class loaders, or anonymous classes, to access privileged annotations. Reviewed-by: coleenp, ahgross, twisti diff -r 9d49f3448114 -r 6406d31bdc1a src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Tue Mar 04 15:58:08 2014 -0500 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Mar 20 08:46:41 2014 -0400 @@ -1698,7 +1698,8 @@ } // Sift through annotations, looking for those significant to the VM: -void ClassFileParser::parse_annotations(u1* buffer, int limit, +void ClassFileParser::parse_annotations(Handle class_loader, + u1* buffer, int limit, constantPoolHandle cp, ClassFileParser::AnnotationCollector* coll, TRAPS) { @@ -1736,7 +1737,7 @@ } // Here is where parsing particular annotations will take place. - AnnotationCollector::ID id = coll->annotation_index(aname); + AnnotationCollector::ID id = coll->annotation_index(class_loader, is_anonymous(), aname); if (id == AnnotationCollector::_unknown) continue; coll->set_annotation(id); // If there are no values, just set the bit and move on: @@ -1765,20 +1766,30 @@ } } -ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) { +ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Handle class_loader, + bool is_anonymous, + Symbol* name) { vmSymbols::SID sid = vmSymbols::find_sid(name); + // Privileged code can use all annotations. Other code silently drops some. + const bool privileged = class_loader.is_null() || is_anonymous || + class_loader()->klass()->klass_part()->name() == + vmSymbols::sun_misc_Launcher_ExtClassLoader(); switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_ForceInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_DontInline; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Compiled; case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature): if (_location != _in_method) break; // only allow for methods + if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; default: break; } @@ -1818,8 +1829,8 @@ // from the method back up to the containing klass. These flag values // are added to klass's access_flags. -methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface, - AccessFlags *promoted_flags, +methodHandle ClassFileParser::parse_method(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags *promoted_flags, typeArrayHandle* method_annotations, typeArrayHandle* method_parameter_annotations, typeArrayHandle* method_default_annotations, @@ -2128,7 +2139,7 @@ runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); + parse_annotations(class_loader, runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = method_attribute_length; @@ -2357,8 +2368,8 @@ // from the methods back up to the containing klass. These flag values // are added to klass's access_flags. -objArrayHandle ClassFileParser::parse_methods(constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, +objArrayHandle ClassFileParser::parse_methods(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, objArrayOop* methods_annotations_oop, objArrayOop* methods_parameter_annotations_oop, @@ -2381,7 +2392,8 @@ objArrayHandle methods_parameter_annotations; objArrayHandle methods_default_annotations; for (int index = 0; index < length; index++) { - methodHandle method = parse_method(cp, is_interface, + methodHandle method = parse_method(class_loader, cp, + is_interface, promoted_flags, &method_annotations, &method_parameter_annotations, @@ -2726,7 +2738,8 @@ } -void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, +void ClassFileParser::parse_classfile_attributes(Handle class_loader, + constantPoolHandle cp, ClassFileParser::ClassAnnotationCollector* parsed_annotations, TRAPS) { ClassFileStream* cfs = stream(); @@ -2809,7 +2822,8 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - parse_annotations(runtime_visible_annotations, + parse_annotations(class_loader, + runtime_visible_annotations, runtime_visible_annotations_length, cp, parsed_annotations, @@ -3172,7 +3186,8 @@ objArrayOop methods_annotations_oop = NULL; objArrayOop methods_parameter_annotations_oop = NULL; objArrayOop methods_default_annotations_oop = NULL; - objArrayHandle methods = parse_methods(cp, access_flags.is_interface(), + objArrayHandle methods = parse_methods(class_loader, cp, + access_flags.is_interface(), &promoted_flags, &has_final_method, &methods_annotations_oop, @@ -3186,7 +3201,7 @@ // Additional attributes ClassAnnotationCollector parsed_annotations; - parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle)); + parse_classfile_attributes(class_loader, cp, &parsed_annotations, CHECK_(nullHandle)); // Make sure this is the end of class file stream guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); diff -r 9d49f3448114 -r 6406d31bdc1a src/share/vm/classfile/classFileParser.hpp --- a/src/share/vm/classfile/classFileParser.hpp Tue Mar 04 15:58:08 2014 -0500 +++ b/src/share/vm/classfile/classFileParser.hpp Thu Mar 20 08:46:41 2014 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,7 +102,7 @@ assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, ""); } // If this annotation name has an ID, report it (or _none). - ID annotation_index(Symbol* name); + ID annotation_index(Handle class_loader, bool is_anonymous, Symbol* name); // Set the annotation name: void set_annotation(ID id) { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); @@ -169,14 +169,14 @@ u2* java_fields_count_ptr, TRAPS); // Method parsing - methodHandle parse_method(constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, + methodHandle parse_method(Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, typeArrayHandle* method_annotations, typeArrayHandle* method_parameter_annotations, typeArrayHandle* method_default_annotations, TRAPS); - objArrayHandle parse_methods (constantPoolHandle cp, bool is_interface, - AccessFlags* promoted_flags, + objArrayHandle parse_methods (Handle class_loader, constantPoolHandle cp, + bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, objArrayOop* methods_annotations_oop, objArrayOop* methods_parameter_annotations_oop, @@ -210,7 +210,8 @@ u2 enclosing_method_method_index, constantPoolHandle cp, TRAPS); - void parse_classfile_attributes(constantPoolHandle cp, + void parse_classfile_attributes(Handle class_loader, + constantPoolHandle cp, ClassAnnotationCollector* parsed_annotations, TRAPS); void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS); @@ -224,7 +225,7 @@ int runtime_invisible_annotations_length, TRAPS); int skip_annotation(u1* buffer, int limit, int index); int skip_annotation_value(u1* buffer, int limit, int index); - void parse_annotations(u1* buffer, int limit, constantPoolHandle cp, + void parse_annotations(Handle class_loader, u1* buffer, int limit, constantPoolHandle cp, /* Results (currently, only one result is supported): */ AnnotationCollector* result, TRAPS);