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

src/share/vm/classfile/classFileParser.cpp

Print this page
rev 1449 : 6930553: classfile format checker allows invalid method descriptor in CONSTANT_NameAndType_info in some cases
Summary: Check NameAndType_info signatures aggressively, even when unreferenced
Reviewed-by:


   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 #include "incls/_precompiled.incl"
  26 #include "incls/_classFileParser.cpp.incl"
  27 
  28 // We generally try to create the oops directly when parsing, rather than allocating
  29 // temporary data structures and copying the bytes twice. A temporary area is only
  30 // needed when parsing utf8 entries in the constant pool and when parsing line number
  31 // tables.
  32 
  33 // We add assert in debug mode when class format is not checked.
  34 
  35 #define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
  36 #define JAVA_MIN_SUPPORTED_VERSION        45
  37 #define JAVA_MAX_SUPPORTED_VERSION        51
  38 #define JAVA_MAX_SUPPORTED_MINOR_VERSION  0
  39 
  40 // Used for two backward compatibility reasons:
  41 // - to check for new additions to the class file format in JDK1.5
  42 // - to check for bug fixes in the format checker in JDK1.5
  43 #define JAVA_1_5_VERSION                  49
  44 
  45 // Used for backward compatibility reasons:
  46 // - to check for javac bug fixes that happened after 1.5
  47 // - also used as the max version when running in jdk6
  48 #define JAVA_6_VERSION                    50
  49 



  50 

  51 void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) {
  52   // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
  53   // this function (_current can be allocated in a register, with scalar
  54   // replacement of aggregates). The _current pointer is copied back to
  55   // stream() when this function returns. DON'T call another method within
  56   // this method that uses stream().
  57   ClassFileStream* cfs0 = stream();
  58   ClassFileStream cfs1 = *cfs0;
  59   ClassFileStream* cfs = &cfs1;
  60 #ifdef ASSERT
  61   u1* old_current = cfs0->current();
  62 #endif
  63 
  64   // Used for batching symbol allocations.
  65   const char* names[SymbolTable::symbol_alloc_batch_size];
  66   int lengths[SymbolTable::symbol_alloc_batch_size];
  67   int indices[SymbolTable::symbol_alloc_batch_size];
  68   unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
  69   int names_count = 0;
  70 


 367                          "Unused constant pool patch at %d in class file %s",
 368                          index, CHECK_(nullHandle));
 369     }
 370   }
 371 
 372   if (!_need_verify) {
 373     return cp;
 374   }
 375 
 376   // second verification pass - checks the strings are of the right format.
 377   // but not yet to the other entries
 378   for (index = 1; index < length; index++) {
 379     jbyte tag = cp->tag_at(index).value();
 380     switch (tag) {
 381       case JVM_CONSTANT_UnresolvedClass: {
 382         symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
 383         // check the name, even if _cp_patches will overwrite it
 384         verify_legal_class_name(class_name, CHECK_(nullHandle));
 385         break;
 386       }














 387       case JVM_CONSTANT_Fieldref:
 388       case JVM_CONSTANT_Methodref:
 389       case JVM_CONSTANT_InterfaceMethodref: {
 390         int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
 391         // already verified to be utf8
 392         int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
 393         // already verified to be utf8
 394         int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index);
 395         symbolHandle name(THREAD, cp->symbol_at(name_ref_index));
 396         symbolHandle signature(THREAD, cp->symbol_at(signature_ref_index));
 397         if (tag == JVM_CONSTANT_Fieldref) {
 398           verify_legal_field_name(name, CHECK_(nullHandle));








 399           verify_legal_field_signature(name, signature, CHECK_(nullHandle));

 400         } else {
 401           verify_legal_method_name(name, CHECK_(nullHandle));








 402           verify_legal_method_signature(name, signature, CHECK_(nullHandle));

 403           if (tag == JVM_CONSTANT_Methodref) {
 404             // 4509014: If a class method name begins with '<', it must be "<init>".
 405             assert(!name.is_null(), "method name in constant pool is null");
 406             unsigned int name_len = name->utf8_length();
 407             assert(name_len > 0, "bad method name");  // already verified as legal name
 408             if (name->byte_at(0) == '<') {
 409               if (name() != vmSymbols::object_initializer_name()) {
 410                 classfile_parse_error(
 411                   "Bad method name at constant pool index %u in class file %s",
 412                   name_ref_index, CHECK_(nullHandle));
 413               }
 414             }
 415           }
 416         }
 417         break;
 418       }
 419     }  // end of switch
 420   }  // end of for
 421 
 422   return cp;


1296     u2 len = *checked_exceptions_length;
1297     cfs->guarantee_more(2 * len, CHECK_NULL);
1298     for (int i = 0; i < len; i++) {
1299       checked_exception = cfs->get_u2_fast();
1300       check_property(
1301         valid_cp_range(checked_exception, cp->length()) &&
1302         is_klass_reference(cp, checked_exception),
1303         "Exception name has bad type at constant pool %u in class file %s",
1304         checked_exception, CHECK_NULL);
1305     }
1306   }
1307   // check exceptions attribute length
1308   if (_need_verify) {
1309     guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) +
1310                                                    sizeof(u2) * size),
1311                       "Exceptions attribute has wrong length in class file %s", CHECK_NULL);
1312   }
1313   return checked_exceptions_start;
1314 }
1315 








1316 
1317 #define MAX_ARGS_SIZE 255
1318 #define MAX_CODE_SIZE 65535
1319 #define INITIAL_MAX_LVT_NUMBER 256
1320 
1321 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions
1322 // attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
1323 // methodOop to save footprint, so we only know the size of the resulting methodOop when the
1324 // entire method attribute is parsed.
1325 //
1326 // The promoted_flags parameter is used to pass relevant access_flags
1327 // from the method back up to the containing klass. These flag values
1328 // are added to klass's access_flags.
1329 
1330 methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface,
1331                                            AccessFlags *promoted_flags,
1332                                            typeArrayHandle* method_annotations,
1333                                            typeArrayHandle* method_parameter_annotations,
1334                                            typeArrayHandle* method_default_annotations,
1335                                            TRAPS) {


4041       THREAD_AND_LOCATION,
4042       vmSymbolHandles::java_lang_ClassFormatError(),
4043       "Illegal method name \"%s\" in class %s", bytes,
4044       _class_name->as_C_string()
4045     );
4046     return;
4047   }
4048 }
4049 
4050 
4051 // Checks if signature is a legal field signature.
4052 void ClassFileParser::verify_legal_field_signature(symbolHandle name, symbolHandle signature, TRAPS) {
4053   if (!_need_verify) { return; }
4054 
4055   char buf[fixed_buffer_size];
4056   char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
4057   unsigned int length = signature->utf8_length();
4058   char* p = skip_over_field_signature(bytes, false, length, CHECK);
4059 
4060   if (p == NULL || (p - bytes) != (int)length) {
4061     ResourceMark rm(THREAD);
4062     Exceptions::fthrow(
4063       THREAD_AND_LOCATION,
4064       vmSymbolHandles::java_lang_ClassFormatError(),
4065       "Field \"%s\" in class %s has illegal signature \"%s\"",
4066       name->as_C_string(), _class_name->as_C_string(), bytes
4067     );
4068     return;
4069   }
4070 }
4071 
4072 // Checks if signature is a legal method signature.
4073 // Returns number of parameters
4074 int ClassFileParser::verify_legal_method_signature(symbolHandle name, symbolHandle signature, TRAPS) {
4075   if (!_need_verify) {
4076     // make sure caller's args_size will be less than 0 even for non-static
4077     // method so it will be recomputed in compute_size_of_parameters().
4078     return -2;
4079   }
4080 
4081   unsigned int args_size = 0;
4082   char buf[fixed_buffer_size];
4083   char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
4084   unsigned int length = signature->utf8_length();
4085   char* nextp;
4086 
4087   // The first character must be a '('
4088   if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) {


4099       nextp = skip_over_field_signature(p, false, length, CHECK_0);
4100     }
4101     // The first non-signature thing better be a ')'
4102     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
4103       length--;
4104       if (name->utf8_length() > 0 && name->byte_at(0) == '<') {
4105         // All internal methods must return void
4106         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
4107           return args_size;
4108         }
4109       } else {
4110         // Now we better just have a return value
4111         nextp = skip_over_field_signature(p, true, length, CHECK_0);
4112         if (nextp && ((int)length == (nextp - p))) {
4113           return args_size;
4114         }
4115       }
4116     }
4117   }
4118   // Report error
4119   ResourceMark rm(THREAD);
4120   Exceptions::fthrow(
4121     THREAD_AND_LOCATION,
4122     vmSymbolHandles::java_lang_ClassFormatError(),
4123     "Method \"%s\" in class %s has illegal signature \"%s\"",
4124     name->as_C_string(),  _class_name->as_C_string(), p
4125   );
4126   return 0;
4127 }
4128 
4129 
4130 // Unqualified names may not contain the characters '.', ';', or '/'.
4131 // Method names also may not contain the characters '<' or '>', unless <init> or <clinit>.
4132 // Note that method names may not be <init> or <clinit> in this method.
4133 // Because these names have been checked as special cases before calling this method
4134 // in verify_legal_method_name.
4135 bool ClassFileParser::verify_unqualified_name(char* name, unsigned int length, int type) {
4136   jchar ch;
4137 
4138   for (char* p = name; p != name + length; ) {
4139     ch = *p;
4140     if (ch < 128) {
4141       p++;
4142       if (ch == '.' || ch == ';') {
4143         return false;   // do not permit '.' or ';'
4144       }
4145       if (type != LegalClass && ch == '/') {




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 #include "incls/_precompiled.incl"
  26 #include "incls/_classFileParser.cpp.incl"
  27 
  28 // We generally try to create the oops directly when parsing, rather than
  29 // allocating temporary data structures and copying the bytes twice. A
  30 // temporary area is only needed when parsing utf8 entries in the constant
  31 // pool and when parsing line number tables.
  32 
  33 // We add assert in debug mode when class format is not checked.
  34 
  35 #define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
  36 #define JAVA_MIN_SUPPORTED_VERSION        45
  37 #define JAVA_MAX_SUPPORTED_VERSION        51
  38 #define JAVA_MAX_SUPPORTED_MINOR_VERSION  0
  39 
  40 // Used for two backward compatibility reasons:
  41 // - to check for new additions to the class file format in JDK1.5
  42 // - to check for bug fixes in the format checker in JDK1.5
  43 #define JAVA_1_5_VERSION                  49
  44 
  45 // Used for backward compatibility reasons:
  46 // - to check for javac bug fixes that happened after 1.5
  47 // - also used as the max version when running in jdk6
  48 #define JAVA_6_VERSION                    50
  49 
  50 // Used for backward compatibility reasons:
  51 // - to check NameAndType_info signatures more aggressively
  52 #define JAVA_7_VERSION                    51
  53 
  54 
  55 void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) {
  56   // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
  57   // this function (_current can be allocated in a register, with scalar
  58   // replacement of aggregates). The _current pointer is copied back to
  59   // stream() when this function returns. DON'T call another method within
  60   // this method that uses stream().
  61   ClassFileStream* cfs0 = stream();
  62   ClassFileStream cfs1 = *cfs0;
  63   ClassFileStream* cfs = &cfs1;
  64 #ifdef ASSERT
  65   u1* old_current = cfs0->current();
  66 #endif
  67 
  68   // Used for batching symbol allocations.
  69   const char* names[SymbolTable::symbol_alloc_batch_size];
  70   int lengths[SymbolTable::symbol_alloc_batch_size];
  71   int indices[SymbolTable::symbol_alloc_batch_size];
  72   unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];
  73   int names_count = 0;
  74 


 371                          "Unused constant pool patch at %d in class file %s",
 372                          index, CHECK_(nullHandle));
 373     }
 374   }
 375 
 376   if (!_need_verify) {
 377     return cp;
 378   }
 379 
 380   // second verification pass - checks the strings are of the right format.
 381   // but not yet to the other entries
 382   for (index = 1; index < length; index++) {
 383     jbyte tag = cp->tag_at(index).value();
 384     switch (tag) {
 385       case JVM_CONSTANT_UnresolvedClass: {
 386         symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
 387         // check the name, even if _cp_patches will overwrite it
 388         verify_legal_class_name(class_name, CHECK_(nullHandle));
 389         break;
 390       }
 391       case JVM_CONSTANT_NameAndType: {
 392         if (_need_verify && _major_version >= JAVA_7_VERSION) {
 393           int sig_index = cp->signature_ref_index_at(index);
 394           int name_index = cp->name_ref_index_at(index);
 395           symbolHandle name(THREAD, cp->symbol_at(name_index));
 396           symbolHandle sig(THREAD, cp->symbol_at(sig_index));
 397           if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) {
 398             verify_legal_method_signature(name, sig, CHECK_(nullHandle));
 399           } else {
 400             verify_legal_field_signature(name, sig, CHECK_(nullHandle));
 401           }
 402         }
 403         break;
 404       }
 405       case JVM_CONSTANT_Fieldref:
 406       case JVM_CONSTANT_Methodref:
 407       case JVM_CONSTANT_InterfaceMethodref: {
 408         int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
 409         // already verified to be utf8
 410         int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
 411         // already verified to be utf8
 412         int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index);
 413         symbolHandle name(THREAD, cp->symbol_at(name_ref_index));
 414         symbolHandle signature(THREAD, cp->symbol_at(signature_ref_index));
 415         if (tag == JVM_CONSTANT_Fieldref) {
 416           verify_legal_field_name(name, CHECK_(nullHandle));
 417           if (_need_verify && _major_version >= JAVA_7_VERSION) {
 418             // Signature is verified above, when iterating NameAndType_info.
 419             // Need only to be sure it's the right type.
 420             if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) {
 421               throwIllegalSignature(
 422                   "Field", name, signature, CHECK_(nullHandle));
 423             }
 424           } else {
 425             verify_legal_field_signature(name, signature, CHECK_(nullHandle));
 426           }
 427         } else {
 428           verify_legal_method_name(name, CHECK_(nullHandle));
 429           if (_need_verify && _major_version >= JAVA_7_VERSION) {
 430             // Signature is verified above, when iterating NameAndType_info.
 431             // Need only to be sure it's the right type.
 432             if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) {
 433               throwIllegalSignature(
 434                   "Method", name, signature, CHECK_(nullHandle));
 435             }
 436           } else {
 437             verify_legal_method_signature(name, signature, CHECK_(nullHandle));
 438           }
 439           if (tag == JVM_CONSTANT_Methodref) {
 440             // 4509014: If a class method name begins with '<', it must be "<init>".
 441             assert(!name.is_null(), "method name in constant pool is null");
 442             unsigned int name_len = name->utf8_length();
 443             assert(name_len > 0, "bad method name");  // already verified as legal name
 444             if (name->byte_at(0) == '<') {
 445               if (name() != vmSymbols::object_initializer_name()) {
 446                 classfile_parse_error(
 447                   "Bad method name at constant pool index %u in class file %s",
 448                   name_ref_index, CHECK_(nullHandle));
 449               }
 450             }
 451           }
 452         }
 453         break;
 454       }
 455     }  // end of switch
 456   }  // end of for
 457 
 458   return cp;


1332     u2 len = *checked_exceptions_length;
1333     cfs->guarantee_more(2 * len, CHECK_NULL);
1334     for (int i = 0; i < len; i++) {
1335       checked_exception = cfs->get_u2_fast();
1336       check_property(
1337         valid_cp_range(checked_exception, cp->length()) &&
1338         is_klass_reference(cp, checked_exception),
1339         "Exception name has bad type at constant pool %u in class file %s",
1340         checked_exception, CHECK_NULL);
1341     }
1342   }
1343   // check exceptions attribute length
1344   if (_need_verify) {
1345     guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) +
1346                                                    sizeof(u2) * size),
1347                       "Exceptions attribute has wrong length in class file %s", CHECK_NULL);
1348   }
1349   return checked_exceptions_start;
1350 }
1351 
1352 void ClassFileParser::throwIllegalSignature(
1353     const char* type, symbolHandle name, symbolHandle sig, TRAPS) {
1354   ResourceMark rm(THREAD);
1355   Exceptions::fthrow(THREAD_AND_LOCATION,
1356       vmSymbols::java_lang_ClassFormatError(),
1357       "%s \"%s\" in class %s has illegal signature \"%s\"", type,
1358       name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
1359 }
1360 
1361 #define MAX_ARGS_SIZE 255
1362 #define MAX_CODE_SIZE 65535
1363 #define INITIAL_MAX_LVT_NUMBER 256
1364 
1365 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions
1366 // attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
1367 // methodOop to save footprint, so we only know the size of the resulting methodOop when the
1368 // entire method attribute is parsed.
1369 //
1370 // The promoted_flags parameter is used to pass relevant access_flags
1371 // from the method back up to the containing klass. These flag values
1372 // are added to klass's access_flags.
1373 
1374 methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface,
1375                                            AccessFlags *promoted_flags,
1376                                            typeArrayHandle* method_annotations,
1377                                            typeArrayHandle* method_parameter_annotations,
1378                                            typeArrayHandle* method_default_annotations,
1379                                            TRAPS) {


4085       THREAD_AND_LOCATION,
4086       vmSymbolHandles::java_lang_ClassFormatError(),
4087       "Illegal method name \"%s\" in class %s", bytes,
4088       _class_name->as_C_string()
4089     );
4090     return;
4091   }
4092 }
4093 
4094 
4095 // Checks if signature is a legal field signature.
4096 void ClassFileParser::verify_legal_field_signature(symbolHandle name, symbolHandle signature, TRAPS) {
4097   if (!_need_verify) { return; }
4098 
4099   char buf[fixed_buffer_size];
4100   char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
4101   unsigned int length = signature->utf8_length();
4102   char* p = skip_over_field_signature(bytes, false, length, CHECK);
4103 
4104   if (p == NULL || (p - bytes) != (int)length) {
4105     throwIllegalSignature("Field", name, signature, CHECK);







4106   }
4107 }
4108 
4109 // Checks if signature is a legal method signature.
4110 // Returns number of parameters
4111 int ClassFileParser::verify_legal_method_signature(symbolHandle name, symbolHandle signature, TRAPS) {
4112   if (!_need_verify) {
4113     // make sure caller's args_size will be less than 0 even for non-static
4114     // method so it will be recomputed in compute_size_of_parameters().
4115     return -2;
4116   }
4117 
4118   unsigned int args_size = 0;
4119   char buf[fixed_buffer_size];
4120   char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
4121   unsigned int length = signature->utf8_length();
4122   char* nextp;
4123 
4124   // The first character must be a '('
4125   if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) {


4136       nextp = skip_over_field_signature(p, false, length, CHECK_0);
4137     }
4138     // The first non-signature thing better be a ')'
4139     if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
4140       length--;
4141       if (name->utf8_length() > 0 && name->byte_at(0) == '<') {
4142         // All internal methods must return void
4143         if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
4144           return args_size;
4145         }
4146       } else {
4147         // Now we better just have a return value
4148         nextp = skip_over_field_signature(p, true, length, CHECK_0);
4149         if (nextp && ((int)length == (nextp - p))) {
4150           return args_size;
4151         }
4152       }
4153     }
4154   }
4155   // Report error
4156   throwIllegalSignature("Method", name, signature, CHECK_0);






4157   return 0;
4158 }
4159 
4160 
4161 // Unqualified names may not contain the characters '.', ';', or '/'.
4162 // Method names also may not contain the characters '<' or '>', unless <init> or <clinit>.
4163 // Note that method names may not be <init> or <clinit> in this method.
4164 // Because these names have been checked as special cases before calling this method
4165 // in verify_legal_method_name.
4166 bool ClassFileParser::verify_unqualified_name(char* name, unsigned int length, int type) {
4167   jchar ch;
4168 
4169   for (char* p = name; p != name + length; ) {
4170     ch = *p;
4171     if (ch < 128) {
4172       p++;
4173       if (ch == '.' || ch == ';') {
4174         return false;   // do not permit '.' or ';'
4175       }
4176       if (type != LegalClass && ch == '/') {


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