Java: Add missing flow step for ThreadLocal.initialValue.

This commit is contained in:
Anders Schack-Mulligen
2023-09-22 13:33:45 +02:00
parent 9f905497a5
commit 8ee1f8ae69
3 changed files with 42 additions and 1 deletions

View File

@@ -23,6 +23,7 @@ private module Frameworks {
private import semmle.code.java.frameworks.InputStream
private import semmle.code.java.frameworks.Properties
private import semmle.code.java.frameworks.Protobuf
private import semmle.code.java.frameworks.ThreadLocal
private import semmle.code.java.frameworks.ratpack.RatpackExec
private import semmle.code.java.frameworks.stapler.Stapler
}

View File

@@ -0,0 +1,40 @@
import java
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.FlowSteps
/**
* Holds if `cie` construct a `ThreadLocal` object with an overridden
* `initialValue` method with a return value of `init`, such that `init` is the
* initial value of the `ThreadLocal` object.
*/
private predicate threadLocalInitialValue(ClassInstanceExpr cie, Method initialValue, Expr init) {
exists(RefType t, ReturnStmt ret |
cie.getConstructedType().getSourceDeclaration() = t and
t.getASourceSupertype+().hasQualifiedName("java.lang", "ThreadLocal") and
ret.getResult() = init and
ret.getEnclosingCallable() = initialValue and
initialValue.hasName("initialValue") and
initialValue.getDeclaringType() = t
)
}
private class ThreadLocalInitialValueStore extends AdditionalStoreStep {
override predicate step(DataFlow::Node node1, DataFlow::Content c, DataFlow::Node node2) {
exists(Method initialValue, Expr init |
threadLocalInitialValue(_, initialValue, init) and
node1.asExpr() = init and
node2.(DataFlow::InstanceParameterNode).getCallable() = initialValue and
c.(DataFlow::SyntheticFieldContent).getField() = "java.lang.ThreadLocal.value"
)
}
}
private class ThreadLocalInitialValueStep extends AdditionalValueStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(ClassInstanceExpr cie, Method initialValue |
threadLocalInitialValue(cie, initialValue, _) and
node1.(DataFlow::InstanceParameterNode).getCallable() = initialValue and
node2.asExpr() = cie
)
}
}

View File

@@ -129,7 +129,7 @@ class DocumentBuilderTests {
public void disableExternalEntities2(Socket sock) throws Exception {
DocumentBuilder builder = XML_DOCUMENT_BUILDER.get();
builder.parse(sock.getInputStream()); // $ SPURIOUS: hasTaintFlow
builder.parse(sock.getInputStream()); // safe
}
}