use abstract class for decompression flow steps

This commit is contained in:
am0o0
2024-06-26 12:45:31 +02:00
parent 656dc4e276
commit 361ad6be6a
4 changed files with 67 additions and 28 deletions

View File

@@ -1,8 +1,16 @@
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
/**
* The Decompression Sink instances, extend this class to defind new decompression sinks.
* The Decompression Sink instances, extend this class to define new decompression sinks.
*/
abstract class DecompressionFunction extends Function {
abstract int getArchiveParameterIndex();
}
/**
* The Decompression Flow Steps, extend this class to define new decompression sinks.
*/
abstract class DecompressionFlowStep extends Function {
abstract predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2);
}

View File

@@ -29,27 +29,7 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig {
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() instanceof UnzOpenFunction |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc
)
or
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_reader_entry |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc.getArgument(1)
)
or
exists(FunctionCall fc | fc.getTarget() instanceof Mz_zip_entry |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc.getArgument(1)
)
or
exists(FunctionCall fc |
fc.getTarget() instanceof GzopenFunction or fc.getTarget() instanceof GzdopenFunction
|
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc
)
any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2)
}
}

View File

@@ -8,7 +8,7 @@ import semmle.code.cpp.security.FlowSources
import DecompressionBomb
/**
* The `mz_zip_entry` function is used in flow source.
* The `mz_zip_entry` function is used in flow sink.
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md)
*/
class Mz_zip_entry extends DecompressionFunction {
@@ -17,6 +17,21 @@ class Mz_zip_entry extends DecompressionFunction {
override int getArchiveParameterIndex() { result = 1 }
}
/**
* The `mz_zip_entry` function is used in flow steps.
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip.md)
*/
class Mz_zip_entry_flow_steps extends DecompressionFlowStep {
Mz_zip_entry_flow_steps() { this.hasGlobalName("mz_zip_entry_read") }
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() = this |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc.getArgument(1)
)
}
}
/**
* The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow source.
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md)
@@ -32,9 +47,31 @@ class Mz_zip_reader_entry extends DecompressionFunction {
override int getArchiveParameterIndex() { result = 1 }
}
/**
* The `mz_zip_reader_entry_*` and `mz_zip_reader_save_all` functions are used in flow steps.
* [docuemnt](https://github.com/zlib-ng/minizip-ng/blob/master/doc/mz_zip_rw.md)
*/
class Mz_zip_reader_entry_flow_steps extends DecompressionFlowStep {
Mz_zip_reader_entry_flow_steps() { this instanceof Mz_zip_reader_entry }
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() = this |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc.getArgument(1)
)
}
}
/**
* The `UnzOpen` function as a flow source.
*/
class UnzOpenFunction extends Function {
class UnzOpenFunction extends DecompressionFlowStep {
UnzOpenFunction() { this.hasGlobalName(["UnzOpen", "unzOpen64", "unzOpen2", "unzOpen2_64"]) }
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() = this |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc
)
}
}

View File

@@ -41,19 +41,33 @@ class GzReadFunction extends DecompressionFunction {
}
/**
* The `gzdopen` function.
* The `gzdopen` function is used in flow steps.
*
* `gzdopen(int fd, const char *mode)`
*/
class GzdopenFunction extends Function {
class GzdopenFunction extends DecompressionFlowStep {
GzdopenFunction() { this.hasGlobalName("gzdopen") }
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() = this |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc
)
}
}
/**
* The `gzopen` function.
* The `gzopen` function is used in flow steps.
*
* `gzopen(const char *path, const char *mode)`
*/
class GzopenFunction extends Function {
class GzopenFunction extends DecompressionFlowStep {
GzopenFunction() { this.hasGlobalName("gzopen") }
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(FunctionCall fc | fc.getTarget() = this |
node1.asExpr() = fc.getArgument(0) and
node2.asExpr() = fc
)
}
}