Skip to content

Commit 16be908

Browse files
committed
add Miniz
1 parent 56bc32f commit 16be908

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
/**
2+
* @name User-controlled file decompression
3+
* @description User-controlled data that flows into decompression library APIs without checking the compression rate is dangerous
4+
* @kind path-problem
5+
* @problem.severity error
6+
* @security-severity 7.8
7+
* @precision high
8+
* @id cpp/user-controlled-file-decompression-miniz
9+
* @tags security
10+
* experimental
11+
* external/cwe/cwe-409
12+
*/
13+
14+
import cpp
15+
import semmle.code.cpp.ir.dataflow.TaintTracking
16+
import semmle.code.cpp.security.FlowSources
17+
18+
/**
19+
* A unsigned char Variable is used in Flow source
20+
*/
21+
private class Uint8Var extends VariableAccess {
22+
Uint8Var() { this.getType().stripType().resolveTypedefs() instanceof UnsignedCharType }
23+
}
24+
25+
/**
26+
* The `mz_streamp`, `z_stream` Variables are used in Flow source
27+
*/
28+
private class MzStreampVar extends VariableAccess {
29+
MzStreampVar() { this.getType().hasName(["mz_streamp", "z_stream"]) }
30+
}
31+
32+
/**
33+
* A Char Variable is used in Flow source
34+
*/
35+
private class CharVar extends VariableAccess {
36+
CharVar() { this.getType().stripType() instanceof CharType }
37+
}
38+
39+
/**
40+
* A `mz_zip_archive` Variable is used in Flow source
41+
*/
42+
private class MzZipArchiveVar extends VariableAccess {
43+
MzZipArchiveVar() { this.getType().hasName("mz_zip_archive") }
44+
}
45+
46+
/**
47+
* The `mz_uncompress` functions are used in Flow Sink
48+
*/
49+
private class MzUncompress extends Function {
50+
MzUncompress() { this.hasGlobalName(["uncompress", "mz_uncompress", "mz_uncompress2"]) }
51+
}
52+
53+
/**
54+
* The `mz_inflate` functions are used in Flow Sink
55+
*/
56+
private class MzInflate extends Function {
57+
MzInflate() { this.hasGlobalName(["mz_inflate", "inflate"]) }
58+
}
59+
60+
/**
61+
* The `mz_inflateInit` functions are used in Flow Sink
62+
*/
63+
private class MzInflateInit extends Function {
64+
MzInflateInit() { this.hasGlobalName(["inflateInit", "mz_inflateInit"]) }
65+
}
66+
67+
/**
68+
* The `mz_zip_reader_extract_*` functions are used in Flow Sink
69+
*/
70+
private class MzZipReaderExtract extends Function {
71+
MzZipReaderExtract() {
72+
this.hasGlobalName([
73+
"mz_zip_reader_extract_file_to_heap", "mz_zip_reader_extract_to_heap",
74+
"mz_zip_reader_extract_to_callback"
75+
])
76+
}
77+
}
78+
79+
/**
80+
* The `mz_zip_reader_locate_file_*` functions are used in Flow Sink
81+
*/
82+
private class MzZipReaderLocateFile extends Function {
83+
MzZipReaderLocateFile() {
84+
this.hasGlobalName(["mz_zip_reader_locate_file", "mz_zip_reader_locate_file_v2"])
85+
}
86+
}
87+
88+
/**
89+
* The `tinfl_decompress_mem_*` functions are used in Flow Sink
90+
*/
91+
private class TinflDecompressMem extends Function {
92+
TinflDecompressMem() {
93+
this.hasGlobalName([
94+
"tinfl_decompress_mem_to_callback", "tinfl_decompress_mem_to_mem",
95+
"tinfl_decompress_mem_to_heap"
96+
])
97+
}
98+
}
99+
100+
/**
101+
* The `tinfl_decompress_*` functions are used in Flow Sink
102+
*/
103+
private class TinflDecompress extends Function {
104+
TinflDecompress() { this.hasGlobalName(["tinfl_decompress"]) }
105+
}
106+
107+
module MinizTaintConfig implements DataFlow::StateConfigSig {
108+
class FlowState = DataFlow::FlowState;
109+
110+
predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
111+
source.asExpr() instanceof Uint8Var and
112+
state = ""
113+
or
114+
source.asExpr() instanceof CharVar and
115+
state = ""
116+
or
117+
source.asExpr() instanceof MzZipArchiveVar and
118+
state = ""
119+
or
120+
source.asExpr() instanceof MzStreampVar and
121+
state = ""
122+
or
123+
// source of inflate(&arg0) is OK
124+
// but the sink which is a call to MzInflate Function first arg can not be determined
125+
// if I debug the query we'll reach to the first arg, it is weird I think.
126+
source.asDefiningArgument() =
127+
any(Call call | call.getTarget() instanceof MzInflateInit).getArgument(0) and
128+
state = "inflate"
129+
}
130+
131+
predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
132+
exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress |
133+
fc.getArgument(2) = sink.asExpr() and
134+
state = ""
135+
)
136+
or
137+
exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderExtract |
138+
fc.getArgument(1) = sink.asExpr() and
139+
state = ""
140+
)
141+
or
142+
exists(FunctionCall fc | fc.getTarget() instanceof MzInflate |
143+
fc.getArgument(0) = sink.asExpr() and
144+
state = "inflate"
145+
)
146+
or
147+
exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompress |
148+
fc.getArgument(1) = sink.asExpr() and
149+
state = ""
150+
)
151+
or
152+
exists(FunctionCall fc | fc.getTarget() instanceof TinflDecompressMem |
153+
fc.getArgument(0) = sink.asExpr() and
154+
state = ""
155+
)
156+
}
157+
158+
predicate isAdditionalFlowStep(
159+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
160+
DataFlow::FlowState state2
161+
) {
162+
exists(FunctionCall fc | fc.getTarget() instanceof MzUncompress |
163+
node1.asExpr() = fc.getArgument(2) and
164+
node2.asExpr() = fc.getArgument(0) and
165+
state1 = "" and
166+
state2 = ""
167+
)
168+
or
169+
exists(FunctionCall fc | fc.getTarget() instanceof MzZipReaderLocateFile |
170+
node1.asExpr() = fc.getArgument(1) and
171+
node2.asExpr() = fc.getArgument(3) and
172+
state1 = "" and
173+
state2 = ""
174+
)
175+
}
176+
177+
predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) { none() }
178+
}
179+
180+
module MinizTaint = TaintTracking::GlobalWithState<MinizTaintConfig>;
181+
182+
import MinizTaint::PathGraph
183+
184+
from MinizTaint::PathNode source, MinizTaint::PathNode sink
185+
where MinizTaint::flowPath(source, sink)
186+
select sink.getNode(), source, sink, "This Decompressiondepends on a $@.", source.getNode(),
187+
"potentially untrusted source"

0 commit comments

Comments
 (0)