Skip to content

Commit 9f40886

Browse files
jbjrdmarsh2
authored andcommitted
C++: Don't allow taint out of a field read
except if it's from a union. This prevents field conflation through buffers of `UnknownType`.
1 parent a0b26d6 commit 9f40886

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,19 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
199199
// Flow through pointer dereference
200200
i2.(LoadInstruction).getSourceAddress() = i1
201201
or
202-
i2.(UnaryInstruction).getUnary() = i1
202+
// Unary instructions tend to preserve enough information in practice that we
203+
// want taint to flow through.
204+
// The exception is `FieldAddressInstruction`. Together with the rule for
205+
// `LoadInstruction` above and for `ChiInstruction` below, flow through
206+
// `FieldAddressInstruction` could cause flow into one field to come out an
207+
// unrelated field. This would happen across function boundaries, where the IR
208+
// would not be able to match loads to stores.
209+
i2.(UnaryInstruction).getUnary() = i1 and
210+
(
211+
not i2 instanceof FieldAddressInstruction
212+
or
213+
i2.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
214+
)
203215
or
204216
// Flow out of definition-by-reference
205217
i2.(ChiInstruction).getPartial() = i1.(WriteSideEffectInstruction) and
@@ -213,7 +225,7 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
213225
or
214226
t instanceof ArrayType
215227
or
216-
// Buffers or unknown size
228+
// Buffers of unknown size
217229
t instanceof UnknownType
218230
)
219231
or

0 commit comments

Comments
 (0)