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

src/share/vm/classfile/verifier.cpp

Print this page




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























































































































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




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






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




2202       if (is_protected_access(current_class(), ref_class_oop, field_name,
2203                               field_sig, false)) {
2204         // It's protected access, check if stack object is assignable to
2205         // current class.
2206         is_assignable = current_type().is_assignable_from(
2207           stack_object_type, this, CHECK_VERIFY(this));
2208         if (!is_assignable) {
2209           verify_error(ErrorContext::bad_type(bci,
2210               current_frame->stack_top_ctx(),
2211               TypeOrigin::implicit(current_type())),
2212               "Bad access to protected data in getfield");
2213           return;
2214         }
2215       }
2216       break;
2217     }
2218     default: ShouldNotReachHere();
2219   }
2220 }
2221 
2222 // Make sure that all switch alternatives end in 'athrow' bytecodes.
2223 // Since it could be difficult to determine where each switch alternative
2224 // ends, parse each switch alternative until either hit a 'return', 'athrow',
2225 // or reach the end of the method's bytecodes.  This is gross but should be
2226 // okay because:
2227 // 1. tableswitch and lookupswitch byte codes in handlers for ctor explicit
2228 //    constructor invocations should be rare.
2229 // 2. if each switch alternative ends in an athrow then the parsing should be
2230 //    short.  If there is no athrow then it is bogus code, anyway.
2231 bool ClassVerifier::switch_athrows(Bytecodes::Code opcode, RawBytecodeStream* bcs) {
2232   assert(opcode == Bytecodes::_lookupswitch || opcode == Bytecodes::_tableswitch,
2233           "Bad opcode");
2234   int bci = bcs->bci();
2235   address bcp = bcs->bcp();
2236   address aligned_bcp = (address) round_to((intptr_t)(bcp + 1), jintSize);
2237   u4 default_offset = Bytes::get_Java_u4(aligned_bcp);
2238   u4 code_length = method()->code_size();
2239   int keys, delta;
2240   if (opcode == Bytecodes::_tableswitch) {
2241     jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
2242     jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
2243     // This is invalid, but let the regular bytecode verifier
2244     // report this because the user will get a better error message.
2245     if (low > high) return true;
2246     keys = high - low + 1;
2247     delta = 1;
2248   } else {
2249     keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
2250     delta = 2;
2251   }
2252 
2253   // This is invalid, but let the regular bytecode verifier
2254   // report this because the user will get a better error message.
2255   if (keys < 0) return true;
2256 
2257   if (default_offset + bci > code_length) return false;
2258   if (!ends_in_athrow(default_offset + bci, code_length, false)) return false;
2259 
2260   for (int i = 0; i < keys; i++) {
2261     u4 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2262     if (target > code_length) return false;
2263     if (!ends_in_athrow(target, code_length, false)) return false;
2264   }
2265 
2266  return true;  // All switch alternatives ended in a throw.
2267 }
2268 
2269 bool ClassVerifier::ends_in_athrow(u4 start_bc_offset, u4 end_bc_offset,
2270                                    bool reach_end_of_bc) {
2271   // Create bytecode stream.
2272   RawBytecodeStream bcs(method());
2273   bcs.set_interval(start_bc_offset, end_bc_offset);
2274   u4 code_length = method()->code_size();
2275   u4 target;
2276 
2277   while (!bcs.is_last_bytecode()) {
2278     Bytecodes::Code opcode = bcs.raw_next();
2279     u2 bci = bcs.bci();
2280 
2281     switch (opcode) {
2282       case Bytecodes::_if_icmpeq:
2283       case Bytecodes::_if_icmpne:
2284       case Bytecodes::_if_icmplt:
2285       case Bytecodes::_if_icmpge:
2286       case Bytecodes::_if_icmpgt:
2287       case Bytecodes::_if_icmple:
2288       case Bytecodes::_ifeq:
2289       case Bytecodes::_ifne:
2290       case Bytecodes::_iflt:
2291       case Bytecodes::_ifge:
2292       case Bytecodes::_ifgt:
2293       case Bytecodes::_ifle:
2294       case Bytecodes::_if_acmpeq:
2295       case Bytecodes::_if_acmpne:
2296       case Bytecodes::_ifnull:
2297       case Bytecodes::_ifnonnull:
2298         target = bcs.dest();
2299         if (target > bci) { // forward branch
2300           if (target >= code_length) return false;
2301           // scan bytecodes up to the target.
2302           if (!ends_in_athrow(bcs.next_bci(), target, true)) return false;
2303           bcs.set_next_bci(target);
2304         } else { // backward branch
2305           // Check the bytecodes between the branch target and the current offset
2306           if (!ends_in_athrow(target, bci, true)) return false;
2307         }
2308         break;
2309 
2310       case Bytecodes::_goto:
2311       case Bytecodes::_goto_w:
2312         target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w());
2313         if (target > bci) {  // forward branch
2314           if (target >= code_length) return false;
2315             return ends_in_athrow(target, code_length, false);
2316         } else { // backward branch
2317           // Check bytecodes between the branch target and the current offset.
2318           if (!ends_in_athrow(target, bci, true)) return false;
2319         }
2320         break;
2321 
2322       case Bytecodes::_lookupswitch :
2323       case Bytecodes::_tableswitch:
2324         if (!switch_athrows(opcode, &bcs)) return false;
2325         break;
2326 
2327       case Bytecodes::_return :
2328         return false;
2329 
2330       case Bytecodes::_athrow :
2331         return true;
2332 
2333       default:
2334         ;
2335     } // end switch
2336   } // end while loop
2337 
2338   return reach_end_of_bc;
2339 }
2340 
2341 void ClassVerifier::verify_invoke_init(
2342     RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
2343     StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
2344     constantPoolHandle cp, TRAPS) {
2345   u2 bci = bcs->bci();
2346   VerificationType type = current_frame->pop_stack(
2347     VerificationType::reference_check(), CHECK_VERIFY(this));
2348   if (type == VerificationType::uninitialized_this_type()) {
2349     // The method must be an <init> method of this class or its superclass
2350     Klass* superk = current_class()->super();
2351     if (ref_class_type.name() != current_class()->name() &&
2352         ref_class_type.name() != superk->name()) {
2353       verify_error(ErrorContext::bad_type(bci,
2354           TypeOrigin::implicit(ref_class_type),
2355           TypeOrigin::implicit(current_type())),
2356           "Bad <init> method call");
2357       return;
2358     }
2359 
2360     // Make sure that this call is not jumped over.
2361     if (bci < furthest_jump()) {
2362       verify_error(ErrorContext::bad_code(bci),
2363                    "Bad <init> method call from inside of a branch");
2364       return;
2365     }
2366 
2367     // Check if this call is done from inside of a TRY block.  If so, make
2368     // sure that all catch clause paths end in a throw.  Otherwise, this
2369     // can result in returning an incomplete object.


2370     ExceptionTable exhandlers(_method());
2371     int exlength = exhandlers.length();
2372     for(int i = 0; i < exlength; i++) {
2373       u2 start_pc = exhandlers.start_pc(i);
2374       u2 end_pc = exhandlers.end_pc(i);
2375 
2376       if (bci >= start_pc && bci < end_pc) {
2377         if (!ends_in_athrow(exhandlers.handler_pc(i), code_length, false)) {
2378           verify_error(ErrorContext::bad_code(bci),
2379                        "Bad <init> method call from after the start of a try block");
2380           return;
2381         } else if (VerboseVerification) {
2382           ResourceMark rm;
2383           tty->print_cr(
2384             "Survived call to ends_in_athrow(): %s",
2385             current_class()->name()->as_C_string());
2386         }
2387       }
2388     }
2389 
2390     current_frame->initialize_object(type, current_type());
2391     *this_uninit = true;
2392   } else if (type.is_uninitialized()) {
2393     u2 new_offset = type.bci();
2394     address new_bcp = bcs->bcp() - bci + new_offset;
2395     if (new_offset > (code_length - 3) || (*new_bcp) != Bytecodes::_new) {
2396       /* Unreachable?  Stack map parsing ensures valid type and new
2397        * instructions have a valid BCI. */
2398       verify_error(ErrorContext::bad_code(new_offset),
2399                    "Expecting new instruction");
2400       return;
2401     }
2402     u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1);
2403     verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this));
2404 
2405     // The method must be an <init> method of the indicated class
2406     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