mirror of
https://github.com/github/codeql.git
synced 2025-12-19 10:23:15 +01:00
Merge pull request #11311 from MathiasVP/repair-mustflow
C++: Repair `MustFlow` library for use-use flow
This commit is contained in:
@@ -26,11 +26,11 @@ predicate intentionallyReturnsStackPointer(Function f) {
|
||||
class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
override predicate isSource(Instruction source) {
|
||||
// Holds if `source` is a node that represents the use of a stack variable
|
||||
exists(VariableAddressInstruction var, Function func |
|
||||
var = source.asInstruction() and
|
||||
func = var.getEnclosingFunction() and
|
||||
var = source and
|
||||
func = source.getEnclosingFunction() and
|
||||
var.getAstVariable() instanceof StackVariable and
|
||||
// Pointer-to-member types aren't properly handled in the dbscheme.
|
||||
not var.getResultType() instanceof PointerToMemberType and
|
||||
@@ -40,7 +40,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
override predicate isSink(Operand sink) {
|
||||
// Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
|
||||
// a `ReturnValueInstruction`.
|
||||
// We use the `StoreInstruction` instead of the instruction that defines the
|
||||
@@ -48,7 +48,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
exists(StoreInstruction store |
|
||||
store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof
|
||||
IRReturnVariable and
|
||||
sink.asOperand() = store.getSourceValueOperand()
|
||||
sink = store.getSourceValueOperand()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -77,10 +77,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
node2.asInstruction().(FieldAddressInstruction).getObjectAddressOperand() = node1.asOperand()
|
||||
override predicate isAdditionalFlowStep(Operand node1, Instruction node2) {
|
||||
node2.(FieldAddressInstruction).getObjectAddressOperand() = node1
|
||||
or
|
||||
node2.asInstruction().(PointerOffsetInstruction).getLeftOperand() = node1.asOperand()
|
||||
node2.(PointerOffsetInstruction).getLeftOperand() = node1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,6 @@ from
|
||||
ReturnStackAllocatedMemoryConfig conf
|
||||
where
|
||||
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
source.getNode().asInstruction() = var
|
||||
select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(),
|
||||
var.getAst().toString()
|
||||
source.getInstruction() = var
|
||||
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
|
||||
var.getAst(), var.getAst().toString()
|
||||
|
||||
@@ -22,37 +22,40 @@ import PathGraph
|
||||
class UnsafeUseOfThisConfig extends MustFlowConfiguration {
|
||||
UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { isSource(source, _, _) }
|
||||
override predicate isSource(Instruction source) { isSource(source, _, _) }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
override predicate isSink(Operand sink) { isSink(sink, _) }
|
||||
}
|
||||
|
||||
/** Holds if `instr` is a `this` pointer used by the call instruction `call`. */
|
||||
predicate isSink(DataFlow::Node sink, CallInstruction call) {
|
||||
/** Holds if `sink` is a `this` pointer used by the call instruction `call`. */
|
||||
predicate isSink(Operand sink, CallInstruction call) {
|
||||
exists(PureVirtualFunction func |
|
||||
call.getStaticCallTarget() = func and
|
||||
call.getThisArgument() = sink.asInstruction() and
|
||||
call.getThisArgumentOperand() = sink and
|
||||
// Weed out implicit calls to destructors of a base class
|
||||
not func instanceof Destructor
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `init` initializes the `this` pointer in class `c`. */
|
||||
predicate isSource(DataFlow::Node source, string msg, Class c) {
|
||||
exists(InitializeParameterInstruction init | init = source.asInstruction() |
|
||||
(
|
||||
exists(Constructor func |
|
||||
not func instanceof CopyConstructor and
|
||||
not func instanceof MoveConstructor and
|
||||
func = init.getEnclosingFunction() and
|
||||
msg = "construction"
|
||||
)
|
||||
or
|
||||
init.getEnclosingFunction() instanceof Destructor and msg = "destruction"
|
||||
) and
|
||||
init.getIRVariable() instanceof IRThisVariable and
|
||||
init.getEnclosingFunction().getDeclaringType() = c
|
||||
)
|
||||
/**
|
||||
* Holds if `source` initializes the `this` pointer in class `c`.
|
||||
*
|
||||
* The string `msg` describes whether the enclosing function is a
|
||||
* constructor or destructor.
|
||||
*/
|
||||
predicate isSource(InitializeParameterInstruction source, string msg, Class c) {
|
||||
(
|
||||
exists(Constructor func |
|
||||
not func instanceof CopyConstructor and
|
||||
not func instanceof MoveConstructor and
|
||||
func = source.getEnclosingFunction() and
|
||||
msg = "construction"
|
||||
)
|
||||
or
|
||||
source.getEnclosingFunction() instanceof Destructor and msg = "destruction"
|
||||
) and
|
||||
source.getIRVariable() instanceof IRThisVariable and
|
||||
source.getEnclosingFunction().getDeclaringType() = c
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,8 +71,8 @@ predicate flows(
|
||||
) {
|
||||
exists(UnsafeUseOfThisConfig conf |
|
||||
conf.hasFlowPath(source, sink) and
|
||||
isSource(source.getNode(), msg, sourceClass) and
|
||||
isSink(sink.getNode(), call)
|
||||
isSource(source.getInstruction(), msg, sourceClass) and
|
||||
isSink(sink.getInstruction().getAUse(), call)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user