comparison src/share/vm/classfile/verifier.cpp @ 20328:92baebeb744b

8050485: super() in a try block in a ctor causes VerifyError Summary: Parse catch clause paths to ensure they end in throws Reviewed-by: dlong, acorn, kamg, ctornqvi, lfoltan
author hseigel
date Tue, 12 Aug 2014 20:29:25 -0400
parents d14a18794c90
children 8cb56c8cb30d
comparison
equal deleted inserted replaced
20327:411e30e5fbb8 20328:92baebeb744b
2229 } 2229 }
2230 default: ShouldNotReachHere(); 2230 default: ShouldNotReachHere();
2231 } 2231 }
2232 } 2232 }
2233 2233
2234 // Look at the method's handlers. If the bci is in the handler's try block
2235 // then check if the handler_pc is already on the stack. If not, push it.
2236 void ClassVerifier::push_handlers(ExceptionTable* exhandlers,
2237 GrowableArray<u4>* handler_stack,
2238 u4 bci) {
2239 int exlength = exhandlers->length();
2240 for(int x = 0; x < exlength; x++) {
2241 if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) {
2242 handler_stack->append_if_missing(exhandlers->handler_pc(x));
2243 }
2244 }
2245 }
2246
2247 // Return TRUE if all code paths starting with start_bc_offset end in
2248 // bytecode athrow or loop.
2249 bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
2250 ResourceMark rm;
2251 // Create bytecode stream.
2252 RawBytecodeStream bcs(method());
2253 u4 code_length = method()->code_size();
2254 bcs.set_start(start_bc_offset);
2255 u4 target;
2256 // Create stack for storing bytecode start offsets for if* and *switch.
2257 GrowableArray<u4>* bci_stack = new GrowableArray<u4>(30);
2258 // Create stack for handlers for try blocks containing this handler.
2259 GrowableArray<u4>* handler_stack = new GrowableArray<u4>(30);
2260 // Create list of visited branch opcodes (goto* and if*).
2261 GrowableArray<u4>* visited_branches = new GrowableArray<u4>(30);
2262 ExceptionTable exhandlers(_method());
2263
2264 while (true) {
2265 if (bcs.is_last_bytecode()) {
2266 // if no more starting offsets to parse or if at the end of the
2267 // method then return false.
2268 if ((bci_stack->is_empty()) || ((u4)bcs.end_bci() == code_length))
2269 return false;
2270 // Pop a bytecode starting offset and scan from there.
2271 bcs.set_start(bci_stack->pop());
2272 }
2273 Bytecodes::Code opcode = bcs.raw_next();
2274 u4 bci = bcs.bci();
2275
2276 // If the bytecode is in a TRY block, push its handlers so they
2277 // will get parsed.
2278 push_handlers(&exhandlers, handler_stack, bci);
2279
2280 switch (opcode) {
2281 case Bytecodes::_if_icmpeq:
2282 case Bytecodes::_if_icmpne:
2283 case Bytecodes::_if_icmplt:
2284 case Bytecodes::_if_icmpge:
2285 case Bytecodes::_if_icmpgt:
2286 case Bytecodes::_if_icmple:
2287 case Bytecodes::_ifeq:
2288 case Bytecodes::_ifne:
2289 case Bytecodes::_iflt:
2290 case Bytecodes::_ifge:
2291 case Bytecodes::_ifgt:
2292 case Bytecodes::_ifle:
2293 case Bytecodes::_if_acmpeq:
2294 case Bytecodes::_if_acmpne:
2295 case Bytecodes::_ifnull:
2296 case Bytecodes::_ifnonnull:
2297 target = bcs.dest();
2298 if (visited_branches->contains(bci)) {
2299 if (bci_stack->is_empty()) return true;
2300 // Pop a bytecode starting offset and scan from there.
2301 bcs.set_start(bci_stack->pop());
2302 } else {
2303 if (target > bci) { // forward branch
2304 if (target >= code_length) return false;
2305 // Push the branch target onto the stack.
2306 bci_stack->push(target);
2307 // then, scan bytecodes starting with next.
2308 bcs.set_start(bcs.next_bci());
2309 } else { // backward branch
2310 // Push bytecode offset following backward branch onto the stack.
2311 bci_stack->push(bcs.next_bci());
2312 // Check bytecodes starting with branch target.
2313 bcs.set_start(target);
2314 }
2315 // Record target so we don't branch here again.
2316 visited_branches->append(bci);
2317 }
2318 break;
2319
2320 case Bytecodes::_goto:
2321 case Bytecodes::_goto_w:
2322 target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w());
2323 if (visited_branches->contains(bci)) {
2324 if (bci_stack->is_empty()) return true;
2325 // Been here before, pop new starting offset from stack.
2326 bcs.set_start(bci_stack->pop());
2327 } else {
2328 if (target >= code_length) return false;
2329 // Continue scanning from the target onward.
2330 bcs.set_start(target);
2331 // Record target so we don't branch here again.
2332 visited_branches->append(bci);
2333 }
2334 break;
2335
2336 // Check that all switch alternatives end in 'athrow' bytecodes. Since it
2337 // is difficult to determine where each switch alternative ends, parse
2338 // each switch alternative until either hit a 'return', 'athrow', or reach
2339 // the end of the method's bytecodes. This is gross but should be okay
2340 // because:
2341 // 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
2342 // constructor invocations should be rare.
2343 // 2. if each switch alternative ends in an athrow then the parsing should be
2344 // short. If there is no athrow then it is bogus code, anyway.
2345 case Bytecodes::_lookupswitch:
2346 case Bytecodes::_tableswitch:
2347 {
2348 address aligned_bcp = (address) round_to((intptr_t)(bcs.bcp() + 1), jintSize);
2349 u4 default_offset = Bytes::get_Java_u4(aligned_bcp) + bci;
2350 int keys, delta;
2351 if (opcode == Bytecodes::_tableswitch) {
2352 jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
2353 jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
2354 // This is invalid, but let the regular bytecode verifier
2355 // report this because the user will get a better error message.
2356 if (low > high) return true;
2357 keys = high - low + 1;
2358 delta = 1;
2359 } else {
2360 keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
2361 delta = 2;
2362 }
2363 // Invalid, let the regular bytecode verifier deal with it.
2364 if (keys < 0) return true;
2365
2366 // Push the offset of the next bytecode onto the stack.
2367 bci_stack->push(bcs.next_bci());
2368
2369 // Push the switch alternatives onto the stack.
2370 for (int i = 0; i < keys; i++) {
2371 u4 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2372 if (target > code_length) return false;
2373 bci_stack->push(target);
2374 }
2375
2376 // Start bytecode parsing for the switch at the default alternative.
2377 if (default_offset > code_length) return false;
2378 bcs.set_start(default_offset);
2379 break;
2380 }
2381
2382 case Bytecodes::_return:
2383 return false;
2384
2385 case Bytecodes::_athrow:
2386 {
2387 if (bci_stack->is_empty()) {
2388 if (handler_stack->is_empty()) {
2389 return true;
2390 } else {
2391 // Parse the catch handlers for try blocks containing athrow.
2392 bcs.set_start(handler_stack->pop());
2393 }
2394 } else {
2395 // Pop a bytecode offset and starting scanning from there.
2396 bcs.set_start(bci_stack->pop());
2397 }
2398 }
2399 break;
2400
2401 default:
2402 ;
2403 } // end switch
2404 } // end while loop
2405
2406 return false;
2407 }
2408
2234 void ClassVerifier::verify_invoke_init( 2409 void ClassVerifier::verify_invoke_init(
2235 RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type, 2410 RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
2236 StackMapFrame* current_frame, u4 code_length, bool *this_uninit, 2411 StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
2237 constantPoolHandle cp, TRAPS) { 2412 constantPoolHandle cp, TRAPS) {
2238 u2 bci = bcs->bci(); 2413 u2 bci = bcs->bci();
2248 TypeOrigin::implicit(current_type())), 2423 TypeOrigin::implicit(current_type())),
2249 "Bad <init> method call"); 2424 "Bad <init> method call");
2250 return; 2425 return;
2251 } 2426 }
2252 2427
2253 // Make sure that this call is not done from within a TRY block because 2428 // Check if this call is done from inside of a TRY block. If so, make
2254 // that can result in returning an incomplete object. Simply checking 2429 // sure that all catch clause paths end in a throw. Otherwise, this
2255 // (bci >= start_pc) also ensures that this call is not done after a TRY 2430 // can result in returning an incomplete object.
2256 // block. That is also illegal because this call must be the first Java
2257 // statement in the constructor.
2258 ExceptionTable exhandlers(_method()); 2431 ExceptionTable exhandlers(_method());
2259 int exlength = exhandlers.length(); 2432 int exlength = exhandlers.length();
2260 for(int i = 0; i < exlength; i++) { 2433 for(int i = 0; i < exlength; i++) {
2261 if (bci >= exhandlers.start_pc(i)) { 2434 u2 start_pc = exhandlers.start_pc(i);
2262 verify_error(ErrorContext::bad_code(bci), 2435 u2 end_pc = exhandlers.end_pc(i);
2263 "Bad <init> method call from after the start of a try block"); 2436
2264 return; 2437 if (bci >= start_pc && bci < end_pc) {
2438 if (!ends_in_athrow(exhandlers.handler_pc(i))) {
2439 verify_error(ErrorContext::bad_code(bci),
2440 "Bad <init> method call from after the start of a try block");
2441 return;
2442 } else if (VerboseVerification) {
2443 ResourceMark rm;
2444 tty->print_cr(
2445 "Survived call to ends_in_athrow(): %s",
2446 current_class()->name()->as_C_string());
2447 }
2265 } 2448 }
2266 } 2449 }
2267 2450
2268 current_frame->initialize_object(type, current_type()); 2451 current_frame->initialize_object(type, current_type());
2269 *this_uninit = true; 2452 *this_uninit = true;