Skip to content

Commit f97b103

Browse files
committed
update test files, add one more additional flow step for inflate function, fix gzopen additional flow step thanks to @jketema
1 parent 6f8eec2 commit f97b103

File tree

4 files changed

+27
-35
lines changed

4 files changed

+27
-35
lines changed

cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/DecompressionBombs.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ module DecompressionTaintConfig implements DataFlow::ConfigSig {
2222

2323
predicate isSink(DataFlow::Node sink) {
2424
exists(FunctionCall fc, DecompressionFunction f | fc.getTarget() = f |
25-
fc.getArgument(f.getArchiveParameterIndex()) = sink.asExpr()
25+
fc.getArgument(f.getArchiveParameterIndex()) = sink.asExpr()
2626
)
2727
}
2828

2929
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
30-
any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2)
30+
any(DecompressionFlowStep f).isAdditionalFlowStep(node1, node2) or
31+
nextInAdditionalFlowStep(node1, node2)
3132
}
3233
}
3334

cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibGzopen.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class GzGetsFunction extends DecompressionFunction {
3737
class GzReadFunction extends DecompressionFunction {
3838
GzReadFunction() { this.hasGlobalName("gzread") }
3939

40-
override int getArchiveParameterIndex() { result = 1 }
40+
override int getArchiveParameterIndex() { result = 0 }
4141
}
4242

4343
/**
@@ -66,7 +66,7 @@ class GzopenFunction extends DecompressionFlowStep {
6666

6767
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
6868
exists(FunctionCall fc | fc.getTarget() = this |
69-
node1.asExpr() = fc.getArgument(0) and
69+
node1.asIndirectExpr() = fc.getArgument(0) and
7070
node2.asExpr() = fc
7171
)
7272
}

cpp/ql/src/experimental/query-tests/Security/CWE/CWE-409/ZlibInflator.qll

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,27 @@ import DecompressionBomb
1010
/**
1111
* The `inflate` and `inflateSync` functions are used in flow sink.
1212
*
13-
* `inflate(z_streamp strm, int flush)`
13+
* `inflate(z_stream strm, int flush)`
1414
*
15-
* `inflateSync(z_streamp strm)`
15+
* `inflateSync(z_stream strm)`
1616
*/
1717
class InflateFunction extends DecompressionFunction {
1818
InflateFunction() { this.hasGlobalName(["inflate", "inflateSync"]) }
1919

2020
override int getArchiveParameterIndex() { result = 0 }
2121
}
22+
23+
/**
24+
* The `next_in` member of a `z_stream` variable is used in flow steps.
25+
*/
26+
predicate nextInAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
27+
exists(Variable nextInVar, VariableAccess zStreamAccess |
28+
nextInVar.getDeclaringType().hasName("z_stream") and
29+
nextInVar.hasName("next_in") and
30+
zStreamAccess.getType().hasName("z_stream")
31+
|
32+
nextInVar.getAnAccess().getQualifier().(VariableAccess).getTarget() = zStreamAccess.getTarget() and
33+
node1.asIndirectExpr() = nextInVar.getAnAssignedValue() and
34+
node2.asExpr() = zStreamAccess
35+
)
36+
}

cpp/ql/test/experimental/query-tests/Security/CWE/CWE-409/zlibTest.cpp

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,40 +51,17 @@ namespace std {
5151
}
5252

5353
int UnsafeInflate(char *a) {
54-
// placeholder for the compressed (deflated) version of "a"
55-
char b[50];
56-
// placeholder for the Uncompressed (inflated) version of "b"
57-
char c[50];
58-
59-
// STEP 1.
60-
// zlib struct
61-
z_stream defstream;
62-
defstream.zalloc = Z_NULL;
63-
defstream.zfree = Z_NULL;
64-
defstream.opaque = Z_NULL;
65-
// setup "a" as the input and "b" as the compressed output
66-
defstream.avail_in = (uInt) 50 + 1; // size of input, string + terminator
67-
defstream.next_in = (Bytef *) a; // input char array
68-
defstream.avail_out = (uInt) sizeof(b); // size of output
69-
defstream.next_out = (Bytef *) b; // output char array
70-
71-
// the actual compression work.
72-
deflateInit(&defstream, Z_BEST_COMPRESSION);
73-
deflate(&defstream, Z_FINISH);
74-
deflateEnd(&defstream);
75-
76-
// This is one way of getting the size of the output
77-
// STEP 2.
78-
// inflate b into c
79-
// zlib struct
54+
// placeholder for the Uncompressed (inflated) version of "a"
55+
char c[1024000];
56+
8057
z_stream infstream;
8158
infstream.zalloc = Z_NULL;
8259
infstream.zfree = Z_NULL;
8360
infstream.opaque = Z_NULL;
8461
// setup "b" as the input and "c" as the compressed output
8562
// TOTHINK: Here we can add additional step from Right operand to z_stream variable access
86-
infstream.avail_in = (uInt) ((char *) defstream.next_out - b); // size of input
87-
infstream.next_in = (Bytef *) b; // input char array
63+
infstream.avail_in = (uInt) (1000); // size of input
64+
infstream.next_in = (Bytef *) a; // input char array
8865
infstream.avail_out = (uInt) sizeof(c); // size of output
8966
infstream.next_out = (Bytef *) c; // output char array
9067

@@ -159,7 +136,6 @@ int UnsafeGzgets(char *fileName) {
159136
}
160137
char *buffer = new char[4000000000];
161138
char *result;
162-
result = gzgets(inFileZ, buffer, 1000000000);
163139
while (true) {
164140
result = gzgets(inFileZ, buffer, 1000000000);
165141
if (result == nullptr) {

0 commit comments

Comments
 (0)