src/share/vm/classfile/verifier.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_8050485_4 Sdiff src/share/vm/classfile

src/share/vm/classfile/verifier.cpp

Print this page




2200       if (is_protected_access(current_class(), ref_class_oop, field_name,
2201                               field_sig, false)) {
2202         // It's protected access, check if stack object is assignable to
2203         // current class.
2204         is_assignable = current_type().is_assignable_from(
2205           stack_object_type, this, CHECK_VERIFY(this));
2206         if (!is_assignable) {
2207           verify_error(ErrorContext::bad_type(bci,
2208               current_frame->stack_top_ctx(),
2209               TypeOrigin::implicit(current_type())),
2210               "Bad access to protected data in getfield");
2211           return;
2212         }
2213       }
2214       break;
2215     }
2216     default: ShouldNotReachHere();
2217   }
2218 }
2219 























































































































































































2220 void ClassVerifier::verify_invoke_init(
2221     RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
2222     StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
2223     constantPoolHandle cp, TRAPS) {
2224   u2 bci = bcs->bci();
2225   VerificationType type = current_frame->pop_stack(
2226     VerificationType::reference_check(), CHECK_VERIFY(this));
2227   if (type == VerificationType::uninitialized_this_type()) {
2228     // The method must be an <init> method of this class or its superclass
2229     Klass* superk = current_class()->super();
2230     if (ref_class_type.name() != current_class()->name() &&
2231         ref_class_type.name() != superk->name()) {
2232       verify_error(ErrorContext::bad_type(bci,
2233           TypeOrigin::implicit(ref_class_type),
2234           TypeOrigin::implicit(current_type())),
2235           "Bad <init> method call");
2236       return;
2237     }
2238 
2239     // Make sure that this call is not done from within a TRY block because
2240     // that can result in returning an incomplete object.  Simply checking
2241     // (bci >= start_pc) also ensures that this call is not done after a TRY
2242     // block.  That is also illegal because this call must be the first Java
2243     // statement in the constructor.
2244     ExceptionTable exhandlers(_method());
2245     int exlength = exhandlers.length();
2246     for(int i = 0; i < exlength; i++) {
2247       if (bci >= exhandlers.start_pc(i)) {




2248         verify_error(ErrorContext::bad_code(bci),
2249                      "Bad <init> method call from after the start of a try block");
2250         return;






2251       }
2252     }
2253 
2254     current_frame->initialize_object(type, current_type());
2255     *this_uninit = true;
2256   } else if (type.is_uninitialized()) {
2257     u2 new_offset = type.bci();
2258     address new_bcp = bcs->bcp() - bci + new_offset;
2259     if (new_offset > (code_length - 3) || (*new_bcp) != Bytecodes::_new) {
2260       /* Unreachable?  Stack map parsing ensures valid type and new
2261        * instructions have a valid BCI. */
2262       verify_error(ErrorContext::bad_code(new_offset),
2263                    "Expecting new instruction");
2264       return;
2265     }
2266     u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1);
2267     verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this));
2268 
2269     // The method must be an <init> method of the indicated class
2270     VerificationType new_class_type = cp_index_to_type(




2200       if (is_protected_access(current_class(), ref_class_oop, field_name,
2201                               field_sig, false)) {
2202         // It's protected access, check if stack object is assignable to
2203         // current class.
2204         is_assignable = current_type().is_assignable_from(
2205           stack_object_type, this, CHECK_VERIFY(this));
2206         if (!is_assignable) {
2207           verify_error(ErrorContext::bad_type(bci,
2208               current_frame->stack_top_ctx(),
2209               TypeOrigin::implicit(current_type())),
2210               "Bad access to protected data in getfield");
2211           return;
2212         }
2213       }
2214       break;
2215     }
2216     default: ShouldNotReachHere();
2217   }
2218 }
2219 
2220 // Look at the method's handlers.  If the bci is in the handler's try block
2221 // then check if the handler_pc is already on the stack.  If not, push it.
2222 void ClassVerifier::push_handlers(ExceptionTable* exhandlers,
2223                                   GrowableArray<u4>* handler_stack,
2224                                   u4 bci) {
2225   int exlength = exhandlers->length();
2226   for(int x = 0; x < exlength; x++) {
2227     if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) {
2228       handler_stack->append_if_missing(exhandlers->handler_pc(x));
2229     }
2230   }
2231 }
2232 
2233 // Return TRUE if all code paths starting with start_bc_offset end in athrow.
2234 bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
2235   // Create bytecode stream.
2236   RawBytecodeStream bcs(method());
2237   u4 code_length = method()->code_size();
2238   bcs.set_interval(start_bc_offset, code_length);
2239   u4 target;
2240   // Create stack for storing bytecode intervals for if*, goto*, and *switch.
2241   GrowableArray<u4>* bci_stack = new GrowableArray<u4>(50);
2242   // Create stack for handlers for try blocks containing this handler.
2243   GrowableArray<u4>* handler_stack = new GrowableArray<u4>(50);
2244   // Create list of visited branch opcodes (goto* and if*).
2245   GrowableArray<u4>* visited_branches = new GrowableArray<u4>(50);
2246   ExceptionTable exhandlers(_method());
2247 
2248   while (true) {
2249     if (bcs.is_last_bytecode()) {
2250       // if no more intervals to parse or if at the end of the method
2251       // then return false.
2252       if ((bci_stack->is_empty()) || ((u4)bcs.end_bci() == code_length))
2253         return false;
2254       // Pop a bytecode interval and scan that interval.
2255       u4 end_offset = pop_bci_end_offset(bci_stack);
2256       u4 start_offset = pop_bci_start_offset(bci_stack);
2257       assert(end_offset >= start_offset, "Messed up bytecode offsets");
2258       bcs.set_interval(start_offset, end_offset);
2259     }
2260     Bytecodes::Code opcode = bcs.raw_next();
2261     u4 bci = bcs.bci();
2262 
2263     // If the bytecode is in a TRY block, push its handlers so they
2264     // will get parsed.
2265     push_handlers(&exhandlers, handler_stack, bci);
2266 
2267     switch (opcode) {
2268       case Bytecodes::_if_icmpeq:
2269       case Bytecodes::_if_icmpne:
2270       case Bytecodes::_if_icmplt:
2271       case Bytecodes::_if_icmpge:
2272       case Bytecodes::_if_icmpgt:
2273       case Bytecodes::_if_icmple:
2274       case Bytecodes::_ifeq:
2275       case Bytecodes::_ifne:
2276       case Bytecodes::_iflt:
2277       case Bytecodes::_ifge:
2278       case Bytecodes::_ifgt:
2279       case Bytecodes::_ifle:
2280       case Bytecodes::_if_acmpeq:
2281       case Bytecodes::_if_acmpne:
2282       case Bytecodes::_ifnull:
2283       case Bytecodes::_ifnonnull:
2284         target = bcs.dest();
2285         if (visited_branches->contains(bci)) {
2286           if (bci_stack->is_empty()) return true;
2287           u4 end_offset = pop_bci_end_offset(bci_stack);
2288           u4 start_offset = pop_bci_start_offset(bci_stack);
2289           assert(end_offset >= start_offset, "Mixed up bytecode offsets");
2290           bcs.set_interval(start_offset, end_offset);
2291         } else {
2292           if (target > bci) { // forward branch
2293             if (target >= code_length) return false;
2294             // Push the branch target interval onto the stack.
2295             push_bci_offsets(bci_stack, target, code_length);
2296             // then, scan bytecodes up to the target.
2297             bcs.set_interval(bcs.next_bci(), target);
2298           } else { // backward branch
2299             // Push the interval following the backward branch onto the stack.
2300             push_bci_offsets(bci_stack, bcs.next_bci(), bcs.end_bci());
2301             // Check bytecodes between the branch target and the current offset.
2302             bcs.set_interval(target, bci);
2303           }
2304           // Record target so we don't branch here again.
2305           visited_branches->append(bci);
2306         }
2307         break;
2308 
2309       case Bytecodes::_goto:
2310       case Bytecodes::_goto_w:
2311         target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w());
2312         if (visited_branches->contains(bci)) {
2313           if (bci_stack->is_empty()) return true;
2314           u4 end_offset = pop_bci_end_offset(bci_stack);
2315           u4 start_offset = pop_bci_start_offset(bci_stack);
2316           assert(end_offset >= start_offset, "Mixed up bytecode offsets");
2317           bcs.set_interval(start_offset, end_offset);
2318         } else {
2319           if (target >= code_length) return false;
2320           // Continue scanning from the target onward.
2321           bcs.set_interval(target, code_length);
2322           // Record target so we don't branch here again.
2323           visited_branches->append(bci);
2324         }
2325         break;
2326 
2327       // Check that all switch alternatives end in 'athrow' bytecodes. Since it
2328       // is  difficult to determine where each switch alternative ends, parse
2329       // each switch alternative until either hit a 'return', 'athrow', or reach
2330       // the end of the method's bytecodes.  This is gross but should be okay
2331       // because:
2332       // 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
2333       //    constructor invocations should be rare.
2334       // 2. if each switch alternative ends in an athrow then the parsing should be
2335       //    short.  If there is no athrow then it is bogus code, anyway.
2336       case Bytecodes::_lookupswitch:
2337       case Bytecodes::_tableswitch:
2338         {
2339           address aligned_bcp = (address) round_to((intptr_t)(bcs.bcp() + 1), jintSize);
2340           u4 default_offset = Bytes::get_Java_u4(aligned_bcp) + bci;
2341           int keys, delta;
2342           if (opcode == Bytecodes::_tableswitch) {
2343             jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
2344             jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
2345             // This is invalid, but let the regular bytecode verifier
2346             // report this because the user will get a better error message.
2347             if (low > high) return true;
2348             keys = high - low + 1;
2349             delta = 1;
2350           } else {
2351             keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
2352             delta = 2;
2353           }
2354           // Invalid, let the regular bytecode verifier deal with it.
2355           if (keys < 0) return true;
2356 
2357           // Push the current state onto the stack.
2358           push_bci_offsets(bci_stack, bcs.next_bci(), bcs.end_bci());
2359 
2360           // Push the switch alternatives onto the stack.
2361           for (int i = 0; i < keys; i++) {
2362             u4 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2363             if (target > code_length) return false;
2364             push_bci_offsets(bci_stack, target, code_length);
2365           }
2366 
2367           // Start bytecode parsing for the switch at the default alternative.
2368           if (default_offset > code_length) return false;
2369           bcs.set_interval(default_offset, code_length);
2370           break;
2371         }
2372 
2373       case Bytecodes::_return:
2374         return false;
2375 
2376       case Bytecodes::_athrow:
2377         {
2378           if (bci_stack->is_empty()) {
2379             if (handler_stack->is_empty()) {
2380               return true;
2381             } else {
2382               // Parse the catch handlers for try blocks containing athrow.
2383               bcs.set_interval(handler_stack->pop(), code_length);
2384             }
2385           } else {
2386             // Pop a bytecode interval and scan that interval.
2387             u4 end_offset = pop_bci_end_offset(bci_stack);
2388             u4 start_offset = pop_bci_start_offset(bci_stack);
2389             assert(end_offset >= start_offset, "Mixed up bytecode offsets");
2390             bcs.set_interval(start_offset, end_offset);
2391           }
2392         }
2393         break;
2394 
2395       default:
2396         ;
2397     } // end switch
2398   } // end while loop
2399 
2400   return false;
2401 }
2402 
2403 void ClassVerifier::verify_invoke_init(
2404     RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
2405     StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
2406     constantPoolHandle cp, TRAPS) {
2407   u2 bci = bcs->bci();
2408   VerificationType type = current_frame->pop_stack(
2409     VerificationType::reference_check(), CHECK_VERIFY(this));
2410   if (type == VerificationType::uninitialized_this_type()) {
2411     // The method must be an <init> method of this class or its superclass
2412     Klass* superk = current_class()->super();
2413     if (ref_class_type.name() != current_class()->name() &&
2414         ref_class_type.name() != superk->name()) {
2415       verify_error(ErrorContext::bad_type(bci,
2416           TypeOrigin::implicit(ref_class_type),
2417           TypeOrigin::implicit(current_type())),
2418           "Bad <init> method call");
2419       return;
2420     }
2421 
2422     // Check if this call is done from inside of a TRY block.  If so, make
2423     // sure that all catch clause paths end in a throw.  Otherwise, this
2424     // can result in returning an incomplete object.


2425     ExceptionTable exhandlers(_method());
2426     int exlength = exhandlers.length();
2427     for(int i = 0; i < exlength; i++) {
2428       u2 start_pc = exhandlers.start_pc(i);
2429       u2 end_pc = exhandlers.end_pc(i);
2430 
2431       if (bci >= start_pc && bci < end_pc) {
2432         if (!ends_in_athrow(exhandlers.handler_pc(i))) {
2433           verify_error(ErrorContext::bad_code(bci),
2434             "Bad <init> method call from after the start of a try block");
2435           return;
2436         } else if (VerboseVerification) {
2437           ResourceMark rm;
2438           tty->print_cr(
2439             "Survived call to ends_in_athrow(): %s",
2440                         current_class()->name()->as_C_string());
2441         }
2442       }
2443     }
2444 
2445     current_frame->initialize_object(type, current_type());
2446     *this_uninit = true;
2447   } else if (type.is_uninitialized()) {
2448     u2 new_offset = type.bci();
2449     address new_bcp = bcs->bcp() - bci + new_offset;
2450     if (new_offset > (code_length - 3) || (*new_bcp) != Bytecodes::_new) {
2451       /* Unreachable?  Stack map parsing ensures valid type and new
2452        * instructions have a valid BCI. */
2453       verify_error(ErrorContext::bad_code(new_offset),
2454                    "Expecting new instruction");
2455       return;
2456     }
2457     u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1);
2458     verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this));
2459 
2460     // The method must be an <init> method of the indicated class
2461     VerificationType new_class_type = cp_index_to_type(


src/share/vm/classfile/verifier.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File