@@ -8,9 +8,8 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
8
8
SideEffectFunction {
9
9
PureStrFunction ( ) {
10
10
hasGlobalOrStdName ( [
11
- "atof" , "atoi" , "atol" , "atoll" , "strcasestr" , "strchnul" , "strchr" , "strchrnul" , "strstr" ,
12
- "strpbrk" , "strcmp" , "strcspn" , "strncmp" , "strrchr" , "strspn" , "strtod" , "strtof" ,
13
- "strtol" , "strtoll" , "strtoq" , "strtoul"
11
+ atoi ( ) , "strcasestr" , "strchnul" , "strchr" , "strchrnul" , "strstr" , "strpbrk" , "strrchr" ,
12
+ "strspn" , strtol ( ) , strrev ( ) , strcmp ( ) , strlwr ( ) , strupr ( )
14
13
] )
15
14
}
16
15
@@ -24,11 +23,16 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
24
23
25
24
override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
26
25
exists ( ParameterIndex i |
27
- input .isParameter ( i ) and
28
- exists ( getParameter ( i ) )
29
- or
30
- input .isParameterDeref ( i ) and
31
- getParameter ( i ) .getUnspecifiedType ( ) instanceof PointerType
26
+ (
27
+ input .isParameter ( i ) and
28
+ exists ( getParameter ( i ) )
29
+ or
30
+ input .isParameterDeref ( i ) and
31
+ getParameter ( i ) .getUnspecifiedType ( ) instanceof PointerType
32
+ ) and
33
+ // Functions that end with _l also take a locale argument (always as the last argument),
34
+ // and we don't want taint from those arguments.
35
+ ( not this .getName ( ) .matches ( "%\\_l" ) or exists ( getParameter ( i + 1 ) ) )
32
36
) and
33
37
(
34
38
output .isReturnValueDeref ( ) and
@@ -60,6 +64,31 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
60
64
}
61
65
}
62
66
67
+ private string atoi ( ) { result = [ "atof" , "atoi" , "atol" , "atoll" ] }
68
+
69
+ private string strtol ( ) { result = [ "strtod" , "strtof" , "strtol" , "strtoll" , "strtoq" , "strtoul" ] }
70
+
71
+ private string strlwr ( ) {
72
+ result = [ "_strlwr" , "_wcslwr" , "_mbslwr" , "_strlwr_l" , "_wcslwr_l" , "_mbslwr_l" ]
73
+ }
74
+
75
+ private string strupr ( ) {
76
+ result = [ "_strupr" , "_wcsupr" , "_mbsupr" , "_strupr_l" , "_wcsupr_l" , "_mbsupr_l" ]
77
+ }
78
+
79
+ private string strrev ( ) { result = [ "_strrev" , "_wcsrev" , "_mbsrev" , "_mbsrev_l" ] }
80
+
81
+ private string strcmp ( ) {
82
+ // NOTE: `strcoll` doesn't satisfy _all_ the definitions of purity: its behavior depends on
83
+ // `LC_COLLATE` (which is set by `setlocale`). Not sure this behavior worth including in the model, so
84
+ // for now we interpret the function as being pure.
85
+ result =
86
+ [
87
+ "strcmp" , "strcspn" , "strncmp" , "strcoll" , "strverscmp" , "_mbsnbcmp" , "_mbsnbcmp_l" ,
88
+ "_stricmp"
89
+ ]
90
+ }
91
+
63
92
/** String standard `strlen` function, and related functions for computing string lengths. */
64
93
private class StrLenFunction extends AliasFunction , ArrayFunction , SideEffectFunction {
65
94
StrLenFunction ( ) {
@@ -114,19 +143,28 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
114
143
/** Pure raw-memory functions. */
115
144
private class PureMemFunction extends AliasFunction , ArrayFunction , TaintFunction ,
116
145
SideEffectFunction {
117
- PureMemFunction ( ) { hasGlobalOrStdName ( [ "memchr" , "memrchr" , "rawmemchr" , "memcmp" , "memmem" ] ) }
146
+ PureMemFunction ( ) {
147
+ hasGlobalOrStdName ( [
148
+ "memchr" , "__builtin_memchr" , "memrchr" , "rawmemchr" , "memcmp" , "__builtin_memcmp" , "memmem"
149
+ ] ) or
150
+ this .hasGlobalName ( "memfrob" )
151
+ }
118
152
119
153
override predicate hasArrayInput ( int bufParam ) {
120
154
getParameter ( bufParam ) .getUnspecifiedType ( ) instanceof PointerType
121
155
}
122
156
123
157
override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
124
158
exists ( ParameterIndex i |
125
- input .isParameter ( i ) and
126
- exists ( getParameter ( i ) )
127
- or
128
- input .isParameterDeref ( i ) and
129
- getParameter ( i ) .getUnspecifiedType ( ) instanceof PointerType
159
+ (
160
+ input .isParameter ( i ) and
161
+ exists ( getParameter ( i ) )
162
+ or
163
+ input .isParameterDeref ( i ) and
164
+ getParameter ( i ) .getUnspecifiedType ( ) instanceof PointerType
165
+ ) and
166
+ // `memfrob` should not have taint from the size argument.
167
+ ( not this .hasGlobalName ( "memfrob" ) or i = 0 )
130
168
) and
131
169
(
132
170
output .isReturnValueDeref ( ) and
0 commit comments