mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
C++: Attach PostUpdateNodes to Chi nodes following aschackmull's suggestion
This commit is contained in:
@@ -148,10 +148,10 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
|
||||
*/
|
||||
predicate readStep(Node node1, Content f, Node node2) {
|
||||
exists(FieldAddressInstruction fa, LoadInstruction load |
|
||||
load.getSourceAddress() = fa and
|
||||
node1.asInstruction() = fa.getObjectAddress() and
|
||||
fa.getField() = f.(FieldContent).getField() and
|
||||
load = node2.asInstruction()
|
||||
node1.asInstruction() = load and
|
||||
load.getSourceAddress() = fa and
|
||||
node2.asInstruction().getAnOperand().getAnyDef() = load
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -245,30 +245,19 @@ abstract class PostUpdateNode extends InstructionNode {
|
||||
* setY(&x); // a partial definition of the object `x`.
|
||||
* ```
|
||||
*/
|
||||
abstract class PartialDefinitionNode extends PostUpdateNode, TInstructionNode {
|
||||
/**
|
||||
* Gets the instruction that partially defines the object. This includes
|
||||
* both the instruction that partially defines the object, and the chi
|
||||
* instruction that links up the partial definition to the object.
|
||||
*/
|
||||
final Instruction getInstructionOrChi() {
|
||||
exists(ChiInstruction chi |
|
||||
not chi.isResultConflated() and
|
||||
chi.getPartial() = getInstruction() and
|
||||
result = chi
|
||||
)
|
||||
or
|
||||
result = getInstruction()
|
||||
}
|
||||
}
|
||||
abstract class PartialDefinitionNode extends PostUpdateNode, TInstructionNode {}
|
||||
|
||||
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override StoreInstruction instr;
|
||||
FieldAddressInstruction field;
|
||||
override ChiInstruction instr;
|
||||
|
||||
ExplicitFieldStoreQualifierNode() { field = instr.getDestinationAddress() }
|
||||
ExplicitFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
exists(StoreInstruction store, FieldInstruction field |
|
||||
instr.getPartial() = store and field = store.getDestinationAddress()
|
||||
)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { result.asInstruction() = field.getObjectAddress() }
|
||||
override Node getPreUpdateNode() { result.asInstruction() = instr.getTotal() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,29 +271,29 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
* `getVariableAccess()` equal to `x`.
|
||||
*/
|
||||
class DefinitionByReferenceNode extends PartialDefinitionNode {
|
||||
override WriteSideEffectInstruction instr;
|
||||
override ChiInstruction instr;
|
||||
WriteSideEffectInstruction write;
|
||||
CallInstruction call;
|
||||
|
||||
DefinitionByReferenceNode() { call = instr.getPrimaryInstruction() }
|
||||
DefinitionByReferenceNode() {
|
||||
instr.getPartial() = write and
|
||||
call = write.getPrimaryInstruction() }
|
||||
|
||||
override Node getPreUpdateNode() {
|
||||
result.asInstruction() = call.getPositionalArgument(instr.getIndex())
|
||||
or
|
||||
result.asInstruction() = call.getThisArgument() and
|
||||
instr.getIndex() = -1
|
||||
result.asInstruction() = instr.getTotal()
|
||||
}
|
||||
|
||||
/** Gets the argument corresponding to this node. */
|
||||
Expr getArgument() {
|
||||
result = call.getPositionalArgument(instr.getIndex()).getUnconvertedResultExpression()
|
||||
result = call.getPositionalArgument(write.getIndex()).getUnconvertedResultExpression()
|
||||
or
|
||||
result = call.getThisArgument().getUnconvertedResultExpression() and
|
||||
instr.getIndex() = -1
|
||||
write.getIndex() = -1
|
||||
}
|
||||
|
||||
/** Gets the parameter through which this value is assigned. */
|
||||
Parameter getParameter() {
|
||||
exists(CallInstruction ci | result = ci.getStaticCallTarget().getParameter(instr.getIndex()))
|
||||
exists(CallInstruction ci | result = ci.getStaticCallTarget().getParameter(write.getIndex()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,10 +382,10 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
|
||||
or
|
||||
exists(LoadInstruction load |
|
||||
load.getSourceValueOperand().getAnyDef() =
|
||||
nodeFrom.(PartialDefinitionNode).getInstructionOrChi() and
|
||||
nodeTo.asInstruction() = load.getSourceAddress().(FieldAddressInstruction).getObjectAddress()
|
||||
exists(LoadInstruction load, ChiInstruction chi |
|
||||
nodeTo.asInstruction() = load and
|
||||
nodeFrom.asInstruction() = chi and
|
||||
load.getSourceValueOperand().getAnyDef() = chi
|
||||
)
|
||||
}
|
||||
|
||||
@@ -423,6 +412,12 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
|
||||
//
|
||||
// Flow through the partial operand belongs in the taint-tracking libraries
|
||||
// for now.
|
||||
|
||||
// TODO: To capture flow from a partial definition of an object (i.e., a field write) to the object
|
||||
// we add dataflow through partial chi operands, but only if the chi node is not the chi node for all
|
||||
// aliased memory.
|
||||
iTo.getAnOperand().(ChiPartialOperand).getDef() = iFrom and not iFrom.isResultConflated()
|
||||
or
|
||||
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
|
||||
or
|
||||
// Flow through modeled functions
|
||||
|
||||
@@ -1,107 +1,27 @@
|
||||
edges
|
||||
| aliasing.cpp:9:3:9:22 | Store : void | aliasing.cpp:9:3:9:22 | Store [m1] : void |
|
||||
| aliasing.cpp:9:3:9:22 | Store [m1] : void | aliasing.cpp:25:17:25:19 | BufferMayWriteSideEffect [m1] : void |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input : void | aliasing.cpp:9:3:9:22 | Store : void |
|
||||
| aliasing.cpp:13:3:13:21 | Store : void | aliasing.cpp:13:3:13:21 | Store [m1] : void |
|
||||
| aliasing.cpp:13:3:13:21 | Store [m1] : void | aliasing.cpp:26:19:26:20 | BufferMayWriteSideEffect [m1] : void |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input : void | aliasing.cpp:13:3:13:21 | Store : void |
|
||||
| aliasing.cpp:25:17:25:19 | BufferMayWriteSideEffect [m1] : void | aliasing.cpp:29:8:29:9 | s1 [m1] : void |
|
||||
| aliasing.cpp:26:19:26:20 | BufferMayWriteSideEffect [m1] : void | aliasing.cpp:30:8:30:9 | s2 [m1] : void |
|
||||
| aliasing.cpp:29:8:29:9 | s1 [m1] : void | aliasing.cpp:29:11:29:12 | m1 |
|
||||
| aliasing.cpp:30:8:30:9 | s2 [m1] : void | aliasing.cpp:30:11:30:12 | m1 |
|
||||
| aliasing.cpp:37:3:37:24 | Store : void | aliasing.cpp:37:3:37:24 | Store [m1] : void |
|
||||
| aliasing.cpp:37:3:37:24 | Store : void | aliasing.cpp:38:11:38:12 | m1 |
|
||||
| aliasing.cpp:37:3:37:24 | Store [m1] : void | aliasing.cpp:38:8:38:9 | s1 [m1] : void |
|
||||
| aliasing.cpp:37:13:37:22 | call to user_input : void | aliasing.cpp:37:3:37:24 | Store : void |
|
||||
| aliasing.cpp:37:13:37:22 | call to user_input : void | aliasing.cpp:38:11:38:12 | m1 |
|
||||
| aliasing.cpp:38:8:38:9 | s1 [m1] : void | aliasing.cpp:38:11:38:12 | m1 |
|
||||
| aliasing.cpp:42:3:42:22 | Store : void | aliasing.cpp:42:3:42:22 | Store [m1] : void |
|
||||
| aliasing.cpp:42:3:42:22 | Store : void | aliasing.cpp:43:13:43:14 | m1 |
|
||||
| aliasing.cpp:42:3:42:22 | Store [m1] : void | aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void |
|
||||
| aliasing.cpp:42:11:42:20 | call to user_input : void | aliasing.cpp:42:3:42:22 | Store : void |
|
||||
| aliasing.cpp:42:11:42:20 | call to user_input : void | aliasing.cpp:43:13:43:14 | m1 |
|
||||
| aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void | aliasing.cpp:43:13:43:14 | m1 |
|
||||
| aliasing.cpp:79:3:79:22 | Store : void | aliasing.cpp:79:3:79:22 | Store [m1] : void |
|
||||
| aliasing.cpp:79:3:79:22 | Store : void | aliasing.cpp:80:12:80:13 | m1 |
|
||||
| aliasing.cpp:79:3:79:22 | Store [m1] : void | aliasing.cpp:80:10:80:10 | s [m1] : void |
|
||||
| aliasing.cpp:79:11:79:20 | call to user_input : void | aliasing.cpp:79:3:79:22 | Store : void |
|
||||
| aliasing.cpp:79:11:79:20 | call to user_input : void | aliasing.cpp:80:12:80:13 | m1 |
|
||||
| aliasing.cpp:80:10:80:10 | s [m1] : void | aliasing.cpp:80:12:80:13 | m1 |
|
||||
| aliasing.cpp:86:3:86:21 | Store : void | aliasing.cpp:86:3:86:21 | Store [m1] : void |
|
||||
| aliasing.cpp:86:3:86:21 | Store : void | aliasing.cpp:87:12:87:13 | m1 |
|
||||
| aliasing.cpp:86:3:86:21 | Store [m1] : void | aliasing.cpp:87:10:87:10 | s [m1] : void |
|
||||
| aliasing.cpp:86:10:86:19 | call to user_input : void | aliasing.cpp:86:3:86:21 | Store : void |
|
||||
| aliasing.cpp:86:10:86:19 | call to user_input : void | aliasing.cpp:87:12:87:13 | m1 |
|
||||
| aliasing.cpp:87:10:87:10 | s [m1] : void | aliasing.cpp:87:12:87:13 | m1 |
|
||||
| aliasing.cpp:92:3:92:23 | Store : void | aliasing.cpp:92:3:92:23 | Store [m1] : void |
|
||||
| aliasing.cpp:92:3:92:23 | Store : void | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| aliasing.cpp:92:3:92:23 | Store [m1] : void | aliasing.cpp:93:10:93:10 | s [m1] : void |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input : void | aliasing.cpp:92:3:92:23 | Store : void |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input : void | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] : void | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| struct_init.c:20:20:20:29 | Store : void | struct_init.c:20:20:20:29 | Store [a] : void |
|
||||
| struct_init.c:20:20:20:29 | Store : void | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:20:20:20:29 | Store [a] : void | struct_init.c:22:8:22:9 | ab [a] : void |
|
||||
| struct_init.c:20:20:20:29 | call to user_input : void | struct_init.c:20:20:20:29 | Store : void |
|
||||
| struct_init.c:20:20:20:29 | call to user_input : void | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:22:8:22:9 | ab [a] : void | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:27:7:27:16 | Store : void | struct_init.c:27:7:27:16 | Store [a] : void |
|
||||
| struct_init.c:27:7:27:16 | Store : void | struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:27:7:27:16 | Store [a] : void | struct_init.c:31:14:31:21 | nestedAB [a] : void |
|
||||
| struct_init.c:27:7:27:16 | call to user_input : void | struct_init.c:27:7:27:16 | Store : void |
|
||||
| struct_init.c:27:7:27:16 | call to user_input : void | struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [a] : void | struct_init.c:31:23:31:23 | a |
|
||||
nodes
|
||||
| aliasing.cpp:9:3:9:22 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:9:3:9:22 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:13:3:13:21 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:13:3:13:21 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:25:17:25:19 | BufferMayWriteSideEffect [m1] : void | semmle.label | BufferMayWriteSideEffect [m1] : void |
|
||||
| aliasing.cpp:26:19:26:20 | BufferMayWriteSideEffect [m1] : void | semmle.label | BufferMayWriteSideEffect [m1] : void |
|
||||
| aliasing.cpp:29:8:29:9 | s1 [m1] : void | semmle.label | s1 [m1] : void |
|
||||
| aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:30:8:30:9 | s2 [m1] : void | semmle.label | s2 [m1] : void |
|
||||
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:37:3:37:24 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:37:3:37:24 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:37:13:37:22 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:38:8:38:9 | s1 [m1] : void | semmle.label | s1 [m1] : void |
|
||||
| aliasing.cpp:38:11:38:12 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:42:3:42:22 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:42:3:42:22 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:42:11:42:20 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void | semmle.label | (reference dereference) [m1] : void |
|
||||
| aliasing.cpp:43:13:43:14 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:79:3:79:22 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:79:3:79:22 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:79:11:79:20 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:80:10:80:10 | s [m1] : void | semmle.label | s [m1] : void |
|
||||
| aliasing.cpp:80:12:80:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:86:3:86:21 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:86:3:86:21 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:86:10:86:19 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:87:10:87:10 | s [m1] : void | semmle.label | s [m1] : void |
|
||||
| aliasing.cpp:87:12:87:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:92:3:92:23 | Store : void | semmle.label | Store : void |
|
||||
| aliasing.cpp:92:3:92:23 | Store [m1] : void | semmle.label | Store [m1] : void |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] : void | semmle.label | s [m1] : void |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
|
||||
| struct_init.c:20:20:20:29 | Store : void | semmle.label | Store : void |
|
||||
| struct_init.c:20:20:20:29 | Store [a] : void | semmle.label | Store [a] : void |
|
||||
| struct_init.c:20:20:20:29 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| struct_init.c:22:8:22:9 | ab [a] : void | semmle.label | ab [a] : void |
|
||||
| struct_init.c:22:11:22:11 | a | semmle.label | a |
|
||||
| struct_init.c:27:7:27:16 | Store : void | semmle.label | Store : void |
|
||||
| struct_init.c:27:7:27:16 | Store [a] : void | semmle.label | Store [a] : void |
|
||||
| struct_init.c:27:7:27:16 | call to user_input : void | semmle.label | call to user_input : void |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [a] : void | semmle.label | nestedAB [a] : void |
|
||||
| struct_init.c:31:23:31:23 | a | semmle.label | a |
|
||||
#select
|
||||
| aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input : void | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input : void | call to user_input : void |
|
||||
| aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input : void | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input : void | call to user_input : void |
|
||||
| aliasing.cpp:38:11:38:12 | m1 | aliasing.cpp:37:13:37:22 | call to user_input : void | aliasing.cpp:38:11:38:12 | m1 | m1 flows from $@ | aliasing.cpp:37:13:37:22 | call to user_input : void | call to user_input : void |
|
||||
| aliasing.cpp:43:13:43:14 | m1 | aliasing.cpp:42:11:42:20 | call to user_input : void | aliasing.cpp:43:13:43:14 | m1 | m1 flows from $@ | aliasing.cpp:42:11:42:20 | call to user_input : void | call to user_input : void |
|
||||
| aliasing.cpp:80:12:80:13 | m1 | aliasing.cpp:79:11:79:20 | call to user_input : void | aliasing.cpp:80:12:80:13 | m1 | m1 flows from $@ | aliasing.cpp:79:11:79:20 | call to user_input : void | call to user_input : void |
|
||||
|
||||
Reference in New Issue
Block a user