@@ -10,64 +10,76 @@ import semmle.code.cpp.models.interfaces.SideEffect
1010import semmle.code.cpp.models.interfaces.Taint
1111
1212/**
13- * The standard functions `memcpy` and `memmove`, and the gcc variant
14- * `__builtin___memcpy_chk`
13+ * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
14+ * `__builtin___memcpy_chk`.
1515 */
16- class MemcpyFunction extends ArrayFunction , DataFlowFunction , SideEffectFunction , TaintFunction {
16+ class MemcpyFunction extends ArrayFunction , DataFlowFunction , SideEffectFunction {
1717 MemcpyFunction ( ) {
18- this .hasName ( "memcpy" ) or
19- this .hasName ( "memmove" ) or
20- this .hasName ( "__builtin___memcpy_chk" )
18+ // memcpy(dest, src, num)
19+ // memmove(dest, src, num)
20+ // memmove(dest, src, num, remaining)
21+ this .hasName ( [ "memcpy" , "memmove" , "__builtin___memcpy_chk" ] )
22+ or
23+ // bcopy(src, dest, num)
24+ this .hasGlobalOrStdName ( "bcopy" )
2125 }
2226
23- override predicate hasArrayInput ( int bufParam ) { bufParam = 1 }
27+ /**
28+ * Gets the index of the parameter that is the source buffer for the copy.
29+ */
30+ int getParamSrc ( ) { if this .hasGlobalOrStdName ( "bcopy" ) then result = 0 else result = 1 }
31+
32+ /**
33+ * Gets the index of the parameter that is the destination buffer for the
34+ * copy.
35+ */
36+ int getParamDest ( ) { if this .hasGlobalOrStdName ( "bcopy" ) then result = 1 else result = 0 }
37+
38+ /**
39+ * Gets the index of the parameter that is the size of the copy (in bytes).
40+ */
41+ int getParamSize ( ) { result = 2 }
42+
43+ override predicate hasArrayInput ( int bufParam ) { bufParam = getParamSrc ( ) }
2444
25- override predicate hasArrayOutput ( int bufParam ) { bufParam = 0 }
45+ override predicate hasArrayOutput ( int bufParam ) { bufParam = getParamDest ( ) }
2646
2747 override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
28- input .isParameterDeref ( 1 ) and
29- output .isParameterDeref ( 0 )
48+ input .isParameterDeref ( getParamSrc ( ) ) and
49+ output .isParameterDeref ( getParamDest ( ) )
3050 or
31- input .isParameterDeref ( 1 ) and
51+ input .isParameterDeref ( getParamSrc ( ) ) and
3252 output .isReturnValueDeref ( )
3353 or
34- input .isParameter ( 0 ) and
54+ input .isParameter ( getParamDest ( ) ) and
3555 output .isReturnValue ( )
3656 }
3757
38- override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
39- input .isParameter ( 2 ) and
40- output .isParameterDeref ( 0 )
41- or
42- input .isParameter ( 2 ) and
43- output .isReturnValueDeref ( )
44- }
45-
4658 override predicate hasArrayWithVariableSize ( int bufParam , int countParam ) {
4759 (
48- bufParam = 0 or
49- bufParam = 1
60+ bufParam = getParamDest ( ) or
61+ bufParam = getParamSrc ( )
5062 ) and
51- countParam = 2
63+ countParam = getParamSize ( )
5264 }
5365
5466 override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
5567
5668 override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
5769
5870 override predicate hasSpecificWriteSideEffect ( ParameterIndex i , boolean buffer , boolean mustWrite ) {
59- i = 0 and buffer = true and mustWrite = true
71+ i = getParamDest ( ) and buffer = true and mustWrite = true
6072 }
6173
6274 override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
63- i = 1 and buffer = true
75+ i = getParamSrc ( ) and buffer = true
6476 }
6577
6678 override ParameterIndex getParameterSizeIndex ( ParameterIndex i ) {
67- result = 2 and
79+ result = getParamSize ( ) and
6880 (
69- i = 0 or
70- i = 1
81+ i = getParamDest ( ) or
82+ i = getParamSrc ( )
7183 )
7284 }
7385}
0 commit comments