Thu, 30 Jun 2016 08:11:30 -0400
8159511: Stack map validation
Reviewed-by: acorn, mschoene
Contributed-by: harold.seigel@oracle.com
src/share/vm/classfile/stackMapTableFormat.hpp | file | annotate | diff | comparison | revisions | |
src/share/vm/classfile/verifier.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/classfile/stackMapTableFormat.hpp Tue Jul 05 14:40:55 2016 -0700 1.2 +++ b/src/share/vm/classfile/stackMapTableFormat.hpp Thu Jun 30 08:11:30 2016 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -203,6 +203,7 @@ 1.11 inline bool verify(address start, address end) const; 1.12 1.13 inline void print_on(outputStream* st, int current_offset) const; 1.14 + inline void print_truncated(outputStream* st, int current_offset) const; 1.15 1.16 // Create as_xxx and is_xxx methods for the subtypes 1.17 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \ 1.18 @@ -263,6 +264,10 @@ 1.19 void print_on(outputStream* st, int current_offset = -1) const { 1.20 st->print("same_frame(@%d)", offset_delta() + current_offset); 1.21 } 1.22 + 1.23 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.24 + print_on(st, current_offset); 1.25 + } 1.26 }; 1.27 1.28 class same_frame_extended : public stack_map_frame { 1.29 @@ -309,6 +314,10 @@ 1.30 void print_on(outputStream* st, int current_offset = -1) const { 1.31 st->print("same_frame_extended(@%d)", offset_delta() + current_offset); 1.32 } 1.33 + 1.34 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.35 + print_on(st, current_offset); 1.36 + } 1.37 }; 1.38 1.39 class same_locals_1_stack_item_frame : public stack_map_frame { 1.40 @@ -381,6 +390,11 @@ 1.41 types()->print_on(st); 1.42 st->print(")"); 1.43 } 1.44 + 1.45 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.46 + st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.", 1.47 + offset_delta() + current_offset); 1.48 + } 1.49 }; 1.50 1.51 class same_locals_1_stack_item_extended : public stack_map_frame { 1.52 @@ -446,6 +460,11 @@ 1.53 types()->print_on(st); 1.54 st->print(")"); 1.55 } 1.56 + 1.57 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.58 + st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.", 1.59 + offset_delta() + current_offset); 1.60 + } 1.61 }; 1.62 1.63 class chop_frame : public stack_map_frame { 1.64 @@ -511,6 +530,10 @@ 1.65 void print_on(outputStream* st, int current_offset = -1) const { 1.66 st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops()); 1.67 } 1.68 + 1.69 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.70 + print_on(st, current_offset); 1.71 + } 1.72 }; 1.73 1.74 class append_frame : public stack_map_frame { 1.75 @@ -619,6 +642,11 @@ 1.76 } 1.77 st->print(")"); 1.78 } 1.79 + 1.80 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.81 + st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.", 1.82 + offset_delta() + current_offset); 1.83 + } 1.84 }; 1.85 1.86 class full_frame : public stack_map_frame { 1.87 @@ -784,6 +812,11 @@ 1.88 } 1.89 st->print("})"); 1.90 } 1.91 + 1.92 + void print_truncated(outputStream* st, int current_offset = -1) const { 1.93 + st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.", 1.94 + offset_delta() + current_offset); 1.95 + } 1.96 }; 1.97 1.98 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \ 1.99 @@ -841,6 +874,10 @@ 1.100 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs)); 1.101 } 1.102 1.103 +void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const { 1.104 + FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs)); 1.105 +} 1.106 + 1.107 #undef VIRTUAL_DISPATCH 1.108 #undef VOID_VIRTUAL_DISPATCH 1.109
2.1 --- a/src/share/vm/classfile/verifier.cpp Tue Jul 05 14:40:55 2016 -0700 2.2 +++ b/src/share/vm/classfile/verifier.cpp Thu Jun 30 08:11:30 2016 -0400 2.3 @@ -504,8 +504,19 @@ 2.4 stack_map_frame* sm_frame = sm_table->entries(); 2.5 streamIndentor si2(ss); 2.6 int current_offset = -1; 2.7 + // Subtract two from StackMapAttribute length because the length includes 2.8 + // two bytes for number of table entries. 2.9 + size_t sm_table_space = method->stackmap_data()->length() - 2; 2.10 for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { 2.11 ss->indent(); 2.12 + size_t sm_frame_size = sm_frame->size(); 2.13 + // If the size of the next stackmap exceeds the length of the entire 2.14 + // stackmap table then print a truncated message and return. 2.15 + if (sm_frame_size > sm_table_space) { 2.16 + sm_frame->print_truncated(ss, current_offset); 2.17 + return; 2.18 + } 2.19 + sm_table_space -= sm_frame_size; 2.20 sm_frame->print_on(ss, current_offset); 2.21 ss->cr(); 2.22 current_offset += sm_frame->offset_delta();