Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly handle static interface methods as entrypoints #1275

Merged
merged 6 commits into from
Jun 26, 2023

Conversation

hjjandy
Copy link
Contributor

@hjjandy hjjandy commented Jun 2, 2023

When a static Interface method is selected as an Entrypoint, WALA creates an invokeinterface instead of an invokestatic instruction in FakeRootMethod. This will lead to an out-of-array read when resolving the receiver for an interface invocation.

A test can be simply an Android app generated by Android Studio for a Basic Activity demo (either Java or Kotlin). In my case, the problem occurs for handling:

40149 = invokeinterface < Application, Landroidx/window/layout/WindowMetricsCalculator, getOrCreate()Landroidx/window/layout/WindowMetricsCalculator; > @32353 exception:40150

And the exception is as follows:

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.lambda$getTargetsForCall$0(SSAPropagationCallGraphBuilder.java:2072)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$CrossProductRec.rec(SSAPropagationCallGraphBuilder.java:542)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.iterateCrossProduct(SSAPropagationCallGraphBuilder.java:2055)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.getTargetsForCall(SSAPropagationCallGraphBuilder.java:2079)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$ConstraintVisitor.visitInvokeInternal(SSAPropagationCallGraphBuilder.java:1159)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$ConstraintVisitor.visitInvoke(SSAPropagationCallGraphBuilder.java:1115)
at com.ibm.wala.ssa.SSAInvokeInstruction.visit(SSAInvokeInstruction.java:94)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addBlockInstructionConstraints(SSAPropagationCallGraphBuilder.java:273)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addNodeInstructionConstraints(SSAPropagationCallGraphBuilder.java:250)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.unconditionallyAddConstraintsFromNode(SSAPropagationCallGraphBuilder.java:226)
at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addConstraintsFromNode(SSAPropagationCallGraphBuilder.java:191)
at com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder.addConstraintsFromNewNodes(PropagationCallGraphBuilder.java:308)
at com.ibm.wala.ipa.callgraph.propagation.StandardSolver.solve(StandardSolver.java:53)
at com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder.makeCallGraph(PropagationCallGraphBuilder.java:248)

This commit prioritizes a static method over an interface method and addresses the above problem.

When a static Interface method is selected as an Entrypoint when analyzing an Android app, WALA creates an invokeinterface instead of an invokestatic instruction in FakeRootMethod. This will lead to an out-of-array read when resolving the receiver for an interface invocation.

A test can be simply an Android app generated by Android Studio for a Basic Activity demo (either Java or Kotlin). In my case, the problem occurs for handling:

40149 = invokeinterface < Application, Landroidx/window/layout/WindowMetricsCalculator, getOrCreate()Landroidx/window/layout/WindowMetricsCalculator; > @32353 exception:40150

And the exception is as follows:

java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.lambda$getTargetsForCall$0(SSAPropagationCallGraphBuilder.java:2072)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$CrossProductRec.rec(SSAPropagationCallGraphBuilder.java:542)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.iterateCrossProduct(SSAPropagationCallGraphBuilder.java:2055)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.getTargetsForCall(SSAPropagationCallGraphBuilder.java:2079)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$ConstraintVisitor.visitInvokeInternal(SSAPropagationCallGraphBuilder.java:1159)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder$ConstraintVisitor.visitInvoke(SSAPropagationCallGraphBuilder.java:1115)
        at com.ibm.wala.ssa.SSAInvokeInstruction.visit(SSAInvokeInstruction.java:94)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addBlockInstructionConstraints(SSAPropagationCallGraphBuilder.java:273)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addNodeInstructionConstraints(SSAPropagationCallGraphBuilder.java:250)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.unconditionallyAddConstraintsFromNode(SSAPropagationCallGraphBuilder.java:226)
        at com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder.addConstraintsFromNode(SSAPropagationCallGraphBuilder.java:191)
        at com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder.addConstraintsFromNewNodes(PropagationCallGraphBuilder.java:308)
        at com.ibm.wala.ipa.callgraph.propagation.StandardSolver.solve(StandardSolver.java:53)
        at com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder.makeCallGraph(PropagationCallGraphBuilder.java:248)

This commit prioritizes a static method over an interface method and addresses the above problem.
Copy link
Member

@msridhar msridhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me! And thanks for the contribution! But can we add a test case for this? I think it shouldn't be too hard, but if you need help let me know

@hjjandy
Copy link
Contributor Author

hjjandy commented Jun 5, 2023

I have included a test, with the Android app, the test code and the needed JAR files. The WALA jars are compiled from an earlier snapshot that has the mentioned issue.
Test.zip

@hjjandy hjjandy requested a review from msridhar June 13, 2023 01:01
@msridhar
Copy link
Member

@hjjandy I meant that we should add a unit test. My feeling is this issue should occur with any static interface Entrypoint method; I don't think it has anything to do with Android. Our test inputs are here:

https://github.com/wala/WALA/tree/master/core/src/testSubjects/java

You could add another small Java source file, and then create a JUnit test like this one:

https://github.com/wala/WALA/blob/master/core/src/test/java/com/ibm/wala/core/tests/callGraph/DefaultMethodsTest.java

Your test would create the appropriate Entrypoint and ensure the exception does not occur. Does that make sense?

@msridhar
Copy link
Member

@hjjandy I went ahead and added a unit test so we can merge. Please see the code in case you'd like to contribute and add tests in the future.

@msridhar msridhar enabled auto-merge (squash) June 26, 2023 21:54
@msridhar msridhar disabled auto-merge June 26, 2023 21:55
@msridhar msridhar changed the title Fixing an OutOfArrayIndex bug. Properly handle static interface methods as entrypoints Jun 26, 2023
@msridhar msridhar enabled auto-merge (squash) June 26, 2023 21:55
@msridhar msridhar merged commit 6f9e6ce into wala:master Jun 26, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants