@@ -16,50 +16,65 @@ import semmle.code.cpp.ir.dataflow.TaintTracking
1616import semmle.code.cpp.security.FlowSources
1717
1818/**
19- * A gzFile Variable as a Flow source
19+ * A ` gzFile` Variable as a Flow source
2020 */
2121private class GzFileVar extends VariableAccess {
2222 GzFileVar ( ) { this .getType ( ) .hasName ( "gzFile" ) }
2323}
2424
2525/**
2626 * The `gzopen` function as a Flow source
27+ *
28+ * `gzopen(const char *path, const char *mode)`
2729 */
2830private class GzopenFunction extends Function {
29- GzopenFunction ( ) { hasGlobalName ( "gzopen" ) }
31+ GzopenFunction ( ) { this . hasGlobalName ( "gzopen" ) }
3032}
3133
3234/**
3335 * The `gzdopen` function as a Flow source
36+ *
37+ * `gzdopen(int fd, const char *mode)`
3438 */
3539private class GzdopenFunction extends Function {
36- GzdopenFunction ( ) { hasGlobalName ( "gzdopen" ) }
40+ GzdopenFunction ( ) { this . hasGlobalName ( "gzdopen" ) }
3741}
3842
3943/**
4044 * The `gzfread` function is used in Flow sink
45+ *
46+ * `gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file)`
4147 */
4248private class GzfreadFunction extends Function {
43- GzfreadFunction ( ) { hasGlobalName ( "gzfread" ) }
49+ GzfreadFunction ( ) { this .hasGlobalName ( "gzfread" ) }
50+ }
51+
52+ /**
53+ * The `gzgets` function is used in Flow sink.
54+ *
55+ * `gzgets(gzFile file, char *buf, int len)`
56+ */
57+ private class GzgetsFunction extends Function {
58+ GzgetsFunction ( ) { this .hasGlobalName ( "gzgets" ) }
4459}
4560
4661/**
4762 * The `gzread` function is used in Flow sink
63+ *
64+ * `gzread(gzFile file, voidp buf, unsigned len)`
4865 */
4966private class GzreadFunction extends Function {
50- GzreadFunction ( ) { hasGlobalName ( "gzread" ) }
67+ GzreadFunction ( ) { this . hasGlobalName ( "gzread" ) }
5168}
5269
5370module ZlibTaintConfig implements DataFlow:: ConfigSig {
5471 predicate isSource ( DataFlow:: Node source ) {
55- // gzopen(const char *path, const char *mode);
5672 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzopenFunction |
5773 fc .getArgument ( 0 ) = source .asExpr ( ) and
5874 // arg 0 can be a path string whichwe must do following check
5975 not fc .getArgument ( 0 ) .isConstant ( )
6076 )
6177 or
62- //gzdopen(int fd, const char *mode);
6378 // IDK whether it is good to use all file decriptors function returns as source or not
6479 // because we can do more sanitization from fd function sources
6580 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzdopenFunction |
@@ -70,40 +85,43 @@ module ZlibTaintConfig implements DataFlow::ConfigSig {
7085 }
7186
7287 predicate isSink ( DataFlow:: Node sink ) {
73- // gzread(gzFile file, voidp buf, unsigned len));
7488 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzreadFunction |
7589 fc .getArgument ( 0 ) = sink .asExpr ( ) and
7690 not sanitizer ( fc )
7791 // TODO: and not sanitizer2(fc.getArgument(2))
7892 )
7993 or
80- // gzfread((voidp buf, z_size_t size, z_size_t nitems, gzFile file));
8194 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzfreadFunction |
8295 sink .asExpr ( ) = fc .getArgument ( 3 )
8396 )
97+ or
98+ exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzgetsFunction |
99+ sink .asExpr ( ) = fc .getArgument ( 0 )
100+ )
84101 }
85102
86103 predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
87- // gzopen(const char *path, const char *mode);
88- // gzdopen(int fd, const char *mode);
89104 exists ( FunctionCall fc |
90105 fc .getTarget ( ) instanceof GzopenFunction or fc .getTarget ( ) instanceof GzdopenFunction
91106 |
92107 node1 .asExpr ( ) = fc .getArgument ( 0 ) and
93108 node2 .asExpr ( ) = fc
94109 )
95110 or
96- // gzread(gzFile file, voidp buf, unsigned len);
97111 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzreadFunction |
98112 node1 .asExpr ( ) = fc .getArgument ( 0 ) and
99113 node2 .asExpr ( ) = fc .getArgument ( 1 )
100114 )
101115 or
102- // gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file);
103116 exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzfreadFunction |
104117 node1 .asExpr ( ) = fc .getArgument ( 3 ) and
105118 node2 .asExpr ( ) = fc .getArgument ( 0 )
106119 )
120+ or
121+ exists ( FunctionCall fc | fc .getTarget ( ) instanceof GzgetsFunction |
122+ node1 .asExpr ( ) = fc .getArgument ( 0 ) and
123+ node1 .asExpr ( ) = fc .getArgument ( 1 )
124+ )
107125 }
108126}
109127
@@ -116,19 +134,12 @@ predicate sanitizer(FunctionCall fc) {
116134}
117135
118136// TODO:
119- // predicate sanitizer2(Expr arg ) {
137+ // predicate sanitizer2(FunctionCall fc ) {
120138// exists(Expr e |
121139// // a RelationalOperation which isn't compared with a Literal that using for end of read
122- // TaintTracking::localExprTaint(arg, e.(RelationalOperation).getAChild*() )
140+ // TaintTracking::localExprTaint(fc.getArgument(2), e )
123141// )
124142// }
125- // predicate test(FunctionCall fc, Expr sink) {
126- // exists( | fc.getTarget() instanceof GzreadFunction |
127- // // a RelationalOperation which isn't compared with a Literal that using for end of read
128- // TaintTracking::localExprTaint(fc.getArgument(2).(VariableAccess), sink)
129- // ) and
130- // sink.getFile().getLocation().toString().matches("%main.cpp%")
131- // }
132143module ZlibTaint = TaintTracking:: Global< ZlibTaintConfig > ;
133144
134145import ZlibTaint:: PathGraph
0 commit comments