@@ -8,9 +8,8 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
88 SideEffectFunction {
99 PureStrFunction ( ) {
1010 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 ( )
1413 ] )
1514 }
1615
@@ -24,11 +23,16 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
2423
2524 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
2625 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 ) ) )
3236 ) and
3337 (
3438 output .isReturnValueDeref ( ) and
@@ -60,6 +64,31 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio
6064 }
6165}
6266
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+
6392/** String standard `strlen` function, and related functions for computing string lengths. */
6493private class StrLenFunction extends AliasFunction , ArrayFunction , SideEffectFunction {
6594 StrLenFunction ( ) {
@@ -114,19 +143,28 @@ private class PureFunction extends TaintFunction, SideEffectFunction {
114143/** Pure raw-memory functions. */
115144private class PureMemFunction extends AliasFunction , ArrayFunction , TaintFunction ,
116145 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+ }
118152
119153 override predicate hasArrayInput ( int bufParam ) {
120154 getParameter ( bufParam ) .getUnspecifiedType ( ) instanceof PointerType
121155 }
122156
123157 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
124158 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 )
130168 ) and
131169 (
132170 output .isReturnValueDeref ( ) and
0 commit comments