Refactor Intent flow steps

This commit is contained in:
Tony Torralba
2022-09-28 13:02:53 +02:00
parent 00b0a6bf38
commit 1857a5d311

View File

@@ -249,88 +249,91 @@ class GrantWriteUriPermissionFlag extends GrantUriPermissionFlag {
GrantWriteUriPermissionFlag() { this.hasName("FLAG_GRANT_WRITE_URI_PERMISSION") } GrantWriteUriPermissionFlag() { this.hasName("FLAG_GRANT_WRITE_URI_PERMISSION") }
} }
/** /** The instantiation of an `android.content.Intent` instance. */
* Gets the `Class<?>` argument of an `android.content.Intent`constructor. private class NewIntent extends ClassInstanceExpr {
* NewIntent() { this.getConstructedType() instanceof TypeIntent }
* The `android.content.Intent` class has two constructors with an argument of type
* `Class<?>`. One has the argument at position 1 and the other at position 3. /** Gets the `Class<?>` argument of this call. */
* https://developer.android.com/reference/android/content/Intent#public-constructors Argument getClassArg() {
*/ result.getType() instanceof TypeClass and
private Argument getClassArgOfIntentConstructor(ClassInstanceExpr classInstanceExpr) { result = this.getAnArgument()
classInstanceExpr.getConstructedType() instanceof TypeIntent and }
if classInstanceExpr.getNumArgument() = 2
then result = classInstanceExpr.getArgument(1)
else result = classInstanceExpr.getArgument(3)
} }
/** /** A call to a method that starts an Android component */
* A value-preserving step from the Intent argument of a `startActivity` call to private class StartComponentMethodAccess extends MethodAccess {
* a `getIntent` call in the Activity the Intent pointed to in its constructor. StartComponentMethodAccess() {
*/ this.getMethod().overrides*(any(StartActivityMethod m)) or
private class StartActivityIntentStep extends AdditionalValueStep { this.getMethod().overrides*(any(StartServiceMethod m)) or
/** this.getMethod().overrides*(any(SendBroadcastMethod m))
* Gets the `Intent` argument of an Android `StartActivityMethod`.
*
* The `startActivityFromChild` and `startActivityFromFragment` methods have
* an argument of type `Intent` at position 1, but the rest of the methods of
* type `StartActivityMethod` have an argument of type `Intent` at position 0.
*/
private Argument getIntentArgOfStartActMethod(MethodAccess methodAccess) {
methodAccess.getMethod().overrides*(any(StartActivityMethod m)) and
if methodAccess.getMethod().hasName(["startActivityFromChild", "startActivityFromFragment"])
then result = methodAccess.getArgument(1)
else result = methodAccess.getArgument(0)
} }
override predicate step(DataFlow::Node n1, DataFlow::Node n2) { /** Gets the intent argument of this call. */
exists(MethodAccess startActivity, MethodAccess getIntent, ClassInstanceExpr newIntent | Argument getIntentArg() {
startActivity.getMethod().overrides*(any(StartActivityMethod m)) and result.getType() instanceof TypeIntent and
getIntent.getMethod().overrides*(any(AndroidGetIntentMethod m)) and result = this.getAnArgument()
newIntent.getConstructedType() instanceof TypeIntent and }
DataFlow::localExprFlow(newIntent, this.getIntentArgOfStartActMethod(startActivity)) and
getClassArgOfIntentConstructor(newIntent).getType().(ParameterizedType).getATypeArgument() = /** Holds if this targets a component of type `targetType`. */
getIntent.getReceiverType() and predicate targetsComponentType(RefType targetType) {
n1.asExpr() = this.getIntentArgOfStartActMethod(startActivity) and exists(NewIntent newIntent |
n2.asExpr() = getIntent DataFlow::localExprFlow(newIntent, this.getIntentArg()) and
newIntent.getClassArg().getType().(ParameterizedType).getATypeArgument() = targetType
) )
} }
} }
/** /**
* A value-preserving step from the Intent argument of a `sendBroadcast` call to * Holds if there is a step from the intent argument `n1` of a `startActivity` call
* the `Intent` parameter in the `onReceive` method of the BroadcastReceiver the * to a `getIntent` call `n2` in the activity `n1` targets.
* Intent pointed to in its constructor. */
private predicate startActivityIntentStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(StartComponentMethodAccess startActivity, MethodAccess getIntent |
startActivity.getMethod().overrides*(any(StartActivityMethod m)) and
getIntent.getMethod().overrides*(any(AndroidGetIntentMethod m)) and
startActivity.targetsComponentType(getIntent.getReceiverType()) and
n1.asExpr() = startActivity.getIntentArg() and
n2.asExpr() = getIntent
)
}
/**
* A value-preserving step from the intent argument of a `startActivity` call to
* a `getIntent` call in the activity the intent targeted in its constructor.
*/
private class StartActivityIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) { startActivityIntentStep(n1, n2) }
}
/**
* A value-preserving step from the intent argument of a `sendBroadcast` call to
* the intent parameter in the `onReceive` method of the receiver the
* intent targeted in its constructor.
*/ */
private class SendBroadcastReceiverIntentStep extends AdditionalValueStep { private class SendBroadcastReceiverIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) { override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess sendBroadcast, Method onReceive, ClassInstanceExpr newIntent | exists(StartComponentMethodAccess sendBroadcast, Method onReceive |
sendBroadcast.getMethod().overrides*(any(SendBroadcastMethod m)) and sendBroadcast.getMethod().overrides*(any(SendBroadcastMethod m)) and
onReceive.overrides*(any(AndroidReceiveIntentMethod m)) and onReceive.overrides*(any(AndroidReceiveIntentMethod m)) and
newIntent.getConstructedType() instanceof TypeIntent and sendBroadcast.targetsComponentType(onReceive.getDeclaringType()) and
DataFlow::localExprFlow(newIntent, sendBroadcast.getArgument(0)) and n1.asExpr() = sendBroadcast.getIntentArg() and
getClassArgOfIntentConstructor(newIntent).getType().(ParameterizedType).getATypeArgument() =
onReceive.getDeclaringType() and
n1.asExpr() = sendBroadcast.getArgument(0) and
n2.asParameter() = onReceive.getParameter(1) n2.asParameter() = onReceive.getParameter(1)
) )
} }
} }
/** /**
* A value-preserving step from the Intent argument of a `startService` call to * A value-preserving step from the intent argument of a `startService` call to
* the `Intent` parameter in an `AndroidServiceIntentMethod` of the Service the * the intent parameter in an `AndroidServiceIntentMethod` of the service the
* Intent pointed to in its constructor. * intent targeted in its constructor.
*/ */
private class StartServiceIntentStep extends AdditionalValueStep { private class StartServiceIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) { override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess startService, Method serviceIntent, ClassInstanceExpr newIntent | exists(StartComponentMethodAccess startService, Method serviceIntent |
startService.getMethod().overrides*(any(StartServiceMethod m)) and startService.getMethod().overrides*(any(StartServiceMethod m)) and
serviceIntent.overrides*(any(AndroidServiceIntentMethod m)) and serviceIntent.overrides*(any(AndroidServiceIntentMethod m)) and
newIntent.getConstructedType() instanceof TypeIntent and startService.targetsComponentType(serviceIntent.getDeclaringType()) and
DataFlow::localExprFlow(newIntent, startService.getArgument(0)) and n1.asExpr() = startService.getIntentArg() and
getClassArgOfIntentConstructor(newIntent).getType().(ParameterizedType).getATypeArgument() =
serviceIntent.getDeclaringType() and
n1.asExpr() = startService.getArgument(0) and
n2.asParameter() = serviceIntent.getParameter(0) n2.asParameter() = serviceIntent.getParameter(0)
) )
} }