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`.
This commit is contained in:
Jonas Jensen
2020-04-08 15:25:26 +02:00
committed by Robert Marsh
parent a0b26d66a4
commit 9f40886af9

View File

@@ -199,7 +199,19 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
// Flow through pointer dereference
i2.(LoadInstruction).getSourceAddress() = i1
or
i2.(UnaryInstruction).getUnary() = i1
// Unary instructions tend to preserve enough information in practice that we
// want taint to flow through.
// The exception is `FieldAddressInstruction`. Together with the rule for
// `LoadInstruction` above and for `ChiInstruction` below, flow through
// `FieldAddressInstruction` could cause flow into one field to come out an
// unrelated field. This would happen across function boundaries, where the IR
// would not be able to match loads to stores.
i2.(UnaryInstruction).getUnary() = i1 and
(
not i2 instanceof FieldAddressInstruction
or
i2.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
)
or
// Flow out of definition-by-reference
i2.(ChiInstruction).getPartial() = i1.(WriteSideEffectInstruction) and
@@ -213,7 +225,7 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
or
t instanceof ArrayType
or
// Buffers or unknown size
// Buffers of unknown size
t instanceof UnknownType
)
or