Skip to content

Commit 2ea71f5

Browse files
committed
Python: Make "..Call" modeling classes extend DataFlow::CfgNode
1 parent 2e30f58 commit 2ea71f5

File tree

1 file changed

+46
-47
lines changed
  • python/ql/src/experimental/semmle/python/frameworks

1 file changed

+46
-47
lines changed

python/ql/src/experimental/semmle/python/frameworks/Stdlib.qll

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ private module Stdlib {
102102
* A call to `os.system`.
103103
* See https://docs.python.org/3/library/os.html#os.system
104104
*/
105-
private class OsSystemCall extends SystemCommandExecution::Range {
106-
OsSystemCall() { this.asCfgNode().(CallNode).getFunction() = os_attr("system").asCfgNode() }
105+
private class OsSystemCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
106+
override CallNode node;
107107

108-
override DataFlow::Node getCommand() {
109-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
110-
}
108+
OsSystemCall() { node.getFunction() = os_attr("system").asCfgNode() }
109+
110+
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
111111
}
112112

113113
/**
@@ -118,70 +118,68 @@ private module Stdlib {
118118
* Although deprecated since version 2.6, they still work in 2.7.
119119
* See https://docs.python.org/2.7/library/os.html#os.popen2
120120
*/
121-
private class OsPopenCall extends SystemCommandExecution::Range {
121+
private class OsPopenCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
122+
override CallNode node;
122123
string name;
123124

124125
OsPopenCall() {
125126
name in ["popen", "popen2", "popen3", "popen4"] and
126-
this.asCfgNode().(CallNode).getFunction() = os_attr(name).asCfgNode()
127+
node.getFunction() = os_attr(name).asCfgNode()
127128
}
128129

129130
override DataFlow::Node getCommand() {
130-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
131+
result.asCfgNode() = node.getArg(0)
131132
or
132133
not name = "popen" and
133-
result.asCfgNode() = this.asCfgNode().(CallNode).getArgByName("cmd")
134+
result.asCfgNode() = node.getArgByName("cmd")
134135
}
135136
}
136137

137138
/**
138139
* A call to any of the `os.exec*` functions
139140
* See https://docs.python.org/3.8/library/os.html#os.execl
140141
*/
141-
private class OsExecCall extends SystemCommandExecution::Range {
142+
private class OsExecCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
143+
override CallNode node;
144+
142145
OsExecCall() {
143146
exists(string name |
144147
name in ["execl", "execle", "execlp", "execlpe", "execv", "execve", "execvp", "execvpe"] and
145-
this.asCfgNode().(CallNode).getFunction() = os_attr(name).asCfgNode()
148+
node.getFunction() = os_attr(name).asCfgNode()
146149
)
147150
}
148151

149-
override DataFlow::Node getCommand() {
150-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
151-
}
152+
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
152153
}
153154

154155
/**
155156
* A call to any of the `os.spawn*` functions
156157
* See https://docs.python.org/3.8/library/os.html#os.spawnl
157158
*/
158-
private class OsSpawnCall extends SystemCommandExecution::Range {
159+
private class OsSpawnCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
160+
override CallNode node;
161+
159162
OsSpawnCall() {
160163
exists(string name |
161164
name in ["spawnl", "spawnle", "spawnlp", "spawnlpe", "spawnv", "spawnve", "spawnvp",
162165
"spawnvpe"] and
163-
this.asCfgNode().(CallNode).getFunction() = os_attr(name).asCfgNode()
166+
node.getFunction() = os_attr(name).asCfgNode()
164167
)
165168
}
166169

167-
override DataFlow::Node getCommand() {
168-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(1)
169-
}
170+
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(1) }
170171
}
171172

172173
/**
173174
* A call to any of the `os.posix_spawn*` functions
174175
* See https://docs.python.org/3.8/library/os.html#os.posix_spawn
175176
*/
176-
private class OsPosixSpawnCall extends SystemCommandExecution::Range {
177-
OsPosixSpawnCall() {
178-
this.asCfgNode().(CallNode).getFunction() =
179-
os_attr(["posix_spawn", "posix_spawnp"]).asCfgNode()
180-
}
177+
private class OsPosixSpawnCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
178+
override CallNode node;
181179

182-
override DataFlow::Node getCommand() {
183-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
184-
}
180+
OsPosixSpawnCall() { node.getFunction() = os_attr(["posix_spawn", "posix_spawnp"]).asCfgNode() }
181+
182+
override DataFlow::Node getCommand() { result.asCfgNode() = node.getArg(0) }
185183
}
186184

187185
/** An additional taint step for calls to `os.path.join` */
@@ -257,29 +255,28 @@ private module Stdlib {
257255
* A call to `subprocess.Popen` or helper functions (call, check_call, check_output, run)
258256
* See https://docs.python.org/3.8/library/subprocess.html#subprocess.Popen
259257
*/
260-
private class SubprocessPopenCall extends SystemCommandExecution::Range {
261-
CallNode call;
258+
private class SubprocessPopenCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
259+
override CallNode node;
262260

263261
SubprocessPopenCall() {
264-
call = this.asCfgNode() and
265262
exists(string name |
266263
name in ["Popen", "call", "check_call", "check_output", "run"] and
267-
call.getFunction() = subprocess_attr(name).asCfgNode()
264+
node.getFunction() = subprocess_attr(name).asCfgNode()
268265
)
269266
}
270267

271268
/** Gets the ControlFlowNode for the `args` argument, if any. */
272269
private ControlFlowNode get_args_arg() {
273-
result = call.getArg(0)
270+
result = node.getArg(0)
274271
or
275-
result = call.getArgByName("args")
272+
result = node.getArgByName("args")
276273
}
277274

278275
/** Gets the ControlFlowNode for the `shell` argument, if any. */
279276
private ControlFlowNode get_shell_arg() {
280-
result = call.getArg(8)
277+
result = node.getArg(8)
281278
or
282-
result = call.getArgByName("shell")
279+
result = node.getArgByName("shell")
283280
}
284281

285282
private boolean get_shell_arg_value() {
@@ -301,9 +298,9 @@ private module Stdlib {
301298

302299
/** Gets the ControlFlowNode for the `executable` argument, if any. */
303300
private ControlFlowNode get_executable_arg() {
304-
result = call.getArg(2)
301+
result = node.getArg(2)
305302
or
306-
result = call.getArgByName("executable")
303+
result = node.getArgByName("executable")
307304
}
308305

309306
override DataFlow::Node getCommand() {
@@ -399,18 +396,20 @@ private module Stdlib {
399396
* A call to any of the `popen.popen*` functions, or instantiation of a `popen.Popen*` class.
400397
* See https://docs.python.org/2.7/library/popen2.html
401398
*/
402-
private class Popen2PopenCall extends SystemCommandExecution::Range {
399+
private class Popen2PopenCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
400+
override CallNode node;
401+
403402
Popen2PopenCall() {
404403
exists(string name |
405404
name in ["popen2", "popen3", "popen4", "Popen3", "Popen4"] and
406-
this.asCfgNode().(CallNode).getFunction() = popen2_attr(name).asCfgNode()
405+
node.getFunction() = popen2_attr(name).asCfgNode()
407406
)
408407
}
409408

410409
override DataFlow::Node getCommand() {
411-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
410+
result.asCfgNode() = node.getArg(0)
412411
or
413-
result.asCfgNode() = this.asCfgNode().(CallNode).getArgByName("cmd")
412+
result.asCfgNode() = node.getArgByName("cmd")
414413
}
415414
}
416415

@@ -471,15 +470,15 @@ private module Stdlib {
471470
* A call to the `platform.popen` function.
472471
* See https://docs.python.org/2.7/library/platform.html#platform.popen
473472
*/
474-
private class PlatformPopenCall extends SystemCommandExecution::Range {
475-
PlatformPopenCall() {
476-
this.asCfgNode().(CallNode).getFunction() = platform_attr("popen").asCfgNode()
477-
}
473+
private class PlatformPopenCall extends SystemCommandExecution::Range, DataFlow::CfgNode {
474+
override CallNode node;
475+
476+
PlatformPopenCall() { node.getFunction() = platform_attr("popen").asCfgNode() }
478477

479478
override DataFlow::Node getCommand() {
480-
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
479+
result.asCfgNode() = node.getArg(0)
481480
or
482-
result.asCfgNode() = this.asCfgNode().(CallNode).getArgByName("cmd")
481+
result.asCfgNode() = node.getArgByName("cmd")
483482
}
484483
}
485484
}

0 commit comments

Comments
 (0)