-
Notifications
You must be signed in to change notification settings - Fork 188
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
codeql: add _delete and _leave checking queries
- Loading branch information
1 parent
50cca6a
commit 4a4802a
Showing
9 changed files
with
192 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/** | ||
* @name Double delete | ||
* @description Double delete: not all _delete functions are idempotent currently. | ||
* @kind path-problem | ||
* @problem.severity warning | ||
* @precision high | ||
* @id asymmetric-research/double-delete | ||
* @tags correctness | ||
* maintainability | ||
*/ | ||
|
||
import cpp | ||
|
||
import GenericDoubleFree | ||
import semmle.code.cpp.dataflow.new.DataFlow | ||
import Flow::PathGraph | ||
|
||
bindingset[x] | ||
string matchDelete(string x) { | ||
result = x.regexpCapture("(.*)_delete", 1) | ||
and not x = "fd_aio_delete" /* nbridge wants this to behave idempotent */ | ||
} | ||
|
||
bindingset[x] | ||
string matchNew(string x) { | ||
result = x.regexpCapture("(.*)_new", 1) | ||
} | ||
|
||
|
||
module Flow = DataFlow::GlobalWithState<DoubleFreeConfig<matchDelete/1, matchNew/1>>; | ||
|
||
from | ||
Flow::PathNode source, Flow::PathNode sink | ||
where | ||
Flow::flowPath(source, sink) | ||
and source.getLocation().getStartLine() != sink.getLocation().getStartLine() | ||
and not source.getLocation().getFile().getBaseName().matches("test%") | ||
select sink.getNode(), source, sink, "double delete" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/** | ||
* @name Double leave | ||
* @description Double leave: An object should be joined before being operated on in any way | ||
* @kind path-problem | ||
* @problem.severity warning | ||
* @precision high | ||
* @id asymmetric-research/double-leave | ||
* @tags correctness | ||
* maintainability | ||
*/ | ||
|
||
import cpp | ||
|
||
import GenericDoubleFree | ||
import semmle.code.cpp.dataflow.new.DataFlow | ||
import Flow::PathGraph | ||
|
||
bindingset[x] | ||
string matchLeave(string x) { | ||
result = x.regexpCapture("(.*)_leave", 1) | ||
} | ||
|
||
bindingset[x] | ||
string matchJoin(string x) { | ||
result = x.regexpCapture("(.*)_join", 1) | ||
} | ||
|
||
|
||
module Flow = DataFlow::GlobalWithState<DoubleFreeConfig<matchLeave/1, matchJoin/1>>; | ||
|
||
from | ||
Flow::PathNode source, Flow::PathNode sink | ||
where | ||
Flow::flowPath(source, sink) | ||
and source.getLocation().getStartLine() != sink.getLocation().getStartLine() | ||
select sink.getNode(), source, sink, "double leave" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import cpp | ||
import semmle.code.cpp.dataflow.new.DataFlow | ||
|
||
bindingset[x] | ||
signature string regcap(string x); | ||
|
||
class CandidateCall extends Call { | ||
CandidateCall() { | ||
not ( | ||
this.getLocation().getFile().getBaseName().matches("test%") or | ||
this.getLocation().getFile().getBaseName().matches("%_ci.%") or | ||
this.getLocation().getFile().getBaseName() = "main.c" /* annoying mismatch with funk_init */ | ||
) | ||
} | ||
} | ||
|
||
module DoubleFreeConfig<regcap/1 doubleMatch, regcap/1 barrierMatch> implements | ||
DataFlow::StateConfigSig | ||
{ | ||
class FlowState = string; | ||
|
||
predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { | ||
exists(CandidateCall call | | ||
source.asIndirectArgument() = call.getArgument(0) and | ||
state = doubleMatch(call.getTarget().getName()) | ||
) | ||
} | ||
|
||
predicate isBarrier(DataFlow::Node barrier, DataFlow::FlowState state) { | ||
exists(CandidateCall call | | ||
barrier.asIndirectArgument() = call.getArgument(0) and | ||
state = barrierMatch(call.getTarget().getName()) | ||
) | ||
} | ||
|
||
predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { | ||
exists(CandidateCall call | | ||
sink.asIndirectArgument() = call.getArgument(0) and | ||
state = doubleMatch(call.getTarget().getName()) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* As defence in depth for memory corrputions, we should always check and reset the magic field | ||
* in a _detroy function. This query finds all functions that have a magic field and do not have | ||
* a check for the magic field or a reset of the magic field. | ||
* @id asymmetric-research/no-magic-delete | ||
* @kind problem | ||
* @severity warning | ||
*/ | ||
|
||
import cpp | ||
|
||
class MagicAccess extends FieldAccess { | ||
MagicAccess() { this.getTarget().getName() = "magic" } | ||
} | ||
|
||
class MagicCmp extends ComparisonOperation { | ||
MagicCmp() { exists(MagicAccess ma | this.getAnOperand().getAChild*() = ma) } | ||
} | ||
|
||
class MagicNulling extends Assignment { | ||
MagicNulling() { exists(MagicAccess ma | ma.getEnclosingStmt().getAChild*() = this) } | ||
} | ||
|
||
|
||
class CheckFunction extends Function { | ||
Field magicField; | ||
Type parentType; | ||
|
||
CheckFunction() { | ||
exists(int n | this.getParameter(n) | ||
.getType() = parentType) | ||
and | ||
parentType.stripType() | ||
.(Struct) | ||
.getAField() = magicField and | ||
magicField.getName() = "magic" | ||
and this.getName().regexpCapture("(.*)_(delete|join)", 1) = parentType.getName().regexpCapture("(.*)_t \\*", 1) | ||
} | ||
|
||
predicate hasMagicCmp() { | ||
exists(MagicCmp cmp | cmp.getBasicBlock().getEnclosingFunction() = this) | ||
} | ||
|
||
predicate setsMagicNull() { | ||
exists(MagicNulling n | n.getBasicBlock().getEnclosingFunction() = this) | ||
} | ||
|
||
string getParentType() { | ||
result = parentType.getName() | ||
} | ||
|
||
predicate valid() { | ||
this.hasMagicCmp() and | ||
(this.setsMagicNull() or not this.getName().matches("%_delete")) | ||
} | ||
} | ||
|
||
from CheckFunction f | ||
where not f.valid() | ||
select f, "should check or null magic of " + f.getParentType() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters