C++: Attach PostUpdateNodes to Chi nodes following aschackmull's suggestion

This commit is contained in:
Mathias Vorreiter Pedersen
2020-04-05 22:35:26 +02:00
parent ce5d8d516f
commit 317734f41e
3 changed files with 31 additions and 116 deletions

View File

@@ -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
)
}

View File

@@ -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

View File

@@ -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 |