Thu, 11 Aug 2016 12:17:39 +0300
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();