Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 375ac63

Browse files
committed
Move to stdlib and extend the models for fmt package
1 parent 8d7cbe3 commit 375ac63

File tree

3 files changed

+443
-70
lines changed

3 files changed

+443
-70
lines changed

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -73,76 +73,6 @@ private class CopyFunction extends TaintTracking::FunctionModel {
7373
}
7474
}
7575

76-
/** Provides models of commonly used functions in the `fmt` package. */
77-
module Fmt {
78-
/** The `Sprint` function or one of its variants. */
79-
class Sprinter extends TaintTracking::FunctionModel {
80-
Sprinter() { this.hasQualifiedName("fmt", ["Sprint", "Sprintf", "Sprintln"]) }
81-
82-
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
83-
inp.isParameter(_) and outp.isResult()
84-
}
85-
}
86-
87-
/** The `Print` function or one of its variants. */
88-
class Printer extends Function {
89-
Printer() { this.hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
90-
}
91-
92-
/** A call to `Print`, `Fprint`, or similar. */
93-
private class PrintCall extends LoggerCall::Range, DataFlow::CallNode {
94-
int firstPrintedArg;
95-
96-
PrintCall() {
97-
this.getTarget() instanceof Printer and firstPrintedArg = 0
98-
or
99-
this.getTarget() instanceof Fprinter and firstPrintedArg = 1
100-
}
101-
102-
override DataFlow::Node getAMessageComponent() {
103-
result = this.getArgument(any(int i | i >= firstPrintedArg))
104-
}
105-
}
106-
107-
/** The `Fprint` function or one of its variants. */
108-
private class Fprinter extends TaintTracking::FunctionModel {
109-
Fprinter() { this.hasQualifiedName("fmt", ["Fprint", "Fprintf", "Fprintln"]) }
110-
111-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
112-
input.isParameter(any(int i | i > 0)) and output.isParameter(0)
113-
}
114-
}
115-
116-
/** The `Sscan` function or one of its variants. */
117-
private class Sscanner extends TaintTracking::FunctionModel {
118-
Sscanner() { this.hasQualifiedName("fmt", ["Sscan", "Sscanf", "Sscanln"]) }
119-
120-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
121-
input.isParameter(0) and
122-
exists(int i | if getName() = "Sscanf" then i > 1 else i > 0 | output.isParameter(i))
123-
}
124-
}
125-
126-
/** The `Scan` function or one of its variants, all of which read from os.Stdin */
127-
class Scanner extends Function {
128-
Scanner() { this.hasQualifiedName("fmt", ["Scan", "Scanf", "Scanln"]) }
129-
}
130-
131-
/**
132-
* The `Fscan` function or one of its variants,
133-
* all of which read from a specified io.Reader
134-
*/
135-
class FScanner extends Function {
136-
FScanner() { this.hasQualifiedName("fmt", ["Fscan", "Fscanf", "Fscanln"]) }
137-
138-
/**
139-
* Returns the node corresponding to the io.Reader
140-
* argument provided in the call.
141-
*/
142-
FunctionInput getReader() { result.isParameter(0) }
143-
}
144-
}
145-
14676
/** Provides models of commonly used functions in the `io` package. */
14777
module Io {
14878
private class Copy extends TaintTracking::FunctionModel {
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `fmt` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `fmt` package. */
8+
module Fmt {
9+
/** The `Sprint` function or one of its variants. */
10+
class Sprinter extends TaintTracking::FunctionModel {
11+
Sprinter() {
12+
// signature: func Sprint(a ...interface{}) string
13+
hasQualifiedName("fmt", "Sprint")
14+
or
15+
// signature: func Sprintf(format string, a ...interface{}) string
16+
hasQualifiedName("fmt", "Sprintf")
17+
or
18+
// signature: func Sprintln(a ...interface{}) string
19+
hasQualifiedName("fmt", "Sprintln")
20+
}
21+
22+
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
23+
inp.isParameter(_) and outp.isResult()
24+
}
25+
}
26+
27+
/** The `Print` function or one of its variants. */
28+
class Printer extends Function {
29+
Printer() { hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
30+
}
31+
32+
/** A call to `Print`, `Fprint`, or similar. */
33+
private class PrintCall extends LoggerCall::Range, DataFlow::CallNode {
34+
int firstPrintedArg;
35+
36+
PrintCall() {
37+
this.getTarget() instanceof Printer and firstPrintedArg = 0
38+
or
39+
this.getTarget() instanceof Fprinter and firstPrintedArg = 1
40+
}
41+
42+
override DataFlow::Node getAMessageComponent() {
43+
result = this.getArgument(any(int i | i >= firstPrintedArg))
44+
}
45+
}
46+
47+
/** The `Fprint` function or one of its variants. */
48+
private class Fprinter extends TaintTracking::FunctionModel {
49+
Fprinter() {
50+
// signature: func Fprint(w io.Writer, a ...interface{}) (n int, err error)
51+
hasQualifiedName("fmt", "Fprint")
52+
or
53+
// signature: func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
54+
hasQualifiedName("fmt", "Fprintf")
55+
or
56+
// signature: func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
57+
hasQualifiedName("fmt", "Fprintln")
58+
}
59+
60+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
61+
input.isParameter(any(int i | i > 0)) and output.isParameter(0)
62+
}
63+
}
64+
65+
/** The `Sscan` function or one of its variants. */
66+
private class Sscanner extends TaintTracking::FunctionModel {
67+
FunctionInput inp;
68+
FunctionOutput outp;
69+
70+
Sscanner() {
71+
// signature: func Sscan(str string, a ...interface{}) (n int, err error)
72+
hasQualifiedName("fmt", "Sscan") and
73+
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
74+
or
75+
// signature: func Sscanf(str string, format string, a ...interface{}) (n int, err error)
76+
hasQualifiedName("fmt", "Sscanf") and
77+
(inp.isParameter([0, 1]) and outp.isParameter(any(int i | i >= 2)))
78+
or
79+
// signature: func Sscanln(str string, a ...interface{}) (n int, err error)
80+
hasQualifiedName("fmt", "Sscanln") and
81+
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
82+
}
83+
84+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
85+
input = inp and output = outp
86+
}
87+
}
88+
89+
/** The `Scan` function or one of its variants, all of which read from os.Stdin */
90+
class Scanner extends Function {
91+
Scanner() { this.hasQualifiedName("fmt", ["Scan", "Scanf", "Scanln"]) }
92+
}
93+
94+
/**
95+
* The `Fscan` function or one of its variants,
96+
* all of which read from a specified io.Reader
97+
*/
98+
class FScanner extends Function {
99+
FScanner() { this.hasQualifiedName("fmt", ["Fscan", "Fscanf", "Fscanln"]) }
100+
101+
/**
102+
* Returns the node corresponding to the io.Reader
103+
* argument provided in the call.
104+
*/
105+
FunctionInput getReader() { result.isParameter(0) }
106+
}
107+
108+
private class FunctionModels extends TaintTracking::FunctionModel {
109+
FunctionInput inp;
110+
FunctionOutput outp;
111+
112+
FunctionModels() {
113+
// signature: func Errorf(format string, a ...interface{}) error
114+
hasQualifiedName("fmt", "Errorf") and
115+
(inp.isParameter(_) and outp.isResult())
116+
or
117+
// signature: func Fscan(r io.Reader, a ...interface{}) (n int, err error)
118+
hasQualifiedName("fmt", "Fscan") and
119+
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
120+
or
121+
// signature: func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
122+
hasQualifiedName("fmt", "Fscanf") and
123+
(inp.isParameter([0, 1]) and outp.isParameter(any(int i | i >= 2)))
124+
or
125+
// signature: func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
126+
hasQualifiedName("fmt", "Fscanln") and
127+
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
128+
}
129+
130+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
131+
input = inp and output = outp
132+
}
133+
}
134+
135+
private class MethodModels extends TaintTracking::FunctionModel, Method {
136+
FunctionInput inp;
137+
FunctionOutput outp;
138+
139+
MethodModels() {
140+
// signature: func (GoStringer).GoString() string
141+
this.implements("fmt", "GoStringer", "GoString") and
142+
(inp.isReceiver() and outp.isResult())
143+
or
144+
// signature: func (ScanState).Read(buf []byte) (n int, err error)
145+
this.implements("fmt", "ScanState", "Read") and
146+
(inp.isReceiver() and outp.isParameter(0))
147+
or
148+
// signature: func (Stringer).String() string
149+
this.implements("fmt", "Stringer", "String") and
150+
(inp.isReceiver() and outp.isResult())
151+
or
152+
// signature: func (ScanState).Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
153+
this.implements("fmt", "ScanState", "Token") and
154+
(inp.isReceiver() and outp.isResult(0))
155+
or
156+
// signature: func (State).Write(b []byte) (n int, err error)
157+
this.implements("fmt", "State", "Write") and
158+
(inp.isParameter(0) and outp.isReceiver())
159+
}
160+
161+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
162+
input = inp and output = outp
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)