diff options
| author | Andy McFadden <fadden@android.com> | 2010-10-10 12:59:11 -0700 |
|---|---|---|
| committer | Andy McFadden <fadden@android.com> | 2010-10-10 14:04:42 -0700 |
| commit | 5276cccb15b6ce0133c8107ff9ff013b4a176ef7 (patch) | |
| tree | 35e08cd5f08f61894993b23d69b35028b61a70fb /vm/analysis/CodeVerify.c | |
| parent | 9be25d09d24b3d6d0dd1a41c1c09471af4827687 (diff) | |
Verify method invocation type.
Dalvik provides five different ways to invoke a method (virtual, super,
direct, static, interface). Using a virtual invoke instruction to call
a direct method will not produce the desired results.
This adds a test to the verifier that ensures the method targeted by
an invocation instruction is of an appropriate kind.
Bug 3082885.
(cherry-pick from dalvik-dev)
Change-Id: I3237cbefc7314f0b9d7557fc0bfd2b548ea30938
Diffstat (limited to 'vm/analysis/CodeVerify.c')
| -rw-r--r-- | vm/analysis/CodeVerify.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c index ef6872e62..a7d634eae 100644 --- a/vm/analysis/CodeVerify.c +++ b/vm/analysis/CodeVerify.c @@ -1002,6 +1002,24 @@ static RegType primSigCharToRegType(char sigChar) } /* + * See if the method matches the MethodType. + */ +static bool isCorrectInvokeKind(MethodType methodType, Method* resMethod) +{ + switch (methodType) { + case METHOD_DIRECT: + return dvmIsDirectMethod(resMethod); + case METHOD_STATIC: + return dvmIsStaticMethod(resMethod); + case METHOD_VIRTUAL: + case METHOD_INTERFACE: + return !dvmIsDirectMethod(resMethod); + default: + return false; + } +} + +/* * Verify the arguments to a method. We're executing in "method", making * a call to the method reference in vB. * @@ -1060,10 +1078,9 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, //char* curMethodDesc = // dexProtoCopyMethodDescriptor(&meth->prototype); - LOGI("Could not find method %s.%s, referenced from " - "method %s.%s\n", - dotMissingClass, methodName/*, methodDesc*/, - dotMethClass, meth->name/*, curMethodDesc*/); + LOGI("Could not find method %s.%s, referenced from method %s.%s\n", + dotMissingClass, methodName/*, methodDesc*/, + dotMethClass, meth->name/*, curMethodDesc*/); free(dotMissingClass); free(dotMethClass); @@ -1093,6 +1110,16 @@ static Method* verifyInvocationArgs(const Method* meth, const RegType* insnRegs, } /* + * See if the method type implied by the invoke instruction matches the + * access flags for the target method. + */ + if (!isCorrectInvokeKind(methodType, resMethod)) { + LOG_VFY("VFY: invoke type does not match method type of %s.%s\n", + resMethod->clazz->descriptor, resMethod->name); + goto fail; + } + + /* * If we're using invoke-super(method), make sure that the executing * method's class' superclass has a vtable entry for the target method. */ |
