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

Skip to content

Commit 4c27c37

Browse files
committed
C++: Respond to more review comments.
1 parent 44e38ab commit 4c27c37

1 file changed

Lines changed: 44 additions & 114 deletions

File tree

cpp/ql/src/Likely Bugs/OO/UnsafeUseOfThis.ql

Lines changed: 44 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ predicate parameterOf(Parameter p, Function f, int n) {
2525

2626
/**
2727
* Holds if `instr` is the `n`'th argument to a call to the non-virtual function `f`, and
28-
* `init` is the corresponding initiazation instruction that receives the value of
29-
* `instr` in `f`.
28+
* `init` is the corresponding initiazation instruction that receives the value of `instr` in `f`.
3029
*/
3130
predicate flowIntoParameter(
3231
CallInstruction call, Instruction instr, Function f, int n, InitializeParameterInstruction init
@@ -39,9 +38,8 @@ predicate flowIntoParameter(
3938
}
4039

4140
/**
42-
* Holds if `instr` is an argument to a call to the function `f`, and
43-
* `init` is the corresponding initiazation instruction that receives the value of
44-
* `instr` in `f`.
41+
* Holds if `instr` is an argument to a call to the function `f`, and `init` is the
42+
* corresponding initialization instruction that receives the value of `instr` in `f`.
4543
*/
4644
pragma[noinline]
4745
predicate getPositionalArgumentInitParam(
@@ -96,42 +94,32 @@ predicate isSource(InitializeParameterInstruction init, string msg, Class c) {
9694
init.getEnclosingFunction().getDeclaringType() = c
9795
}
9896

99-
/**
100-
* Holds if `instr` flows to the sink instruction `sink` that is a `this`
101-
* pointer of type `sinkClass`
102-
*/
103-
predicate flowsToSink(Instruction instr, Instruction sink, Class sinkClass) {
104-
instr = sink and
105-
isSink(sink, _, sinkClass)
97+
/** Holds if `instr` flows to a sink. */
98+
predicate flowsToSink(Instruction instr) {
99+
isSink(instr, _, _)
106100
or
107101
exists(Instruction mid |
108-
successor(instr, mid, sinkClass) and
109-
flowsToSink(mid, sink, sinkClass)
102+
successor(instr, mid) and
103+
flowsToSink(mid)
110104
)
111105
}
112106

113-
/**
114-
* Holds if `source` is an initialization of a `this` pointer of type `sourceClass`, and
115-
* `source` flows to instruction `instr`.
116-
*/
117-
predicate flowsFromSource(Instruction source, Instruction instr, Class sourceClass) {
118-
source = instr and
119-
isSource(source, _, sourceClass)
107+
/** Holds if `instr` flows from a source. */
108+
predicate flowsFromSource(Instruction instr) {
109+
isSource(instr, _, _)
120110
or
121111
exists(Instruction mid |
122-
successorFwd(mid, instr, sourceClass) and
123-
flowsFromSource(source, mid, sourceClass)
112+
successor(mid, instr) and
113+
flowsFromSource(mid)
124114
)
125115
}
126116

127117
/**
128-
* Holds if
129-
* - `instr` is an argument (or argument indirection) to a call, and
130-
* - `succ` is the corresponding initialization instruction in the call target, and
131-
* - `succ` eventually flows to an instruction that is used as a `this` pointer of type `sinkClass`.
118+
* Holds if `instr` is an argument (or argument indirection) to a call, and
119+
* `succ` is the corresponding initialization instruction in the call target.
132120
*/
133-
predicate flowThroughCallable(Instruction instr, Instruction succ, Class sinkClass) {
134-
flowsToSink(succ, _, sinkClass) and
121+
predicate flowThroughCallable(Instruction instr, Instruction succ) {
122+
flowsToSink(succ) and
135123
(
136124
// Flow from an argument to a parameter
137125
exists(CallInstruction call, InitializeParameterInstruction init | init = succ |
@@ -160,115 +148,57 @@ predicate flowThroughCallable(Instruction instr, Instruction succ, Class sinkCla
160148
)
161149
}
162150

163-
/**
164-
* Holds if `instr` flows to `succ` and `succ` eventually flows to an instruction that is used
165-
* as a `this` pointer of type `sinkClass`.
166-
*/
167-
predicate successor(Instruction instr, Instruction succ, Class sinkClass) {
168-
flowsToSink(succ, _, sinkClass) and
151+
/** Holds if `instr` flows to `succ`. */
152+
predicate successor(Instruction instr, Instruction succ) {
153+
flowsToSink(succ) and
169154
(
170155
irBbPostDominates(succ.getBlock(), instr.getBlock()) and
171156
(
172-
(
173-
succ.(CopyInstruction).getSourceValue() = instr or
174-
succ.(CheckedConvertOrNullInstruction).getUnary() = instr or
175-
succ.(ChiInstruction).getTotal() = instr or
176-
succ.(ConvertInstruction).getUnary() = instr
177-
)
178-
or
157+
succ.(CopyInstruction).getSourceValue() = instr or
158+
succ.(CheckedConvertOrNullInstruction).getUnary() = instr or
159+
succ.(ChiInstruction).getTotal() = instr or
160+
succ.(ConvertInstruction).getUnary() = instr or
179161
succ.(InheritanceConversionInstruction).getUnary() = instr
180162
)
181163
or
182-
flowThroughCallable(instr, succ, sinkClass)
164+
flowThroughCallable(instr, succ)
183165
)
184166
}
185167

186-
/**
187-
* Holds if
188-
* - `instr` is an argument (or argument indirection) to a call, and
189-
* - `succ` is the corresponding initialization instruction in the call target, and
190-
* - there exists an initialization of a `this` pointer of type `sourceClass` that flows to `instr`.
191-
*/
192-
predicate flowThroughCallableFwd(Instruction instr, Instruction succ, Class sourceClass) {
193-
flowsFromSource(_, instr, sourceClass) and
194-
(
195-
// Flow from an argument to a parameter
196-
exists(CallInstruction call, InitializeParameterInstruction init | init = succ |
197-
getPositionalArgumentInitParam(call, instr, init, call.getStaticCallTarget())
198-
or
199-
getThisArgumentInitParam(call, instr, init, call.getStaticCallTarget())
200-
)
201-
or
202-
// Flow from argument indirection to parameter indirection
203-
exists(
204-
CallInstruction call, ReadSideEffectInstruction read, InitializeIndirectionInstruction init
205-
|
206-
init = succ and
207-
init.getEnclosingFunction() = call.getStaticCallTarget() and
208-
read.getPrimaryInstruction() = call and
209-
read.getSideEffectOperand().getAnyDef() = instr
210-
|
211-
exists(int n |
212-
read.getIndex() = n and
213-
init.getParameter().getIndex() = unbind(n)
214-
)
215-
or
216-
call.getThisArgument() = instr and
217-
init.getIRVariable() instanceof IRThisVariable
218-
)
219-
)
220-
}
221-
222-
/**
223-
* Holds if there exists an initialization of a `this` pointer of type `sourceClass` that flows
224-
* to `instr`, and `instr` flows to `succ` and `succ`.
225-
*/
226-
predicate successorFwd(Instruction instr, Instruction succ, Class sourceClass) {
227-
flowsFromSource(_, instr, sourceClass) and
228-
(
229-
irBbPostDominates(succ.getBlock(), instr.getBlock()) and
230-
(
231-
(
232-
succ.(CopyInstruction).getSourceValue() = instr or
233-
succ.(CheckedConvertOrNullInstruction).getUnary() = instr or
234-
succ.(ChiInstruction).getTotal() = instr or
235-
succ.(ConvertInstruction).getUnary() = instr
236-
)
237-
or
238-
succ.(InheritanceConversionInstruction).getUnary() = instr
239-
)
240-
or
241-
flowThroughCallableFwd(instr, succ, sourceClass)
242-
)
243-
}
168+
predicate successorTC(Instruction i1, Instruction i2) = fastTC(successor/2)(i1, i2)
244169

245170
/**
246-
* Holds if `instr` is in the path from an initialization of a `this` pointer in a subclass, to a use
247-
* of the `this` pointer in a baseclass.
171+
* Holds if:
172+
* - `source` is an initialization of a `this` pointer of type `sourceClass`, and
173+
* - `sink` is a use of the `this` pointer as type `sinkClass`, and
174+
* - `call` invokes a pure virtual function using `sink` as the `this` pointer, and
175+
* - `msg` is a string describing whether `source` is from a constructor or destructor.
248176
*/
249-
predicate isInPath(Instruction instr) {
250-
exists(Class sourceClass, Class sinkClass |
251-
flowsFromSource(_, instr, sourceClass) and
252-
flowsToSink(instr, _, sinkClass) and
253-
sourceClass.getABaseClass+() = sinkClass
254-
)
177+
predicate flows(
178+
Instruction source, string msg, Class sourceClass, Instruction sink, CallInstruction call,
179+
Class sinkClass
180+
) {
181+
isSource(source, msg, sourceClass) and
182+
successorTC(source, sink) and
183+
isSink(sink, call, sinkClass)
255184
}
256185

257186
query predicate edges(Instruction a, Instruction b) {
258-
successor(a, b, _) and isInPath(a) and isInPath(b)
187+
successor(a, b) and flowsFromSource(a) and flowsFromSource(b)
259188
}
260189

261190
query predicate nodes(Instruction n, string key, string val) {
262-
isInPath(n) and key = "semmle.label" and val = n.toString()
191+
flowsFromSource(n) and
192+
flowsToSink(n) and
193+
key = "semmle.label" and
194+
val = n.toString()
263195
}
264196

265197
from
266198
Instruction source, Instruction sink, CallInstruction call, string msg, Class sourceClass,
267199
Class sinkClass
268200
where
269-
isSource(source, msg, sourceClass) and
270-
flowsToSink(source, sink, sinkClass) and
271-
isSink(sink, call, sinkClass) and
201+
flows(source, msg, sourceClass, sink, call, sinkClass) and
272202
sourceClass.getABaseClass+() = sinkClass
273203
select call.getUnconvertedResultExpression(), source, sink,
274204
"Call to pure virtual function during " + msg

0 commit comments

Comments
 (0)