< prev index next >

src/hotspot/share/prims/jniCheck.cpp

Print this page

 239   fieldDescriptor fd;
 240 
 241   /* make sure it is a static field */
 242   if (!jfieldIDWorkaround::is_static_jfieldID(fid))
 243     ReportJNIFatalError(thr, fatal_should_be_static);
 244 
 245   /* validate the class being passed */
 246   ASSERT_OOPS_ALLOWED;
 247   Klass* k_oop = jniCheck::validate_class(thr, cls, false);
 248 
 249   /* check for proper subclass hierarchy */
 250   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid);
 251   Klass* f_oop = id->holder();
 252   if (!k_oop->is_subtype_of(f_oop))
 253     ReportJNIFatalError(thr, fatal_wrong_static_field);
 254 
 255   /* check for proper field type */
 256   if (!id->find_local_field(&fd))
 257     ReportJNIFatalError(thr, fatal_static_field_not_found);
 258   if ((fd.field_type() != ftype) &&
 259       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {

 260     ReportJNIFatalError(thr, fatal_static_field_mismatch);
 261   }
 262 }
 263 
 264 static inline void
 265 checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype)
 266 {
 267   fieldDescriptor fd;
 268 
 269   /* make sure it is an instance field */
 270   if (jfieldIDWorkaround::is_static_jfieldID(fid))
 271     ReportJNIFatalError(thr, fatal_should_be_nonstatic);
 272 
 273   /* validate the object being passed and then get its class */
 274   ASSERT_OOPS_ALLOWED;
 275   oop oopObj = jniCheck::validate_object(thr, obj);
 276   if (oopObj == nullptr) {
 277     ReportJNIFatalError(thr, fatal_null_object);
 278   }
 279   Klass* k_oop = oopObj->klass();
 280 
 281   if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) {
 282     ReportJNIFatalError(thr, fatal_wrong_field);
 283   }
 284 
 285   /* make sure the field exists */
 286   int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid);
 287   if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset))
 288     ReportJNIFatalError(thr, fatal_wrong_field);
 289 
 290   /* check for proper field type */
 291   if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset,
 292                                                               false, &fd))
 293     ReportJNIFatalError(thr, fatal_instance_field_not_found);
 294 
 295   if ((fd.field_type() != ftype) &&
 296       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {

 297     ReportJNIFatalError(thr, fatal_instance_field_mismatch);
 298   }
 299 }
 300 
 301 static inline void
 302 checkString(JavaThread* thr, jstring js)
 303 {
 304   ASSERT_OOPS_ALLOWED;
 305   oop s = jniCheck::validate_object(thr, js);
 306   if ((s == nullptr) || !java_lang_String::is_instance(s))
 307     ReportJNIFatalError(thr, fatal_non_string);
 308 }
 309 
 310 static inline arrayOop
 311 check_is_array(JavaThread* thr, jarray jArray)
 312 {
 313   ASSERT_OOPS_ALLOWED;
 314   arrayOop aOop;
 315 
 316   aOop = (arrayOop)jniCheck::validate_object(thr, jArray);

 327   if (!aOop->is_typeArray()) {
 328      ReportJNIFatalError(thr, fatal_prim_type_array_expected);
 329   }
 330   return aOop;
 331 }
 332 
 333 static inline void
 334 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
 335 {
 336   BasicType array_type;
 337   arrayOop aOop;
 338 
 339   aOop = check_is_primitive_array(thr, jArray);
 340   array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
 341   if (array_type != elementType) {
 342     ReportJNIFatalError(thr, fatal_element_type_mismatch);
 343   }
 344 }
 345 
 346 static inline void
 347 check_is_obj_array(JavaThread* thr, jarray jArray) {
 348   arrayOop aOop = check_is_array(thr, jArray);
 349   if (!aOop->is_objArray()) {
 350     ReportJNIFatalError(thr, fatal_object_array_expected);
 351   }
 352 }
 353 
 354 /*
 355  * Copy and wrap array elements for bounds checking.
 356  * Remember the original elements (GuardedMemory::get_tag())
 357  */
 358 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
 359     void* orig_elements) {
 360   void* result;
 361   IN_VM(
 362     oop a = JNIHandles::resolve_non_null(array);
 363     size_t len = arrayOop(a)->length() <<
 364         TypeArrayKlass::cast(a->klass())->log2_element_size();
 365     result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
 366   )
 367   return result;
 368 }
 369 

 449 
 450 oop jniCheck::validate_object(JavaThread* thr, jobject obj) {
 451   if (obj == nullptr) return nullptr;
 452   ASSERT_OOPS_ALLOWED;
 453   oop oopObj = jniCheck::validate_handle(thr, obj);
 454   if (oopObj == nullptr) {
 455     ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
 456   }
 457   return oopObj;
 458 }
 459 
 460 // Warn if a class descriptor is in decorated form; class descriptors
 461 // passed to JNI findClass should not be decorated unless they are
 462 // array descriptors.
 463 void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) {
 464   if (name == nullptr) return;  // implementation accepts null so just return
 465 
 466   size_t len = strlen(name);
 467 
 468   if (len >= 2 &&
 469       name[0] == JVM_SIGNATURE_CLASS &&            // 'L'
 470       name[len-1] == JVM_SIGNATURE_ENDCLASS ) {    // ';'
 471     char msg[JVM_MAXPATHLEN];
 472     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s",
 473                  warn_bad_class_descriptor1, name, warn_bad_class_descriptor2);
 474     ReportJNIWarning(thr, msg);
 475   }
 476 
 477   // Verify that the class name given is a valid utf8 string
 478   if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) {
 479     char msg[JVM_MAXPATHLEN];
 480     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2);
 481     ReportJNIFatalError(thr, msg);
 482   }
 483 }
 484 
 485 Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) {
 486   ASSERT_OOPS_ALLOWED;
 487   oop mirror = jniCheck::validate_handle(thr, clazz);
 488   if (mirror == nullptr) {
 489     ReportJNIFatalError(thr, fatal_received_null_class);

1589     return result;
1590 JNI_END
1591 
1592 JNI_ENTRY_CHECKED(jobjectArray,
1593   checked_jni_NewObjectArray(JNIEnv *env,
1594                              jsize len,
1595                              jclass clazz,
1596                              jobject init))
1597     functionEnter(thr);
1598     jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
1599     functionExit(thr);
1600     return result;
1601 JNI_END
1602 
1603 JNI_ENTRY_CHECKED(jobject,
1604   checked_jni_GetObjectArrayElement(JNIEnv *env,
1605                                     jobjectArray array,
1606                                     jsize index))
1607     functionEnter(thr);
1608     IN_VM(
1609       check_is_obj_array(thr, array);
1610     )
1611     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
1612     functionExit(thr);
1613     return result;
1614 JNI_END
1615 
1616 JNI_ENTRY_CHECKED(void,
1617   checked_jni_SetObjectArrayElement(JNIEnv *env,
1618                                     jobjectArray array,
1619                                     jsize index,
1620                                     jobject val))
1621     functionEnter(thr);
1622     IN_VM(
1623       check_is_obj_array(thr, array);
1624     )
1625     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
1626     functionExit(thr);
1627 JNI_END
1628 
1629 #define WRAPPER_NewScalarArray(Return, Result) \
1630 JNI_ENTRY_CHECKED(Return, \
1631   checked_jni_New##Result##Array(JNIEnv *env, \
1632                                  jsize len)) \
1633     functionEnter(thr); \
1634     Return result = UNCHECKED()->New##Result##Array(env,len); \
1635     functionExit(thr); \
1636     return (Return) result; \
1637 JNI_END
1638 
1639 WRAPPER_NewScalarArray(jbooleanArray, Boolean)
1640 WRAPPER_NewScalarArray(jbyteArray, Byte)
1641 WRAPPER_NewScalarArray(jshortArray, Short)
1642 WRAPPER_NewScalarArray(jcharArray, Char)
1643 WRAPPER_NewScalarArray(jintArray, Int)

 239   fieldDescriptor fd;
 240 
 241   /* make sure it is a static field */
 242   if (!jfieldIDWorkaround::is_static_jfieldID(fid))
 243     ReportJNIFatalError(thr, fatal_should_be_static);
 244 
 245   /* validate the class being passed */
 246   ASSERT_OOPS_ALLOWED;
 247   Klass* k_oop = jniCheck::validate_class(thr, cls, false);
 248 
 249   /* check for proper subclass hierarchy */
 250   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid);
 251   Klass* f_oop = id->holder();
 252   if (!k_oop->is_subtype_of(f_oop))
 253     ReportJNIFatalError(thr, fatal_wrong_static_field);
 254 
 255   /* check for proper field type */
 256   if (!id->find_local_field(&fd))
 257     ReportJNIFatalError(thr, fatal_static_field_not_found);
 258   if ((fd.field_type() != ftype) &&
 259       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) &&
 260       !(fd.field_type() == T_PRIMITIVE_OBJECT && ftype == T_OBJECT)) {
 261     ReportJNIFatalError(thr, fatal_static_field_mismatch);
 262   }
 263 }
 264 
 265 static inline void
 266 checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype)
 267 {
 268   fieldDescriptor fd;
 269 
 270   /* make sure it is an instance field */
 271   if (jfieldIDWorkaround::is_static_jfieldID(fid))
 272     ReportJNIFatalError(thr, fatal_should_be_nonstatic);
 273 
 274   /* validate the object being passed and then get its class */
 275   ASSERT_OOPS_ALLOWED;
 276   oop oopObj = jniCheck::validate_object(thr, obj);
 277   if (oopObj == nullptr) {
 278     ReportJNIFatalError(thr, fatal_null_object);
 279   }
 280   Klass* k_oop = oopObj->klass();
 281 
 282   if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) {
 283     ReportJNIFatalError(thr, fatal_wrong_field);
 284   }
 285 
 286   /* make sure the field exists */
 287   int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid);
 288   if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset))
 289     ReportJNIFatalError(thr, fatal_wrong_field);
 290 
 291   /* check for proper field type */
 292   if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset,
 293                                                               false, &fd))
 294     ReportJNIFatalError(thr, fatal_instance_field_not_found);
 295 
 296   if ((fd.field_type() != ftype) &&
 297       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) &&
 298       !(fd.field_type() == T_PRIMITIVE_OBJECT && ftype == T_OBJECT)) {
 299     ReportJNIFatalError(thr, fatal_instance_field_mismatch);
 300   }
 301 }
 302 
 303 static inline void
 304 checkString(JavaThread* thr, jstring js)
 305 {
 306   ASSERT_OOPS_ALLOWED;
 307   oop s = jniCheck::validate_object(thr, js);
 308   if ((s == nullptr) || !java_lang_String::is_instance(s))
 309     ReportJNIFatalError(thr, fatal_non_string);
 310 }
 311 
 312 static inline arrayOop
 313 check_is_array(JavaThread* thr, jarray jArray)
 314 {
 315   ASSERT_OOPS_ALLOWED;
 316   arrayOop aOop;
 317 
 318   aOop = (arrayOop)jniCheck::validate_object(thr, jArray);

 329   if (!aOop->is_typeArray()) {
 330      ReportJNIFatalError(thr, fatal_prim_type_array_expected);
 331   }
 332   return aOop;
 333 }
 334 
 335 static inline void
 336 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType)
 337 {
 338   BasicType array_type;
 339   arrayOop aOop;
 340 
 341   aOop = check_is_primitive_array(thr, jArray);
 342   array_type = TypeArrayKlass::cast(aOop->klass())->element_type();
 343   if (array_type != elementType) {
 344     ReportJNIFatalError(thr, fatal_element_type_mismatch);
 345   }
 346 }
 347 
 348 static inline void
 349 check_is_obj_or_inline_array(JavaThread* thr, jarray jArray) {
 350   arrayOop aOop = check_is_array(thr, jArray);
 351   if (!aOop->is_objArray() && !aOop->is_flatArray()) {
 352     ReportJNIFatalError(thr, fatal_object_array_expected);
 353   }
 354 }
 355 
 356 /*
 357  * Copy and wrap array elements for bounds checking.
 358  * Remember the original elements (GuardedMemory::get_tag())
 359  */
 360 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
 361     void* orig_elements) {
 362   void* result;
 363   IN_VM(
 364     oop a = JNIHandles::resolve_non_null(array);
 365     size_t len = arrayOop(a)->length() <<
 366         TypeArrayKlass::cast(a->klass())->log2_element_size();
 367     result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
 368   )
 369   return result;
 370 }
 371 

 451 
 452 oop jniCheck::validate_object(JavaThread* thr, jobject obj) {
 453   if (obj == nullptr) return nullptr;
 454   ASSERT_OOPS_ALLOWED;
 455   oop oopObj = jniCheck::validate_handle(thr, obj);
 456   if (oopObj == nullptr) {
 457     ReportJNIFatalError(thr, fatal_bad_ref_to_jni);
 458   }
 459   return oopObj;
 460 }
 461 
 462 // Warn if a class descriptor is in decorated form; class descriptors
 463 // passed to JNI findClass should not be decorated unless they are
 464 // array descriptors.
 465 void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) {
 466   if (name == nullptr) return;  // implementation accepts null so just return
 467 
 468   size_t len = strlen(name);
 469 
 470   if (len >= 2 &&
 471       (name[0] == JVM_SIGNATURE_CLASS || name[0] == JVM_SIGNATURE_PRIMITIVE_OBJECT) && // 'L' or 'Q'
 472       name[len-1] == JVM_SIGNATURE_ENDCLASS ) {    // ';'
 473     char msg[JVM_MAXPATHLEN];
 474     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s",
 475                  warn_bad_class_descriptor1, name, warn_bad_class_descriptor2);
 476     ReportJNIWarning(thr, msg);
 477   }
 478 
 479   // Verify that the class name given is a valid utf8 string
 480   if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) {
 481     char msg[JVM_MAXPATHLEN];
 482     jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2);
 483     ReportJNIFatalError(thr, msg);
 484   }
 485 }
 486 
 487 Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) {
 488   ASSERT_OOPS_ALLOWED;
 489   oop mirror = jniCheck::validate_handle(thr, clazz);
 490   if (mirror == nullptr) {
 491     ReportJNIFatalError(thr, fatal_received_null_class);

1591     return result;
1592 JNI_END
1593 
1594 JNI_ENTRY_CHECKED(jobjectArray,
1595   checked_jni_NewObjectArray(JNIEnv *env,
1596                              jsize len,
1597                              jclass clazz,
1598                              jobject init))
1599     functionEnter(thr);
1600     jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init);
1601     functionExit(thr);
1602     return result;
1603 JNI_END
1604 
1605 JNI_ENTRY_CHECKED(jobject,
1606   checked_jni_GetObjectArrayElement(JNIEnv *env,
1607                                     jobjectArray array,
1608                                     jsize index))
1609     functionEnter(thr);
1610     IN_VM(
1611       check_is_obj_or_inline_array(thr, array);
1612     )
1613     jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
1614     functionExit(thr);
1615     return result;
1616 JNI_END
1617 
1618 JNI_ENTRY_CHECKED(void,
1619   checked_jni_SetObjectArrayElement(JNIEnv *env,
1620                                     jobjectArray array,
1621                                     jsize index,
1622                                     jobject val))
1623     functionEnter(thr);
1624     IN_VM(
1625       check_is_obj_or_inline_array(thr, array);
1626     )
1627     UNCHECKED()->SetObjectArrayElement(env,array,index,val);
1628     functionExit(thr);
1629 JNI_END
1630 
1631 #define WRAPPER_NewScalarArray(Return, Result) \
1632 JNI_ENTRY_CHECKED(Return, \
1633   checked_jni_New##Result##Array(JNIEnv *env, \
1634                                  jsize len)) \
1635     functionEnter(thr); \
1636     Return result = UNCHECKED()->New##Result##Array(env,len); \
1637     functionExit(thr); \
1638     return (Return) result; \
1639 JNI_END
1640 
1641 WRAPPER_NewScalarArray(jbooleanArray, Boolean)
1642 WRAPPER_NewScalarArray(jbyteArray, Byte)
1643 WRAPPER_NewScalarArray(jshortArray, Short)
1644 WRAPPER_NewScalarArray(jcharArray, Char)
1645 WRAPPER_NewScalarArray(jintArray, Int)
< prev index next >