Open
Description
Hey, If I am a code like this:
void pure_alloc(){
void * o = malloc(0x20); // [+] @a
printf("[+] I have been called between the path\n"); // [+] @c
*(int *)(o + 0) = 0x44; // [+] @b
}
I Could easily find the path from |@a->@b||
by this query(Thanks for @smowton help me understand this):
/**
* @name bad malloc
* @kind path-problem
* @id cpp/workshop/unsecure-malloc
*/
import cpp
import DataFlow::PathGraph
import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.dataflow.new.TaintTracking
class BadMallocCall extends FunctionCall{
BadMallocCall(){
this.getTarget().hasGlobalName("malloc")
}
}
class BadMallocConfiguration extends TaintTracking::Configuration{
BadMallocConfiguration() { this = "BadMallocConfiguration" }
// [+] source
override predicate isSource(DataFlow::Node source) {
//source.asExpr().(FunctionCall).getTarget().hasGlobalName("malloc")
exists( BadMallocCall call |
call = source.asExpr()
)
}
// [+] sink
override predicate isSink(DataFlow::Node sink) { // [+] Ensure it has been deference
dereferenced(sink.asExpr())
}
}
from BadMallocConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink, "[+] this pointer is $@ and $@, causing a potential vulnerability.", source, "freed here", sink, "used here"
Is there are anyway to make me know "printf" has been called between in the path a->b?
I have query the document, seems isAdditionalTaintStep is the most related choice. But If I don't misunderstand anything, It just build path from source to sink.
override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(Loop loop, LoopCounter lc |
loop = lc.getALoop() and
loop.getControllingExpr().(RelationalOperation).getGreaterOperand() = pred.asExpr()
|
succ.asExpr() = lc.getVariableAccessInLoop(loop)
)
}
So any tips? Thank u very much.