changeset 5120:6406d31bdc1a

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
author hseigel
date Thu, 20 Mar 2014 08:46:41 -0400
parents 9d49f3448114
children 7d83f2b1a320
files src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/classFileParser.hpp
diffstat 2 files changed, 37 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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));
--- 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);