Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3befa1c

Browse files
authored
Merge pull request #10965 from MathiasVP/fix-gettypeimpl-in-ir-dataflow
C++: Fix `getType` in IR dataflow
2 parents 557b94c + 39b2681 commit 3befa1c

5 files changed

Lines changed: 144 additions & 49 deletions

File tree

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

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -366,22 +366,20 @@ class OperandNode extends Node, TOperandNode {
366366
}
367367

368368
/**
369-
* Returns `t`, but stripped of the `n` outermost pointers, references, etc.
369+
* Returns `t`, but stripped of the outermost pointer, reference, etc.
370370
*
371-
* For example, `stripPointers(int*&, 2)` is `int` and `stripPointers(int*, 0)` is `int*`.
371+
* For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`.
372372
*/
373-
private Type stripPointers(Type t, int n) {
374-
result = t and n = 0
373+
private Type stripPointer(Type t) {
374+
result = t.(PointerType).getBaseType()
375375
or
376-
result = stripPointers(t.(PointerType).getBaseType(), n - 1)
376+
result = t.(ArrayType).getBaseType()
377377
or
378-
result = stripPointers(t.(ArrayType).getBaseType(), n - 1)
378+
result = t.(ReferenceType).getBaseType()
379379
or
380-
result = stripPointers(t.(ReferenceType).getBaseType(), n - 1)
380+
result = t.(PointerToMemberType).getBaseType()
381381
or
382-
result = stripPointers(t.(PointerToMemberType).getBaseType(), n - 1)
383-
or
384-
result = stripPointers(t.(FunctionPointerIshType).getBaseType(), n - 1)
382+
result = t.(FunctionPointerIshType).getBaseType()
385383
}
386384

387385
/**
@@ -611,36 +609,12 @@ class IndirectReturnOutNode extends Node {
611609
int getIndirectionIndex() { result = indirectionIndex }
612610
}
613611

614-
private PointerType getGLValueType(Type t, int indirectionIndex) {
615-
result.getBaseType() = stripPointers(t, indirectionIndex - 1)
616-
}
617-
618-
bindingset[isGLValue]
619-
private DataFlowType getTypeImpl(Type t, int indirectionIndex, boolean isGLValue) {
620-
if isGLValue = true
621-
then
622-
result = getGLValueType(t, indirectionIndex)
623-
or
624-
// Ideally, the above case would cover all glvalue cases. However, consider the case where
625-
// the database consists only of:
626-
// ```
627-
// void test() {
628-
// int* x;
629-
// x = nullptr;
630-
// }
631-
// ```
632-
// and we want to compute the type of `*x` in the assignment `x = nullptr`. Here, `x` is an lvalue
633-
// of type int* (which morally is an int**). So when we call `getTypeImpl` it will be with the
634-
// parameters:
635-
// - t = int*
636-
// - indirectionIndex = 1 (when we want to model the dataflow node corresponding to *x)
637-
// - isGLValue = true
638-
// In this case, `getTypeImpl(t, indirectionIndex, isGLValue)` should give back `int**`. In this
639-
// case, however, `int**` does not exist in the database. So instead we return int* (which is
640-
// wrong, but at least we have a type).
641-
not exists(getGLValueType(t, indirectionIndex)) and
642-
result = stripPointers(t, indirectionIndex - 1)
643-
else result = stripPointers(t, indirectionIndex)
612+
private Type getTypeImpl(Type t, int indirectionIndex) {
613+
indirectionIndex = 0 and
614+
result = t
615+
or
616+
indirectionIndex > 0 and
617+
result = getTypeImpl(stripPointer(t), indirectionIndex - 1)
644618
}
645619

646620
/**
@@ -665,8 +639,8 @@ class IndirectOperand extends Node, TIndirectOperand {
665639
override Declaration getEnclosingCallable() { result = this.getFunction() }
666640

667641
override DataFlowType getType() {
668-
exists(boolean isGLValue | if operand.isGLValue() then isGLValue = true else isGLValue = false |
669-
result = getTypeImpl(operand.getType().getUnspecifiedType(), indirectionIndex, isGLValue)
642+
exists(int sub | if operand.isGLValue() then sub = 1 else sub = 0 |
643+
result = getTypeImpl(operand.getType().getUnspecifiedType(), indirectionIndex - sub)
670644
)
671645
}
672646

@@ -718,8 +692,8 @@ class IndirectInstruction extends Node, TIndirectInstruction {
718692
override Declaration getEnclosingCallable() { result = this.getFunction() }
719693

720694
override DataFlowType getType() {
721-
exists(boolean isGLValue | if instr.isGLValue() then isGLValue = true else isGLValue = false |
722-
result = getTypeImpl(instr.getResultType().getUnspecifiedType(), indirectionIndex, isGLValue)
695+
exists(int sub | if instr.isGLValue() then sub = 1 else sub = 0 |
696+
result = getTypeImpl(instr.getResultType().getUnspecifiedType(), indirectionIndex - sub)
723697
)
724698
}
725699

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
edges
2-
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... |
2+
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath |
33
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath |
44
nodes
55
| test.cpp:23:20:23:23 | argv | semmle.label | argv |
6-
| test.cpp:29:13:29:20 | (const char *)... | semmle.label | (const char *)... |
6+
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
77
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
88
subpaths
99
#select
10-
| test.cpp:29:13:29:20 | (const char *)... | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
10+
| test.cpp:29:13:29:20 | filePath | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
1111
| test.cpp:29:13:29:20 | filePath | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ void test_recv() {
233233
int send(int, const void*, int, int);
234234

235235
void test_send(char* buffer, int length) {
236-
send(0, buffer, length, 0); // $ MISSING: remote
236+
send(0, buffer, length, 0); // $ remote
237237
}
238238

239239
struct iovec {
@@ -257,5 +257,5 @@ int test_readv_and_writev(iovec* iovs) {
257257
sink(p); // $ MISSING: ast,ir
258258
sink(*p); // $ MISSING: ast,ir
259259

260-
writev(0, iovs, 16); // $ MISSING: remote
260+
writev(0, iovs, 16); // $ remote
261261
}

0 commit comments

Comments
 (0)