Skip to content

Commit 5264936

Browse files
committed
Correct the run method and add Math.min check
1 parent 272e4f6 commit 5264936

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

java/ql/src/experimental/Security/CWE/CWE-400/ThreadPauseSink.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ import java
44
import semmle.code.java.dataflow.DataFlow
55
import semmle.code.java.dataflow.ExternalFlow
66

7+
/** `java.lang.Math` data model for value comparison in the new CSV format. */
8+
private class MathCompDataModel extends SummaryModelCsv {
9+
override predicate row(string row) {
10+
row =
11+
[
12+
"java.lang;Math;false;min;;;Argument[0..1];ReturnValue;taint",
13+
"java.lang;Math;false;max;;;Argument[0..1];ReturnValue;taint"
14+
]
15+
}
16+
}
17+
718
/** Thread pause data model in the new CSV format. */
819
private class PauseThreadDataModel extends SinkModelCsv {
920
override predicate row(string row) {

java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.ql

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,29 @@ class ThreadResourceAbuse extends TaintTracking::Configuration {
6363

6464
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
6565
exists(
66-
Method rm, ClassInstanceExpr ce, Argument arg, FieldAccess fa // thread.start() invokes the run() method of thread implementation
66+
Method rm, ClassInstanceExpr ce, Argument arg, Parameter p, FieldAccess fa, int i // thread.start() invokes the run() method of thread implementation
6767
|
6868
rm.hasName("run") and
6969
ce.getConstructedType().getSourceDeclaration() = rm.getSourceDeclaration().getDeclaringType() and
7070
ce.getConstructedType().getASupertype*().hasQualifiedName("java.lang", "Runnable") and
71-
ce.getAnArgument() = arg and
72-
fa = rm.getAnAccessedField().getAnAccess() and
73-
arg.getType() = fa.getField().getType() and
71+
ce.getArgument(i) = arg and
72+
ce.getConstructor().getParameter(i) = p and
73+
fa.getEnclosingCallable() = rm and
74+
DataFlow::localExprFlow(p.getAnAccess(), fa.getField().getAnAssignedValue()) and
7475
node1.asExpr() = arg and
7576
node2.asExpr() = fa
7677
)
7778
}
7879

80+
override predicate isSanitizer(DataFlow::Node node) {
81+
exists(
82+
MethodAccess ma // Math.min(sleepTime, MAX_INTERVAL)
83+
|
84+
ma.getMethod().hasQualifiedName("java.lang", "Math", "min") and
85+
node.asExpr() = ma.getAnArgument()
86+
)
87+
}
88+
7989
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
8090
guard instanceof LessThanSanitizer // if (sleepTime > 0 && sleepTime < 5000) { ... }
8191
}

java/ql/test/experimental/query-tests/security/CWE-400/ThreadResourceAbuse.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ protected void doHead(HttpServletRequest request, HttpServletResponse response)
150150
}
151151
}
152152

153-
int parseReplyAfter(String value) {
153+
int parseRetryAfter(String value) {
154154
if (value == null || value.isEmpty()) {
155155
return DEFAULT_RETRY_AFTER;
156156
}
@@ -183,7 +183,7 @@ protected void doHead2(HttpServletRequest request, HttpServletResponse response)
183183
protected void doHead3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
184184
// Get thread pause time from request header
185185
String header = request.getHeader("Retry-After");
186-
int retryAfter = parseReplyAfter(header);
186+
int retryAfter = parseRetryAfter(header);
187187

188188
try {
189189
// GOOD: wait for retry-after with input validation

0 commit comments

Comments
 (0)