C++: Return statement inside Guard Block
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
Is the dataFlow guarded if the condition has return statement?
Here's the code
```
#include
#include
bool test_func(const char* str1, const char* str2) {
return strcmp(str1, str2) == 0;
}
struct test_struct {
int a;
int b;
};
int func(int num){
struct test_struct *test = NULL;
if(num > 0) {
test = (test_struct *)calloc(num, sizeof(*test));
if(!test) {
return 1;
}
}
test[0].a = 1;
test[0].b = 2;
return 0;
}
int main() {
func(2);
func(0);
return 0;
}
```
Here's the query
```
/**
* @kind path-problem
*/
import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.controlflow.IRGuards
import Flow::PathGraph
/**
* Holds if `g` is a guard that ensures that `e` is not null when `g` evaluates to `branch`
*/
predicate isNotNullCheck(IRGuardCondition g, Expr e, boolean branch) {
g.comparesEq(any(Instruction instr | instr.getUnconvertedResultExpression() = e).getAUse(),
any(ConstantValueInstruction const | const.getValue() = "0").getAUse(), 0, false, branch)
}
module UAFConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(Expr e | e = source.asExpr() | e.(NullValue).getValue().toInt() = 0)
}
predicate isSink(DataFlow::Node sink) {
dereferenced(sink.asExpr())
}
predicate isBarrier(DataFlow::Node node) {
node = DataFlow::BarrierGuard::getABarrierNode()
}
}
module Flow = DataFlow::Global;
from Flow::PathNode source, Flow::PathNode sink
where Flow::flowPath(source, sink)
select sink, source, sink, "Null ptr deref: $@ and $@.", source, "source", sink, "deref"
```
Output:
1.test=NULL, -> test[0].a , this is TP
2. calloc() , -> test[0].a , this is FP because when calloc return null, test[0] is unreachable..
two more results for test[1], which is same as above..
Is this because Guard Condition can't see the return statement inside the conditional block?
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Start with the supplied C++ reproducer and the query entry points in semmle.code.cpp.dataflow.new.DataFlow, semmle.code.cpp.controlflow.IRGuards, and Flow::PathGraph. Run the query and compare paths through the conditional return for calloc and the null source. Done means determining whether the reported paths are expected and documenting or correcting the guard behavior.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- cpp
- Domaine
- devtools, security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 28/100