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

Skip to content

Commit 46b9ef7

Browse files
committed
Python points-to: Fix up neverReturns() and return value of __import__().
1 parent 62e0518 commit 46b9ef7

4 files changed

Lines changed: 37 additions & 4 deletions

File tree

python/ql/src/semmle/python/objects/Callables.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ abstract class CallableObjectInternal extends ObjectInternal {
5252

5353
override int length() { none() }
5454

55+
abstract predicate neverReturns();
5556
}
5657

5758

@@ -146,6 +147,10 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
146147
result.getNode() = this.getScope().getArgByName(name)
147148
}
148149

150+
151+
override predicate neverReturns() {
152+
InterProceduralPointsTo::neverReturns(this.getScope())
153+
}
149154
}
150155

151156

@@ -220,9 +225,11 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
220225
or
221226
func = Builtin::builtin("intern") and result = Builtin::special("str")
222227
or
228+
func = Builtin::builtin("__import__") and result = Builtin::special("ModuleType")
229+
or
223230
/* Fix a few minor inaccuracies in the CPython analysis */
224231
ext_rettype(func, result) and not (
225-
func = Builtin::builtin("__import__") and result = Builtin::special("NoneType")
232+
func = Builtin::builtin("__import__")
226233
or
227234
func = Builtin::builtin("compile") and result = Builtin::special("NoneType")
228235
or
@@ -251,6 +258,10 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
251258
none()
252259
}
253260

261+
override predicate neverReturns() {
262+
this = Module::named("sys").attr("exit")
263+
}
264+
254265
}
255266

256267

@@ -334,6 +345,8 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
334345
none()
335346
}
336347

348+
override predicate neverReturns() { none() }
349+
337350
}
338351

339352
class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
@@ -405,6 +418,10 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
405418
result = this.getFunction().getParameterByName(name)
406419
}
407420

421+
override predicate neverReturns() {
422+
this.getFunction().neverReturns()
423+
}
424+
408425
}
409426

410427

python/ql/src/semmle/python/objects/ObjectAPI.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ class CallableValue extends Value {
103103
}
104104

105105
predicate neverReturns() {
106-
// TO DO..
107-
none()
106+
this.(CallableObjectInternal).neverReturns()
108107
}
109108

110109
Function getScope() {

python/ql/src/semmle/python/pointsto/PointsTo.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,23 @@ module InterProceduralPointsTo {
10221022
BaseFlow::reaches_exit(evar)
10231023
}
10241024

1025+
/** INTERNAL -- Use `FunctionObject.neverReturns()` instead.
1026+
* Whether function `func` never returns. Slightly conservative approximation, this predicate may be false
1027+
* for a function that can never return. */
1028+
cached predicate neverReturns(Function f) {
1029+
/* A Python function never returns if it has no normal exits that are not dominated by a
1030+
* call to a function which itself never returns.
1031+
*/
1032+
forall(BasicBlock exit |
1033+
exit = f.getANormalExit().getBasicBlock() |
1034+
exists(FunctionObject callee, BasicBlock call |
1035+
callee.getACall().getBasicBlock() = call and
1036+
callee.neverReturns() and
1037+
call.dominates(exit)
1038+
)
1039+
)
1040+
}
1041+
10251042
}
10261043

10271044
/** Gets the `value, origin` that `f` would refer to if it has not been assigned some other value */

python/ql/src/semmle/python/security/TaintTracking.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ library module TaintFlowImplementation {
12681268
|
12691269
test.getSense() = true and not exists(kind.getClass())
12701270
or
1271-
test.getSense() = true and kind.getClass().getASuperType() = cls
1271+
test.getSense() = true and kind.getType().getASuperType() = cls
12721272
or
12731273
test.getSense() = false and not kind.getType().getASuperType() = cls
12741274
)

0 commit comments

Comments
 (0)