8159507: RuntimeVisibleAnnotation validation

Thu, 11 Aug 2016 12:17:39 +0300

author
vkempik
date
Thu, 11 Aug 2016 12:17:39 +0300
changeset 8679
fff265b31090
parent 8678
57f957f4731d
child 8680
6009b66f2fa1

8159507: RuntimeVisibleAnnotation validation
Reviewed-by: rprotacio

src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/classFileParser.cpp	Tue Aug 09 13:24:03 2016 -0700
     1.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Thu Aug 11 12:17:39 2016 +0300
     1.3 @@ -944,11 +944,12 @@
     1.4          runtime_visible_annotations_length = attribute_length;
     1.5          runtime_visible_annotations = cfs->get_u1_buffer();
     1.6          assert(runtime_visible_annotations != NULL, "null visible annotations");
     1.7 +        cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
     1.8          parse_annotations(runtime_visible_annotations,
     1.9                            runtime_visible_annotations_length,
    1.10                            parsed_annotations,
    1.11                            CHECK);
    1.12 -        cfs->skip_u1(runtime_visible_annotations_length, CHECK);
    1.13 +        cfs->skip_u1_fast(runtime_visible_annotations_length);
    1.14        } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
    1.15          runtime_invisible_annotations_length = attribute_length;
    1.16          runtime_invisible_annotations = cfs->get_u1_buffer();
    1.17 @@ -1655,6 +1656,11 @@
    1.18    return index;
    1.19  }
    1.20  
    1.21 +// Safely increment index by val if does not pass limit
    1.22 +#define SAFE_ADD(index, limit, val) \
    1.23 +if (index >= limit - val) return limit; \
    1.24 +index += val;
    1.25 +
    1.26  // Skip an annotation value.  Return >=limit if there is any problem.
    1.27  int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
    1.28    // value := switch (tag:u1) {
    1.29 @@ -1665,19 +1671,19 @@
    1.30    //   case @: annotation;
    1.31    //   case s: s_con:u2;
    1.32    // }
    1.33 -  if ((index += 1) >= limit)  return limit;  // read tag
    1.34 +  SAFE_ADD(index, limit, 1); // read tag
    1.35    u1 tag = buffer[index-1];
    1.36    switch (tag) {
    1.37    case 'B': case 'C': case 'I': case 'S': case 'Z':
    1.38    case 'D': case 'F': case 'J': case 'c': case 's':
    1.39 -    index += 2;  // skip con or s_con
    1.40 +    SAFE_ADD(index, limit, 2);  // skip con or s_con
    1.41      break;
    1.42    case 'e':
    1.43 -    index += 4;  // skip e_class, e_name
    1.44 +    SAFE_ADD(index, limit, 4);  // skip e_class, e_name
    1.45      break;
    1.46    case '[':
    1.47      {
    1.48 -      if ((index += 2) >= limit)  return limit;  // read nval
    1.49 +      SAFE_ADD(index, limit, 2);  // read nval
    1.50        int nval = Bytes::get_Java_u2(buffer+index-2);
    1.51        while (--nval >= 0 && index < limit) {
    1.52          index = skip_annotation_value(buffer, limit, index);
    1.53 @@ -1699,8 +1705,8 @@
    1.54                                          ClassFileParser::AnnotationCollector* coll,
    1.55                                          TRAPS) {
    1.56    // annotations := do(nann:u2) {annotation}
    1.57 -  int index = 0;
    1.58 -  if ((index += 2) >= limit)  return;  // read nann
    1.59 +  int index = 2;
    1.60 +  if (index >= limit)  return;  // read nann
    1.61    int nann = Bytes::get_Java_u2(buffer+index-2);
    1.62    enum {  // initial annotation layout
    1.63      atype_off = 0,      // utf8 such as 'Ljava/lang/annotation/Retention;'
    1.64 @@ -1719,7 +1725,8 @@
    1.65        s_size = 9,
    1.66      min_size = 6        // smallest possible size (zero members)
    1.67    };
    1.68 -  while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
    1.69 +  // Cannot add min_size to index in case of overflow MAX_INT
    1.70 +  while ((--nann) >= 0 && (index-2 <= limit - min_size)) {
    1.71      int index0 = index;
    1.72      index = skip_annotation(buffer, limit, index);
    1.73      u1* abase = buffer + index0;
    1.74 @@ -2324,10 +2331,11 @@
    1.75          runtime_visible_annotations_length = method_attribute_length;
    1.76          runtime_visible_annotations = cfs->get_u1_buffer();
    1.77          assert(runtime_visible_annotations != NULL, "null visible annotations");
    1.78 +        cfs->guarantee_more(runtime_visible_annotations_length, CHECK_(nullHandle));
    1.79          parse_annotations(runtime_visible_annotations,
    1.80              runtime_visible_annotations_length, &parsed_annotations,
    1.81              CHECK_(nullHandle));
    1.82 -        cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
    1.83 +        cfs->skip_u1_fast(runtime_visible_annotations_length);
    1.84        } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
    1.85          runtime_invisible_annotations_length = method_attribute_length;
    1.86          runtime_invisible_annotations = cfs->get_u1_buffer();
    1.87 @@ -2953,11 +2961,12 @@
    1.88          runtime_visible_annotations_length = attribute_length;
    1.89          runtime_visible_annotations = cfs->get_u1_buffer();
    1.90          assert(runtime_visible_annotations != NULL, "null visible annotations");
    1.91 +        cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
    1.92          parse_annotations(runtime_visible_annotations,
    1.93                            runtime_visible_annotations_length,
    1.94                            parsed_annotations,
    1.95                            CHECK);
    1.96 -        cfs->skip_u1(runtime_visible_annotations_length, CHECK);
    1.97 +        cfs->skip_u1_fast(runtime_visible_annotations_length);
    1.98        } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
    1.99          runtime_invisible_annotations_length = attribute_length;
   1.100          runtime_invisible_annotations = cfs->get_u1_buffer();

mercurial