6739363: Xcheck jni doesn't check native function arguments

Fix adds support for verifying arguments with -Xcheck:jni.

Reviewed-by: coleenp
This commit is contained in:
Poonam Bajaj 2008-12-04 17:29:56 -08:00
parent 8eb2e02296
commit eddda26255
8 changed files with 63 additions and 36 deletions

View file

@ -309,8 +309,12 @@ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArgument
CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
// Make sure that the arguments have the right type
debug_only(args->verify(method, result->get_type(), thread));
// Verify the arguments
if (CheckJNICalls) {
args->verify(method, result->get_type(), thread);
}
else debug_only(args->verify(method, result->get_type(), thread));
// Ignore call if method is empty
if (method->is_empty_method()) {
@ -431,24 +435,26 @@ intptr_t* JavaCallArguments::parameters() {
return TaggedStackInterpreter ? _parameters : _value;
}
//--------------------------------------------------------------------------------------
// Non-Product code
#ifndef PRODUCT
class SignatureChekker : public SignatureIterator {
private:
bool *_is_oop;
int _pos;
BasicType _return_type;
intptr_t* _value;
Thread* _thread;
public:
bool _is_return;
SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop) : SignatureIterator(signature) {
SignatureChekker(symbolHandle signature, BasicType return_type, bool is_static, bool* is_oop, intptr_t* value, Thread* thread) : SignatureIterator(signature) {
_is_oop = is_oop;
_is_return = false;
_return_type = return_type;
_pos = 0;
_value = value;
_thread = thread;
if (!is_static) {
check_value(true); // Receiver must be an oop
}
@ -489,6 +495,24 @@ class SignatureChekker : public SignatureIterator {
check_return_type(t);
return;
}
// verify handle and the oop pointed to by handle
int p = _pos;
bool bad = false;
// If argument is oop
if (_is_oop[p]) {
intptr_t v = _value[p];
if (v != 0 ) {
size_t t = (size_t)v;
bad = (t < (size_t)os::vm_page_size() ) || !(*(oop*)v)->is_oop_or_null(true);
if (CheckJNICalls && bad) {
ReportJNIFatalError((JavaThread*)_thread, "Bad JNI oop argument");
}
}
// for the regular debug case.
assert(!bad, "Bad JNI oop argument");
}
check_value(true);
}
@ -505,6 +529,7 @@ class SignatureChekker : public SignatureIterator {
void do_array(int begin, int end) { check_obj(T_OBJECT); }
};
void JavaCallArguments::verify(methodHandle method, BasicType return_type,
Thread *thread) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
@ -515,10 +540,9 @@ void JavaCallArguments::verify(methodHandle method, BasicType return_type,
// Check that oop information is correct
symbolHandle signature (thread, method->signature());
SignatureChekker sc(signature, return_type, method->is_static(),_is_oop);
SignatureChekker sc(signature, return_type, method->is_static(),_is_oop, _value, thread);
sc.iterate_parameters();
sc.check_doing_return(true);
sc.iterate_returntype();
}
#endif // PRODUCT