@@ -13,66 +13,10 @@ import semmle.code.java.Collections
1313 * i.e. it's not in a position that selects a command to execute.
1414 */
1515predicate isSafeCommandArgument ( Expr ex ) {
16- exists ( ArrayInit ai , int i |
17- ex = ai .getInit ( i ) and
16+ exists ( CommandArguments arguments , int i |
1817 i > 0 and
19- not isShell ( ai .getInit ( 0 ) ) and
20- (
21- not exists ( delegatedCommandIndex ( ai .getInit ( 0 ) ) )
22- or
23- exists ( int commandIndex |
24- commandIndex = delegatedCommandIndex ( ai .getInit ( 0 ) ) and
25- (
26- i < commandIndex
27- or
28- i > commandIndex and
29- not isShell ( ai .getInit ( commandIndex ) ) and
30- not exists ( delegatedCommandIndex ( ai .getInit ( commandIndex ) ) )
31- )
32- )
33- )
34- )
35- or
36- exists ( CommandArgumentList cal , int i |
37- not cal .isShell ( ) and
38- i > 0 and
39- ex = cal .getArgument ( i ) and
40- (
41- not exists ( delegatedCommandIndex ( cal .getArgument ( 0 ) ) )
42- or
43- exists ( int commandIndex |
44- commandIndex = delegatedCommandIndex ( cal .getArgument ( 0 ) ) and
45- (
46- i < commandIndex
47- or
48- i > commandIndex and
49- exists ( cal .getArgument ( commandIndex ) ) and
50- not isShell ( cal .getArgument ( commandIndex ) ) and
51- not exists ( delegatedCommandIndex ( cal .getArgument ( commandIndex ) ) )
52- )
53- )
54- )
55- )
56- or
57- exists ( CommandArgArrayImmutableFirst caa , int i |
58- not caa .isShell ( ) and
59- i > 0 and
60- ex = caa .getAWrite ( i ) and
61- (
62- not exists ( delegatedCommandIndex ( caa .getFirstElement ( ) ) )
63- or
64- exists ( int commandIndex |
65- commandIndex = delegatedCommandIndex ( caa .getFirstElement ( ) ) and
66- (
67- i < commandIndex
68- or
69- i > commandIndex and
70- exists ( caa .getAnElement ( commandIndex ) ) and
71- not isShell ( caa .getAnElement ( commandIndex ) ) and
72- not exists ( delegatedCommandIndex ( caa .getAnElement ( commandIndex ) ) )
73- )
74- )
75- )
18+ ex = arguments .getArgumentUse ( i ) and
19+ arguments .hasSafeArgument ( i )
7620 )
7721}
7822
@@ -116,6 +60,66 @@ private int delegatedCommandIndex(Expr ex) {
11660 )
11761}
11862
63+ private newtype TCommandArguments =
64+ TLiteralArguments ( ArrayInit init ) or
65+ TListArguments ( CommandArgumentList list ) or
66+ TMutableArguments ( CommandArgArrayImmutableFirst array )
67+
68+ /** An ordered sequence of command arguments. */
69+ private class CommandArguments extends TCommandArguments {
70+ string toString ( ) { result = this .getArgument ( 0 ) .toString ( ) }
71+
72+ /** Gets a possible value at the given index. */
73+ private Expr getArgument ( int index ) {
74+ exists ( ArrayInit init | this = TLiteralArguments ( init ) | result = init .getInit ( index ) )
75+ or
76+ exists ( CommandArgumentList list |
77+ this = TListArguments ( list ) and
78+ result = list .getArgument ( index )
79+ )
80+ or
81+ exists ( CommandArgArrayImmutableFirst array |
82+ this = TMutableArguments ( array ) and
83+ result = array .getAnElement ( index )
84+ )
85+ }
86+
87+ /** Gets an expression whose value is stored at the given index. */
88+ Expr getArgumentUse ( int index ) {
89+ exists ( ArrayInit init | this = TLiteralArguments ( init ) | result = init .getInit ( index ) )
90+ or
91+ exists ( CommandArgumentList list |
92+ this = TListArguments ( list ) and
93+ result = list .getArgument ( index )
94+ )
95+ or
96+ exists ( CommandArgArrayImmutableFirst array |
97+ this = TMutableArguments ( array ) and
98+ result = array .getAWrite ( index )
99+ )
100+ }
101+
102+ predicate hasSafeArgument ( int index ) {
103+ exists ( this .getArgumentUse ( index ) ) and
104+ not isShell ( this .getArgument ( 0 ) ) and
105+ (
106+ not exists ( delegatedCommandIndex ( this .getArgument ( 0 ) ) )
107+ or
108+ exists ( int commandIndex |
109+ commandIndex = delegatedCommandIndex ( this .getArgument ( 0 ) ) and
110+ (
111+ index < commandIndex
112+ or
113+ index > commandIndex and
114+ exists ( this .getArgument ( commandIndex ) ) and
115+ not isShell ( this .getArgument ( commandIndex ) ) and
116+ not exists ( delegatedCommandIndex ( this .getArgument ( commandIndex ) ) )
117+ )
118+ )
119+ )
120+ }
121+ }
122+
119123/**
120124 * A type that could be a list of strings. Includes raw `List` types.
121125 */
@@ -184,9 +188,6 @@ private class CommandArgumentList extends SsaExplicitWrite {
184188
185189 /** Gets the argument added at the given index. */
186190 Expr getArgument ( int index ) { result = this .getAnAddAtIndex ( index ) .getArgument ( 0 ) }
187-
188- /** Holds if the first element of this list is a shell command. */
189- predicate isShell ( ) { isShell ( this .getArgument ( 0 ) ) }
190191}
191192
192193/**
@@ -252,9 +253,6 @@ private class CommandArgArrayImmutableFirst extends CommandArgumentArray {
252253 result = arrayElementOf ( this .getDefiningExpr ( ) , index )
253254 )
254255 }
255-
256- /** Holds if the first element of this array is a shell command. */
257- predicate isShell ( ) { isShell ( this .getFirstElement ( ) ) }
258256}
259257
260258/** Gets an element of an immutable array of strings. */
0 commit comments