mirror of
https://github.com/github/codeql.git
synced 2025-12-23 20:26:32 +01:00
Refactor Intent flow steps
This commit is contained in:
@@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user