提交 53669696 编写于 作者: V vkempik

8159507: RuntimeVisibleAnnotation validation

Reviewed-by: rprotacio
上级 704ab198
...@@ -944,11 +944,12 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count, ...@@ -944,11 +944,12 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
runtime_visible_annotations_length = attribute_length; runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer(); runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, runtime_visible_annotations_length,
parsed_annotations, parsed_annotations,
CHECK); CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK); cfs->skip_u1_fast(runtime_visible_annotations_length);
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length; runtime_invisible_annotations_length = attribute_length;
runtime_invisible_annotations = cfs->get_u1_buffer(); runtime_invisible_annotations = cfs->get_u1_buffer();
...@@ -1655,6 +1656,11 @@ int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) { ...@@ -1655,6 +1656,11 @@ int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) {
return index; return index;
} }
// Safely increment index by val if does not pass limit
#define SAFE_ADD(index, limit, val) \
if (index >= limit - val) return limit; \
index += val;
// Skip an annotation value. Return >=limit if there is any problem. // Skip an annotation value. Return >=limit if there is any problem.
int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
// value := switch (tag:u1) { // value := switch (tag:u1) {
...@@ -1665,19 +1671,19 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { ...@@ -1665,19 +1671,19 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
// case @: annotation; // case @: annotation;
// case s: s_con:u2; // case s: s_con:u2;
// } // }
if ((index += 1) >= limit) return limit; // read tag SAFE_ADD(index, limit, 1); // read tag
u1 tag = buffer[index-1]; u1 tag = buffer[index-1];
switch (tag) { switch (tag) {
case 'B': case 'C': case 'I': case 'S': case 'Z': case 'B': case 'C': case 'I': case 'S': case 'Z':
case 'D': case 'F': case 'J': case 'c': case 's': case 'D': case 'F': case 'J': case 'c': case 's':
index += 2; // skip con or s_con SAFE_ADD(index, limit, 2); // skip con or s_con
break; break;
case 'e': case 'e':
index += 4; // skip e_class, e_name SAFE_ADD(index, limit, 4); // skip e_class, e_name
break; break;
case '[': case '[':
{ {
if ((index += 2) >= limit) return limit; // read nval SAFE_ADD(index, limit, 2); // read nval
int nval = Bytes::get_Java_u2(buffer+index-2); int nval = Bytes::get_Java_u2(buffer+index-2);
while (--nval >= 0 && index < limit) { while (--nval >= 0 && index < limit) {
index = skip_annotation_value(buffer, limit, index); index = skip_annotation_value(buffer, limit, index);
...@@ -1699,8 +1705,8 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit, ...@@ -1699,8 +1705,8 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
ClassFileParser::AnnotationCollector* coll, ClassFileParser::AnnotationCollector* coll,
TRAPS) { TRAPS) {
// annotations := do(nann:u2) {annotation} // annotations := do(nann:u2) {annotation}
int index = 0; int index = 2;
if ((index += 2) >= limit) return; // read nann if (index >= limit) return; // read nann
int nann = Bytes::get_Java_u2(buffer+index-2); int nann = Bytes::get_Java_u2(buffer+index-2);
enum { // initial annotation layout enum { // initial annotation layout
atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
...@@ -1719,7 +1725,8 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit, ...@@ -1719,7 +1725,8 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
s_size = 9, s_size = 9,
min_size = 6 // smallest possible size (zero members) min_size = 6 // smallest possible size (zero members)
}; };
while ((--nann) >= 0 && (index-2 + min_size <= limit)) { // Cannot add min_size to index in case of overflow MAX_INT
while ((--nann) >= 0 && (index-2 <= limit - min_size)) {
int index0 = index; int index0 = index;
index = skip_annotation(buffer, limit, index); index = skip_annotation(buffer, limit, index);
u1* abase = buffer + index0; u1* abase = buffer + index0;
...@@ -2324,10 +2331,11 @@ methodHandle ClassFileParser::parse_method(bool is_interface, ...@@ -2324,10 +2331,11 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer(); runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
cfs->guarantee_more(runtime_visible_annotations_length, CHECK_(nullHandle));
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, &parsed_annotations, runtime_visible_annotations_length, &parsed_annotations,
CHECK_(nullHandle)); CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); cfs->skip_u1_fast(runtime_visible_annotations_length);
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = method_attribute_length; runtime_invisible_annotations_length = method_attribute_length;
runtime_invisible_annotations = cfs->get_u1_buffer(); runtime_invisible_annotations = cfs->get_u1_buffer();
...@@ -2953,11 +2961,12 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio ...@@ -2953,11 +2961,12 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
runtime_visible_annotations_length = attribute_length; runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer(); runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations"); assert(runtime_visible_annotations != NULL, "null visible annotations");
cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
parse_annotations(runtime_visible_annotations, parse_annotations(runtime_visible_annotations,
runtime_visible_annotations_length, runtime_visible_annotations_length,
parsed_annotations, parsed_annotations,
CHECK); CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK); cfs->skip_u1_fast(runtime_visible_annotations_length);
} else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length; runtime_invisible_annotations_length = attribute_length;
runtime_invisible_annotations = cfs->get_u1_buffer(); runtime_invisible_annotations = cfs->get_u1_buffer();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册