Skip to content

Commit 88ef6cf

Browse files
owen-mcCopilot
andcommitted
Test command injection through delegating launchers
Document supported simple forms and known limitations with inline expectations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 449d672 commit 88ef6cf

4 files changed

Lines changed: 240 additions & 50 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
| TaintedEnvironment.java:39:35:39:55 | new String[] | Command with a relative path 'ls' is executed. |
2-
| Test.java:50:46:50:49 | "ls" | Command with a relative path 'ls' is executed. |
2+
| Test.java:219:46:219:49 | "ls" | Command with a relative path 'ls' is executed. |
Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,48 @@
11
#select
2-
| Test.java:7:44:7:69 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:7:25:7:70 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
3-
| Test.java:10:29:10:74 | new String[] | Test.java:57:27:57:39 | args : String[] | Test.java:10:29:10:74 | new String[] | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
4-
| Test.java:18:29:18:31 | cmd | Test.java:57:27:57:39 | args : String[] | Test.java:18:29:18:31 | cmd | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
5-
| Test.java:24:29:24:32 | cmd1 | Test.java:57:27:57:39 | args : String[] | Test.java:24:29:24:32 | cmd1 | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
6-
| Test.java:29:44:29:64 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:29:25:29:65 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
2+
| Test.java:8:44:8:69 | ... + ... | Test.java:226:27:226:39 | args : String[] | Test.java:8:25:8:70 | new ..[] { .. } | This command line depends on a $@. | Test.java:226:27:226:39 | args | user-provided value |
3+
| Test.java:11:29:11:74 | new String[] | Test.java:226:27:226:39 | args : String[] | Test.java:11:29:11:74 | new String[] | This command line depends on a $@. | Test.java:226:27:226:39 | args | user-provided value |
4+
| Test.java:19:29:19:31 | cmd | Test.java:226:27:226:39 | args : String[] | Test.java:19:29:19:31 | cmd | This command line depends on a $@. | Test.java:226:27:226:39 | args | user-provided value |
5+
| Test.java:25:29:25:32 | cmd1 | Test.java:226:27:226:39 | args : String[] | Test.java:25:29:25:32 | cmd1 | This command line depends on a $@. | Test.java:226:27:226:39 | args | user-provided value |
6+
| Test.java:30:44:30:64 | ... + ... | Test.java:226:27:226:39 | args : String[] | Test.java:30:25:30:65 | new ..[] { .. } | This command line depends on a $@. | Test.java:226:27:226:39 | args | user-provided value |
77
edges
8-
| Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... : String | provenance | |
9-
| Test.java:6:35:6:44 | arg : String | Test.java:10:61:10:73 | ... + ... : String | provenance | |
10-
| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String | provenance | |
11-
| Test.java:6:35:6:44 | arg : String | Test.java:22:15:22:27 | ... + ... : String | provenance | |
12-
| Test.java:7:44:7:69 | ... + ... : String | Test.java:7:25:7:70 | new ..[] { .. } | provenance | Sink:MaD:2 |
13-
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | provenance | Sink:MaD:2 |
14-
| Test.java:10:61:10:73 | ... + ... : String | Test.java:10:29:10:74 | {...} : String[] [[]] : String | provenance | |
15-
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | provenance | Sink:MaD:1 |
16-
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:3 |
17-
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | provenance | Sink:MaD:2 |
18-
| Test.java:22:15:22:27 | ... + ... : String | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | provenance | |
19-
| Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... : String | provenance | |
20-
| Test.java:29:44:29:64 | ... + ... : String | Test.java:29:25:29:65 | new ..[] { .. } | provenance | Sink:MaD:2 |
21-
| Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String | provenance | |
22-
| Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String | provenance | |
23-
| Test.java:60:20:60:22 | arg : String | Test.java:6:35:6:44 | arg : String | provenance | |
24-
| Test.java:61:23:61:25 | arg : String | Test.java:28:38:28:47 | arg : String | provenance | |
8+
| Test.java:7:35:7:44 | arg : String | Test.java:8:44:8:69 | ... + ... : String | provenance | |
9+
| Test.java:7:35:7:44 | arg : String | Test.java:11:61:11:73 | ... + ... : String | provenance | |
10+
| Test.java:7:35:7:44 | arg : String | Test.java:17:13:17:25 | ... + ... : String | provenance | |
11+
| Test.java:7:35:7:44 | arg : String | Test.java:23:15:23:27 | ... + ... : String | provenance | |
12+
| Test.java:8:44:8:69 | ... + ... : String | Test.java:8:25:8:70 | new ..[] { .. } | provenance | Sink:MaD:2 |
13+
| Test.java:11:29:11:74 | {...} : String[] [[]] : String | Test.java:11:29:11:74 | new String[] | provenance | Sink:MaD:2 |
14+
| Test.java:11:61:11:73 | ... + ... : String | Test.java:11:29:11:74 | {...} : String[] [[]] : String | provenance | |
15+
| Test.java:17:5:17:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:19:29:19:31 | cmd | provenance | Sink:MaD:1 |
16+
| Test.java:17:13:17:25 | ... + ... : String | Test.java:17:5:17:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:3 |
17+
| Test.java:23:5:23:8 | cmd1 [post update] : String[] [[]] : String | Test.java:25:29:25:32 | cmd1 | provenance | Sink:MaD:2 |
18+
| Test.java:23:15:23:27 | ... + ... : String | Test.java:23:5:23:8 | cmd1 [post update] : String[] [[]] : String | provenance | |
19+
| Test.java:29:38:29:47 | arg : String | Test.java:30:44:30:64 | ... + ... : String | provenance | |
20+
| Test.java:30:44:30:64 | ... + ... : String | Test.java:30:25:30:65 | new ..[] { .. } | provenance | Sink:MaD:2 |
21+
| Test.java:226:27:226:39 | args : String[] | Test.java:229:20:229:22 | arg : String | provenance | |
22+
| Test.java:226:27:226:39 | args : String[] | Test.java:230:23:230:25 | arg : String | provenance | |
23+
| Test.java:229:20:229:22 | arg : String | Test.java:7:35:7:44 | arg : String | provenance | |
24+
| Test.java:230:23:230:25 | arg : String | Test.java:29:38:29:47 | arg : String | provenance | |
2525
models
2626
| 1 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (List); ; Argument[0]; command-injection; ai-manual |
2727
| 2 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (String[]); ; Argument[0]; command-injection; ai-manual |
2828
| 3 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual |
2929
nodes
30-
| Test.java:6:35:6:44 | arg : String | semmle.label | arg : String |
31-
| Test.java:7:25:7:70 | new ..[] { .. } | semmle.label | new ..[] { .. } |
32-
| Test.java:7:44:7:69 | ... + ... : String | semmle.label | ... + ... : String |
33-
| Test.java:10:29:10:74 | new String[] | semmle.label | new String[] |
34-
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | semmle.label | {...} : String[] [[]] : String |
35-
| Test.java:10:61:10:73 | ... + ... : String | semmle.label | ... + ... : String |
36-
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | semmle.label | cmd [post update] : ArrayList [<element>] : String |
37-
| Test.java:16:13:16:25 | ... + ... : String | semmle.label | ... + ... : String |
38-
| Test.java:18:29:18:31 | cmd | semmle.label | cmd |
39-
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | semmle.label | cmd1 [post update] : String[] [[]] : String |
40-
| Test.java:22:15:22:27 | ... + ... : String | semmle.label | ... + ... : String |
41-
| Test.java:24:29:24:32 | cmd1 | semmle.label | cmd1 |
42-
| Test.java:28:38:28:47 | arg : String | semmle.label | arg : String |
43-
| Test.java:29:25:29:65 | new ..[] { .. } | semmle.label | new ..[] { .. } |
44-
| Test.java:29:44:29:64 | ... + ... : String | semmle.label | ... + ... : String |
45-
| Test.java:57:27:57:39 | args : String[] | semmle.label | args : String[] |
46-
| Test.java:60:20:60:22 | arg : String | semmle.label | arg : String |
47-
| Test.java:61:23:61:25 | arg : String | semmle.label | arg : String |
30+
| Test.java:7:35:7:44 | arg : String | semmle.label | arg : String |
31+
| Test.java:8:25:8:70 | new ..[] { .. } | semmle.label | new ..[] { .. } |
32+
| Test.java:8:44:8:69 | ... + ... : String | semmle.label | ... + ... : String |
33+
| Test.java:11:29:11:74 | new String[] | semmle.label | new String[] |
34+
| Test.java:11:29:11:74 | {...} : String[] [[]] : String | semmle.label | {...} : String[] [[]] : String |
35+
| Test.java:11:61:11:73 | ... + ... : String | semmle.label | ... + ... : String |
36+
| Test.java:17:5:17:7 | cmd [post update] : ArrayList [<element>] : String | semmle.label | cmd [post update] : ArrayList [<element>] : String |
37+
| Test.java:17:13:17:25 | ... + ... : String | semmle.label | ... + ... : String |
38+
| Test.java:19:29:19:31 | cmd | semmle.label | cmd |
39+
| Test.java:23:5:23:8 | cmd1 [post update] : String[] [[]] : String | semmle.label | cmd1 [post update] : String[] [[]] : String |
40+
| Test.java:23:15:23:27 | ... + ... : String | semmle.label | ... + ... : String |
41+
| Test.java:25:29:25:32 | cmd1 | semmle.label | cmd1 |
42+
| Test.java:29:38:29:47 | arg : String | semmle.label | arg : String |
43+
| Test.java:30:25:30:65 | new ..[] { .. } | semmle.label | new ..[] { .. } |
44+
| Test.java:30:44:30:64 | ... + ... : String | semmle.label | ... + ... : String |
45+
| Test.java:226:27:226:39 | args : String[] | semmle.label | args : String[] |
46+
| Test.java:229:20:229:22 | arg : String | semmle.label | arg : String |
47+
| Test.java:230:23:230:25 | arg : String | semmle.label | arg : String |
4848
subpaths
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| Test.java:7:44:7:69 | ... + ... | Command line is built with string concatenation. |
2-
| Test.java:29:44:29:64 | ... + ... | Command line is built with string concatenation. |
1+
| Test.java:8:44:8:69 | ... + ... | Command line is built with string concatenation. |
2+
| Test.java:30:44:30:64 | ... + ... | Command line is built with string concatenation. |

‎java/ql/test/query-tests/security/CWE-078/Test.java‎

Lines changed: 197 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import java.lang.ProcessBuilder;
22
import java.util.List;
33
import java.util.ArrayList;
4+
import java.util.Arrays;
45

56
class Test {
67
public static void shellCommand(String arg) throws java.io.IOException {
@@ -28,22 +29,190 @@ public static void shellCommand(String arg) throws java.io.IOException {
2829
public static void nonShellCommand(String arg) throws java.io.IOException {
2930
ProcessBuilder pb = new ProcessBuilder("./customTool " + arg); // $ Alert[java/concatenated-command-line] Alert[java/command-line-injection]
3031
pb.start();
32+
}
3133

32-
pb = new ProcessBuilder(new String[]{"./customTool", arg});
33-
pb.start();
34+
public static void nonShellCommandLiteralArguments(String arg) throws java.io.IOException {
35+
new ProcessBuilder(new String[]{"./customTool", arg}).start(); // GOOD
36+
}
3437

38+
public static void nonShellCommandListArguments(String arg) throws java.io.IOException {
3539
List<String> cmd = new ArrayList<String>();
3640
cmd.add("./customTool");
3741
cmd.add(arg);
42+
new ProcessBuilder(cmd).start(); // GOOD
43+
}
3844

39-
pb = new ProcessBuilder(cmd);
40-
pb.start();
41-
45+
public static void nonShellCommandArrayArguments(String arg) throws java.io.IOException {
4246
String[] cmd1 = new String[]{"./customTool", "<arg>"};
4347
cmd1[1] = arg;
48+
new ProcessBuilder(cmd1).start(); // GOOD
49+
}
4450

45-
pb = new ProcessBuilder(cmd1);
46-
pb.start();
51+
public static void nonShellCommandWithIntermediateRead(String arg) throws java.io.IOException {
52+
List<String> readList = new ArrayList<String>();
53+
readList.add("./customTool");
54+
readList.size();
55+
readList.add(arg);
56+
new ProcessBuilder(readList).start(); // GOOD
57+
}
58+
59+
public static void nonShellCommandWithAddAll(String arg) throws java.io.IOException {
60+
List<String> addAllList = new ArrayList<String>();
61+
addAllList.add("./customTool");
62+
addAllList.addAll(Arrays.asList("-v"));
63+
addAllList.add(arg);
64+
new ProcessBuilder(addAllList).start(); // GOOD
65+
}
66+
67+
public static void delegatingLauncherLiterals(String arg) throws java.io.IOException {
68+
new ProcessBuilder(new String[]{"/usr/bin/env", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
69+
new ProcessBuilder(new String[]{"/usr/bin/sudo", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
70+
new ProcessBuilder(new String[]{"/usr/bin/xargs", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
71+
new ProcessBuilder(new String[]{"/usr/sbin/chroot", "/tmp/root", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
72+
new ProcessBuilder(new String[]{"/usr/bin/nice", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
73+
new ProcessBuilder(new String[]{"/usr/bin/nohup", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
74+
new ProcessBuilder(new String[]{"/usr/bin/setsid", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
75+
new ProcessBuilder(new String[]{"/usr/bin/stdbuf", "-oL", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
76+
new ProcessBuilder(new String[]{"/usr/bin/timeout", "10", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
77+
new ProcessBuilder(new String[]{"/usr/bin/env", "/bin/sh", "-c", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
78+
}
79+
80+
public static void fixedDelegatingLauncherLiteral(String arg) throws java.io.IOException {
81+
new ProcessBuilder(new String[]{"/usr/bin/env", "/bin/cp", arg, "/tmp/destination"}).start(); // GOOD
82+
}
83+
84+
public static void fixedDelegatingLauncherLiteralWithPrefix(String arg)
85+
throws java.io.IOException {
86+
new ProcessBuilder(new String[]{"/usr/bin/timeout", "10", "/bin/cp", arg, "/tmp/destination"}).start(); // GOOD
87+
}
88+
89+
public static void delegatingLauncherListAlerts(String arg, boolean condition)
90+
throws java.io.IOException {
91+
List<String> delegatedList = new ArrayList<String>();
92+
delegatedList.add("/usr/bin/env");
93+
delegatedList.add(arg);
94+
new ProcessBuilder(delegatedList).start(); // $ MISSING: Alert[java/command-line-injection]
95+
96+
List<String> branchingPosition = new ArrayList<String>();
97+
branchingPosition.add("/usr/bin/timeout");
98+
if (condition) {
99+
branchingPosition.add("10");
100+
}
101+
branchingPosition.add(arg);
102+
new ProcessBuilder(branchingPosition).start(); // $ MISSING: Alert[java/command-line-injection]
103+
104+
List<String> branchingLauncher = new ArrayList<String>();
105+
if (condition) {
106+
branchingLauncher.add("/usr/bin/env");
107+
} else {
108+
branchingLauncher.add("/usr/bin/timeout");
109+
}
110+
branchingLauncher.add("10");
111+
branchingLauncher.add(arg);
112+
new ProcessBuilder(branchingLauncher).start(); // $ MISSING: Alert[java/command-line-injection]
113+
}
114+
115+
public static void fixedDelegatingLauncherLaterListArgument(String arg)
116+
throws java.io.IOException {
117+
List<String> laterArgumentList = new ArrayList<String>();
118+
laterArgumentList.add("/usr/bin/timeout");
119+
laterArgumentList.add("10");
120+
laterArgumentList.add("/bin/cp");
121+
laterArgumentList.add(arg);
122+
laterArgumentList.add("/tmp/destination");
123+
new ProcessBuilder(laterArgumentList).start(); // GOOD
124+
}
125+
126+
public static void fixedDelegatingLauncherList(String arg) throws java.io.IOException {
127+
List<String> fixedList = new ArrayList<String>();
128+
fixedList.add("/usr/bin/env");
129+
fixedList.add("/bin/cp");
130+
fixedList.add(arg);
131+
fixedList.add("/tmp/destination");
132+
new ProcessBuilder(fixedList).start(); // GOOD
133+
}
134+
135+
public static void fixedDelegatingLauncherLoopList(String arg) throws java.io.IOException {
136+
List<String> loopList = new ArrayList<String>();
137+
loopList.add("/usr/bin/env");
138+
loopList.add("/bin/cp");
139+
for (String value : Arrays.asList(arg)) {
140+
loopList.add(value);
141+
}
142+
new ProcessBuilder(loopList).start(); // GOOD
143+
}
144+
145+
public static void delegatingLauncherArrayAlerts(String arg, boolean condition)
146+
throws java.io.IOException {
147+
String[] delegatedArray = new String[2];
148+
delegatedArray[0] = "/usr/bin/env";
149+
delegatedArray[1] = arg;
150+
new ProcessBuilder(delegatedArray).start(); // $ MISSING: Alert[java/command-line-injection]
151+
152+
String launcher;
153+
if (condition) {
154+
launcher = "/usr/bin/env";
155+
} else {
156+
launcher = "/usr/bin/timeout";
157+
}
158+
new ProcessBuilder(new String[]{launcher, "10", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
159+
}
160+
161+
public static void fixedDelegatingLauncherArray(String arg) throws java.io.IOException {
162+
String[] fixedArray = new String[]{"/usr/bin/env", "/bin/cp", "<arg>", "/tmp/destination"};
163+
fixedArray[2] = arg;
164+
new ProcessBuilder(fixedArray).start(); // GOOD
165+
}
166+
167+
public static void changedDelegatedCommand(String arg) throws java.io.IOException {
168+
String[] command = new String[]{"/usr/bin/env", "/bin/cp", "-c", arg};
169+
command[1] = "/bin/sh";
170+
new ProcessBuilder(command).start(); // $ MISSING: Alert[java/command-line-injection]
171+
172+
String[] copiedInline =
173+
Arrays.copyOf(new String[]{"/usr/bin/env", "/bin/cp", "-c", arg}, 4);
174+
copiedInline[1] = "/bin/sh";
175+
new ProcessBuilder(copiedInline).start(); // $ MISSING: Alert[java/command-line-injection]
176+
177+
String[] base = new String[]{"/usr/bin/env", "/bin/cp", "-c", arg};
178+
String[] copiedStored = Arrays.copyOf(base, 4);
179+
copiedStored[1] = "/bin/sh";
180+
new ProcessBuilder(copiedStored).start(); // $ MISSING: Alert[java/command-line-injection]
181+
}
182+
183+
public static String[] returnedNonShellCommand(String arg) {
184+
return new String[]{"./customTool", arg};
185+
}
186+
187+
public static void nestedNonShellCommand(String arg) throws java.io.IOException {
188+
new ProcessBuilder(
189+
arg.isEmpty()
190+
? new String[]{"./customTool", arg}
191+
: new String[]{"./otherCustomTool", arg})
192+
.start(); // GOOD
193+
}
194+
195+
public static void useReturnedNonShellCommand(String arg) throws java.io.IOException {
196+
new ProcessBuilder(returnedNonShellCommand(arg)).start(); // GOOD
197+
}
198+
199+
public static void unknownDelegatedCommand(String arg, String command) throws java.io.IOException {
200+
new ProcessBuilder(new String[]{"/usr/bin/env", command, "-c", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
201+
}
202+
203+
public static void unsupportedEnvAssignment(String arg) throws java.io.IOException {
204+
new ProcessBuilder(new String[]{"/usr/bin/env", "LANG=C", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
205+
}
206+
207+
public static void unsupportedSudoOption(String arg) throws java.io.IOException {
208+
new ProcessBuilder(new String[]{"/usr/bin/sudo", "-u", "nobody", arg}).start(); // $ MISSING: Alert[java/command-line-injection]
209+
}
210+
211+
public static void changedDelegatedCommandThroughAlias(String arg) throws java.io.IOException {
212+
String[] command = new String[]{"/usr/bin/env", "/bin/cp", "-c", arg};
213+
String[] alias = command;
214+
alias[1] = "/bin/sh";
215+
new ProcessBuilder(command).start(); // $ MISSING: Alert[java/command-line-injection]
47216
}
48217

49218
public static void relativeCommand() throws java.io.IOException {
@@ -59,6 +228,27 @@ public static void main(String[] args) throws java.io.IOException { // $ Source[
59228

60229
shellCommand(arg);
61230
nonShellCommand(arg);
231+
nonShellCommandLiteralArguments(arg);
232+
nonShellCommandListArguments(arg);
233+
nonShellCommandArrayArguments(arg);
234+
nonShellCommandWithIntermediateRead(arg);
235+
nonShellCommandWithAddAll(arg);
236+
delegatingLauncherLiterals(arg);
237+
fixedDelegatingLauncherLiteral(arg);
238+
fixedDelegatingLauncherLiteralWithPrefix(arg);
239+
delegatingLauncherListAlerts(arg, args.length > 2);
240+
fixedDelegatingLauncherLaterListArgument(arg);
241+
fixedDelegatingLauncherList(arg);
242+
fixedDelegatingLauncherLoopList(arg);
243+
delegatingLauncherArrayAlerts(arg, args.length > 2);
244+
fixedDelegatingLauncherArray(arg);
245+
changedDelegatedCommand(arg);
246+
nestedNonShellCommand(arg);
247+
useReturnedNonShellCommand(arg);
248+
unknownDelegatedCommand(arg, "/bin/sh");
249+
unsupportedEnvAssignment(arg);
250+
unsupportedSudoOption(arg);
251+
changedDelegatedCommandThroughAlias(arg);
62252
relativeCommand();
63253
}
64254
}

0 commit comments

Comments
 (0)