|
4 | 4 | */
|
5 | 5 |
|
6 | 6 | import java
|
| 7 | +private import semmle.code.java.controlflow.Guards |
7 | 8 | private import semmle.code.java.dataflow.DataFlow
|
8 | 9 | private import semmle.code.java.dataflow.TaintTracking
|
9 | 10 | private import semmle.code.java.frameworks.android.Android
|
@@ -85,38 +86,40 @@ private class IntentFlagsOrDataChangedSanitizer extends IntentUriPermissionManip
|
85 | 86 | private class IntentFlagsOrDataCheckedGuard extends IntentUriPermissionManipulationGuard {
|
86 | 87 | Expr condition;
|
87 | 88 |
|
88 |
| - IntentFlagsOrDataCheckedGuard() { |
89 |
| - this.(MethodAccess).getMethod() instanceof EqualsMethod and |
90 |
| - condition = [this.(MethodAccess).getArgument(0), this.(MethodAccess).getQualifier()] |
91 |
| - or |
92 |
| - condition = this.(EqualityTest).getAnOperand().(AndBitwiseExpr) |
93 |
| - } |
| 89 | + IntentFlagsOrDataCheckedGuard() { intentFlagsOrDataChecked(this, _, _) } |
94 | 90 |
|
95 |
| - override predicate checks(Expr e, boolean branch) { |
96 |
| - exists(MethodAccess ma, Method m | |
97 |
| - // This checks `intent` when the result of an `intent.getFlags` or `intent.getData` call flows to `condition` |
98 |
| - // (i.e., that result is equality-tested) |
99 |
| - ma.getMethod() = m and |
100 |
| - m.getDeclaringType() instanceof TypeIntent and |
101 |
| - m.hasName(["getFlags", "getData"]) and |
102 |
| - TaintTracking::localExprTaint(ma, condition) and |
103 |
| - ma.getQualifier() = e |
104 |
| - | |
105 |
| - bitwiseCheck(branch) |
106 |
| - or |
107 |
| - this.(MethodAccess).getMethod() instanceof EqualsMethod and branch = true |
108 |
| - ) |
109 |
| - } |
| 91 | + override predicate checks(Expr e, boolean branch) { intentFlagsOrDataChecked(this, e, branch) } |
| 92 | +} |
110 | 93 |
|
111 |
| - /** |
112 |
| - * Holds if `this` is a bitwise check. `branch` is `true` when the expected value is `0` |
113 |
| - * and `false` otherwise. |
114 |
| - */ |
115 |
| - private predicate bitwiseCheck(boolean branch) { |
116 |
| - exists(CompileTimeConstantExpr operand | operand = this.(EqualityTest).getAnOperand() | |
117 |
| - if operand.getIntValue() = 0 |
118 |
| - then this.(EqualityTest).polarity() = branch |
119 |
| - else this.(EqualityTest).polarity().booleanNot() = branch |
120 |
| - ) |
121 |
| - } |
| 94 | +/** |
| 95 | + * Holds if `g` checks `intent` when the result of an `intent.getFlags` or `intent.getData` call |
| 96 | + * is equality-tested. |
| 97 | + */ |
| 98 | +private predicate intentFlagsOrDataChecked(Guard g, Expr intent, boolean branch) { |
| 99 | + exists(MethodAccess ma, Method m, Expr checkedValue | |
| 100 | + ma.getQualifier() = intent and |
| 101 | + ma.getMethod() = m and |
| 102 | + m.getDeclaringType() instanceof TypeIntent and |
| 103 | + m.hasName(["getFlags", "getData"]) and |
| 104 | + TaintTracking::localExprTaint(ma, checkedValue) |
| 105 | + | |
| 106 | + bitwiseCheck(g, branch) and |
| 107 | + checkedValue = g.(EqualityTest).getAnOperand().(AndBitwiseExpr) |
| 108 | + or |
| 109 | + g.(MethodAccess).getMethod() instanceof EqualsMethod and |
| 110 | + branch = true and |
| 111 | + checkedValue = [g.(MethodAccess).getArgument(0), g.(MethodAccess).getQualifier()] |
| 112 | + ) |
| 113 | +} |
| 114 | + |
| 115 | +/** |
| 116 | + * Holds if `g` is a bitwise check. `branch` is `true` when the expected value is `0` |
| 117 | + * and `false` otherwise. |
| 118 | + */ |
| 119 | +private predicate bitwiseCheck(Guard g, boolean branch) { |
| 120 | + exists(CompileTimeConstantExpr operand | operand = g.(EqualityTest).getAnOperand() | |
| 121 | + if operand.getIntValue() = 0 |
| 122 | + then g.(EqualityTest).polarity() = branch |
| 123 | + else g.(EqualityTest).polarity().booleanNot() = branch |
| 124 | + ) |
122 | 125 | }
|
0 commit comments