Skip to content

Commit b107c4c

Browse files
committed
C++: Fix missing result in 'ModelUtil'. The problem was that 'n.asInstruction()' on line 81 wasn't necessarily a 'CallInstruction' (it could be a conversion).
1 parent c0b04ea commit b107c4c

File tree

3 files changed

+30
-24
lines changed

3 files changed

+30
-24
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,34 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
3232
}
3333

3434
/**
35-
* Gets the instruction that holds the `output` for `call`.
35+
* Gets the node that represents the output of `call` with kind `output` at
36+
* indirection index `indirectionIndex`.
3637
*/
37-
Node callOutput(CallInstruction call, FunctionOutput output) {
38+
private Node callOutputWithIndirectionIndex(
39+
CallInstruction call, FunctionOutput output, int indirectionIndex
40+
) {
3841
// The return value
3942
simpleOutNode(result, call) and
40-
output.isReturnValue()
43+
output.isReturnValue() and
44+
indirectionIndex = 0
4145
or
4246
// The side effect of a call on the value pointed to by an argument or qualifier
43-
exists(int index, int indirectionIndex |
47+
exists(int index |
4448
result.(IndirectArgumentOutNode).getArgumentIndex() = index and
45-
result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex and
49+
result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex - 1 and
4650
result.(IndirectArgumentOutNode).getCallInstruction() = call and
47-
output.isParameterDerefOrQualifierObject(index, indirectionIndex)
51+
output.isParameterDerefOrQualifierObject(index, indirectionIndex - 1)
4852
)
4953
or
50-
exists(int ind |
51-
result = getIndirectReturnOutNode(call, ind) and
52-
output.isReturnValueDeref(ind)
53-
)
54+
result = getIndirectReturnOutNode(call, indirectionIndex) and
55+
output.isReturnValueDeref(indirectionIndex)
56+
}
57+
58+
/**
59+
* Gets the instruction that holds the `output` for `call`.
60+
*/
61+
Node callOutput(CallInstruction call, FunctionOutput output) {
62+
result = callOutputWithIndirectionIndex(call, output, _)
5463
}
5564

5665
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
@@ -76,19 +85,16 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
7685
*/
7786
bindingset[d]
7887
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
79-
exists(DataFlow::Node n | n = callOutput(call, output) and d > 0 |
88+
exists(DataFlow::Node n, int indirectionIndex |
89+
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
90+
|
8091
// The return value
81-
result = getIndirectReturnOutNode(n.asInstruction(), d)
92+
result = callOutputWithIndirectionIndex(call, output, indirectionIndex + d)
8293
or
94+
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and
8395
// If there isn't an indirect out node for the call with indirection `d` then
8496
// we conflate this with the underlying `CallInstruction`.
85-
not exists(getIndirectReturnOutNode(call, d)) and
97+
not exists(getIndirectReturnOutNode(call, indirectionIndex + d)) and
8698
n = result
87-
or
88-
// The side effect of a call on the value pointed to by an argument or qualifier
89-
exists(Operand operand, int indirectionIndex |
90-
Ssa::outNodeHasAddressAndIndex(n, operand, indirectionIndex) and
91-
Ssa::outNodeHasAddressAndIndex(result, operand, indirectionIndex + d)
92-
)
9399
)
94100
}

cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,5 +447,5 @@ void test_indirect_taint() {
447447
int* p = indirect_source();
448448
m[1] = p;
449449
int* q = m[1];
450-
sink(q); // $ MISSING: ast ir
450+
sink(q); // $ ir MISSING: ast
451451
}

cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ struct B {
8585

8686
void test_operator_arrow(std::unique_ptr<A> p, std::unique_ptr<B> q) {
8787
p->x = source();
88-
sink(p->x); // $ ast,ir
88+
sink(p->x); // $ ast MISSING: ir
8989
sink(p->y);
9090

9191
q->a1.x = source();
92-
sink(q->a1.x); // $ ast,ir
92+
sink(q->a1.x); // $ ast MISSING: ir
9393
sink(q->a1.y);
9494
sink(q->a2.x);
9595
}
@@ -101,7 +101,7 @@ void taint_x(A* pa) {
101101
void reverse_taint_smart_pointer() {
102102
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
103103
taint_x(p.get());
104-
sink(p->x); // $ ast,ir
104+
sink(p->x); // $ ast MISSING: ir
105105
}
106106

107107
struct C {
@@ -131,7 +131,7 @@ int nested_shared_ptr_taint(std::shared_ptr<C> p1, std::unique_ptr<std::shared_p
131131

132132
int nested_shared_ptr_taint_cref(std::shared_ptr<C> p1, std::unique_ptr<std::shared_ptr<int>> p2) {
133133
taint_x_shared_cref(p1->q);
134-
sink(p1->q->x); // $ ast,ir
134+
sink(p1->q->x); // $ ast MISSING: ir
135135

136136
getNumberCRef(*p2);
137137
sink(**p2); // $ ast,ir

0 commit comments

Comments
 (0)