mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Merge pull request #5843 from JLLeitschuh/feat/JLL/improve_kryo_support
[Java] Fix Kryo FP & Kryo 5 Support
This commit is contained in:
@@ -292,6 +292,7 @@ private predicate summaryModelCsv(string row) {
|
||||
"java.util;StringTokenizer;false;StringTokenizer;;;Argument[0];Argument[-1];taint",
|
||||
"java.beans;XMLDecoder;false;XMLDecoder;;;Argument[0];Argument[-1];taint",
|
||||
"com.esotericsoftware.kryo.io;Input;false;Input;;;Argument[0];Argument[-1];taint",
|
||||
"com.esotericsoftware.kryo5.io;Input;false;Input;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;BufferedInputStream;false;BufferedInputStream;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;DataInputStream;false;DataInputStream;;;Argument[0];Argument[-1];taint",
|
||||
"java.io;ByteArrayInputStream;false;ByteArrayInputStream;;;Argument[0];Argument[-1];taint",
|
||||
|
||||
@@ -3,19 +3,60 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.FlowSteps
|
||||
|
||||
/**
|
||||
* The type `com.esotericsoftware.kryo.Kryo`.
|
||||
*/
|
||||
class Kryo extends RefType {
|
||||
Kryo() { this.hasQualifiedName("com.esotericsoftware.kryo", "Kryo") }
|
||||
Kryo() {
|
||||
hasQualifiedName("com.esotericsoftware.kryo", "Kryo") or
|
||||
hasQualifiedName("com.esotericsoftware.kryo5", "Kryo")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Kryo input stream.
|
||||
*/
|
||||
class KryoInput extends RefType {
|
||||
KryoInput() { this.hasQualifiedName("com.esotericsoftware.kryo.io", "Input") }
|
||||
KryoInput() {
|
||||
hasQualifiedName("com.esotericsoftware.kryo.io", "Input") or
|
||||
hasQualifiedName("com.esotericsoftware.kryo5.io", "Input")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Kryo pool.
|
||||
*/
|
||||
class KryoPool extends RefType {
|
||||
KryoPool() {
|
||||
hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool") or
|
||||
hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Kryo pool builder.
|
||||
*/
|
||||
class KryoPoolBuilder extends RefType {
|
||||
KryoPoolBuilder() {
|
||||
hasQualifiedName("com.esotericsoftware.kryo.pool", "KryoPool$Builder") or
|
||||
hasQualifiedName("com.esotericsoftware.kryo5.pool", "KryoPool$Builder")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Kryo pool builder method used in a fluent API call chain.
|
||||
*/
|
||||
class KryoPoolBuilderMethod extends Method {
|
||||
KryoPoolBuilderMethod() {
|
||||
getDeclaringType() instanceof KryoPoolBuilder and
|
||||
(
|
||||
getReturnType() instanceof KryoPoolBuilder or
|
||||
getReturnType() instanceof KryoPool
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,3 +86,13 @@ class KryoEnableWhiteListing extends MethodAccess {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A KryoPool method that uses a Kryo instance.
|
||||
*/
|
||||
class KryoPoolRunMethod extends Method {
|
||||
KryoPoolRunMethod() {
|
||||
getDeclaringType() instanceof KryoPool and
|
||||
hasName("run")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,65 @@ class SafeKryo extends DataFlow2::Configuration {
|
||||
ma.getMethod() instanceof KryoReadObjectMethod
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
stepKryoPoolBuilderFactoryArgToConstructor(node1, node2) or
|
||||
stepKryoPoolRunMethodAccessQualifierToFunctionalArgument(node1, node2) or
|
||||
stepKryoPoolBuilderChainMethod(node1, node2) or
|
||||
stepKryoPoolBorrowMethod(node1, node2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds when a functional expression is used to create a `KryoPool.Builder`.
|
||||
* Eg. `new KryoPool.Builder(() -> new Kryo())`
|
||||
*/
|
||||
private predicate stepKryoPoolBuilderFactoryArgToConstructor(
|
||||
DataFlow::Node node1, DataFlow::Node node2
|
||||
) {
|
||||
exists(ConstructorCall cc, FunctionalExpr fe |
|
||||
cc.getConstructedType() instanceof KryoPoolBuilder and
|
||||
fe.asMethod().getBody().getAStmt().(ReturnStmt).getResult() = node1.asExpr() and
|
||||
node2.asExpr() = cc and
|
||||
cc.getArgument(0) = fe
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds when a `KryoPool.run` is called to use a `Kryo` instance.
|
||||
* Eg. `pool.run(kryo -> ...)`
|
||||
*/
|
||||
private predicate stepKryoPoolRunMethodAccessQualifierToFunctionalArgument(
|
||||
DataFlow::Node node1, DataFlow::Node node2
|
||||
) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod() instanceof KryoPoolRunMethod and
|
||||
node1.asExpr() = ma.getQualifier() and
|
||||
ma.getArgument(0).(FunctionalExpr).asMethod().getParameter(0) = node2.asParameter()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds when a `KryoPool.Builder` method is called fluently.
|
||||
*/
|
||||
private predicate stepKryoPoolBuilderChainMethod(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod() instanceof KryoPoolBuilderMethod and
|
||||
ma = node2.asExpr() and
|
||||
ma.getQualifier() = node1.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds when a `KryoPool.borrow` method is called.
|
||||
*/
|
||||
private predicate stepKryoPoolBorrowMethod(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getMethod() =
|
||||
any(Method m | m.getDeclaringType() instanceof KryoPool and m.hasName("borrow")) and
|
||||
node1.asExpr() = ma.getQualifier() and
|
||||
node2.asExpr() = ma
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
|
||||
|
||||
Reference in New Issue
Block a user