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

Commit 45dfc2b

Browse files
committed
Move to stdlib, extend and refactor the Io module
1 parent fee596a commit 45dfc2b

File tree

3 files changed

+435
-220
lines changed
  • ql
    • src/semmle/go/frameworks
    • test/library-tests/semmle/go/frameworks/StdlibTaintFlow

3 files changed

+435
-220
lines changed

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

Lines changed: 1 addition & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import semmle.go.frameworks.stdlib.EncodingPem
2929
import semmle.go.frameworks.stdlib.EncodingXml
3030
import semmle.go.frameworks.stdlib.Html
3131
import semmle.go.frameworks.stdlib.HtmlTemplate
32+
import semmle.go.frameworks.stdlib.Io
3233
import semmle.go.frameworks.stdlib.Path
3334
import semmle.go.frameworks.stdlib.PathFilepath
3435
import semmle.go.frameworks.stdlib.Reflect
@@ -145,226 +146,6 @@ module Fmt {
145146
}
146147
}
147148

148-
/** Provides models of commonly used functions in the `io` package. */
149-
module Io {
150-
private class Copy extends TaintTracking::FunctionModel {
151-
Copy() {
152-
// func Copy(dst Writer, src Reader) (written int64, err error)
153-
// func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
154-
// func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
155-
hasQualifiedName("io", "Copy") or
156-
hasQualifiedName("io", "CopyBuffer") or
157-
hasQualifiedName("io", "CopyN")
158-
}
159-
160-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
161-
input.isParameter(1) and output.isParameter(0)
162-
}
163-
}
164-
165-
private class Pipe extends TaintTracking::FunctionModel {
166-
Pipe() {
167-
// func Pipe() (*PipeReader, *PipeWriter)
168-
hasQualifiedName("io", "Pipe")
169-
}
170-
171-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
172-
input.isResult(0) and output.isResult(1)
173-
}
174-
}
175-
176-
private class ReadAtLeast extends TaintTracking::FunctionModel {
177-
ReadAtLeast() {
178-
// func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
179-
// func ReadFull(r Reader, buf []byte) (n int, err error)
180-
hasQualifiedName("io", "ReadAtLeast") or
181-
hasQualifiedName("io", "ReadFull")
182-
}
183-
184-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
185-
input.isParameter(0) and output.isParameter(1)
186-
}
187-
}
188-
189-
private class WriteString extends TaintTracking::FunctionModel {
190-
WriteString() {
191-
// func WriteString(w Writer, s string) (n int, err error)
192-
this.hasQualifiedName("io", "WriteString")
193-
}
194-
195-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
196-
input.isParameter(1) and output.isParameter(0)
197-
}
198-
}
199-
200-
private class ByteReaderReadByte extends TaintTracking::FunctionModel, Method {
201-
ByteReaderReadByte() {
202-
// func ReadByte() (byte, error)
203-
this.implements("io", "ByteReader", "ReadByte")
204-
}
205-
206-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
207-
input.isReceiver() and output.isResult(0)
208-
}
209-
}
210-
211-
private class ByteWriterWriteByte extends TaintTracking::FunctionModel, Method {
212-
ByteWriterWriteByte() {
213-
// func WriteByte(c byte) error
214-
this.implements("io", "ByteWriter", "WriteByte")
215-
}
216-
217-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
218-
input.isParameter(0) and output.isReceiver()
219-
}
220-
}
221-
222-
private class ReaderRead extends TaintTracking::FunctionModel, Method {
223-
ReaderRead() {
224-
// func Read(p []byte) (n int, err error)
225-
this.implements("io", "Reader", "Read")
226-
}
227-
228-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
229-
input.isReceiver() and output.isParameter(0)
230-
}
231-
}
232-
233-
private class LimitReader extends TaintTracking::FunctionModel {
234-
LimitReader() {
235-
// func LimitReader(r Reader, n int64) Reader
236-
this.hasQualifiedName("io", "LimitReader")
237-
}
238-
239-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
240-
input.isParameter(0) and output.isResult()
241-
}
242-
}
243-
244-
private class MultiReader extends TaintTracking::FunctionModel {
245-
MultiReader() {
246-
// func MultiReader(readers ...Reader) Reader
247-
this.hasQualifiedName("io", "MultiReader")
248-
}
249-
250-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
251-
input.isParameter(_) and output.isResult()
252-
}
253-
}
254-
255-
private class TeeReader extends TaintTracking::FunctionModel {
256-
TeeReader() {
257-
// func TeeReader(r Reader, w Writer) Reader
258-
this.hasQualifiedName("io", "TeeReader")
259-
}
260-
261-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
262-
input.isParameter(0) and output.isResult()
263-
or
264-
input.isParameter(0) and output.isParameter(1)
265-
}
266-
}
267-
268-
private class ReaderAtReadAt extends TaintTracking::FunctionModel, Method {
269-
ReaderAtReadAt() {
270-
// func ReadAt(p []byte, off int64) (n int, err error)
271-
this.implements("io", "ReaderAt", "ReadAt")
272-
}
273-
274-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
275-
input.isReceiver() and output.isParameter(0)
276-
}
277-
}
278-
279-
private class ReaderFromReadFrom extends TaintTracking::FunctionModel, Method {
280-
ReaderFromReadFrom() {
281-
// func ReadFrom(r Reader) (n int64, err error)
282-
this.implements("io", "ReaderFrom", "ReadFrom")
283-
}
284-
285-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
286-
input.isParameter(0) and output.isReceiver()
287-
}
288-
}
289-
290-
private class RuneReaderReadRune extends TaintTracking::FunctionModel, Method {
291-
RuneReaderReadRune() {
292-
// func ReadRune() (r rune, size int, err error)
293-
this.implements("io", "RuneReader", "ReadRune")
294-
}
295-
296-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
297-
input.isReceiver() and output.isResult(0)
298-
}
299-
}
300-
301-
private class NewSectionReader extends TaintTracking::FunctionModel {
302-
NewSectionReader() {
303-
// func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
304-
this.hasQualifiedName("io", "NewSectionReader")
305-
}
306-
307-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
308-
input.isParameter(0) and output.isResult()
309-
}
310-
}
311-
312-
private class StringWriterWriteString extends TaintTracking::FunctionModel, Method {
313-
StringWriterWriteString() {
314-
// func WriteString(s string) (n int, err error)
315-
this.implements("io", "StringWriter", "WriteString")
316-
}
317-
318-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
319-
input.isParameter(0) and output.isReceiver()
320-
}
321-
}
322-
323-
private class WriterWrite extends TaintTracking::FunctionModel, Method {
324-
WriterWrite() {
325-
// func Write(p []byte) (n int, err error)
326-
this.implements("io", "Writer", "Write")
327-
}
328-
329-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
330-
input.isParameter(0) and output.isReceiver()
331-
}
332-
}
333-
334-
private class MultiWriter extends TaintTracking::FunctionModel {
335-
MultiWriter() {
336-
// func MultiWriter(writers ...Writer) Writer
337-
hasQualifiedName("io", "MultiWriter")
338-
}
339-
340-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
341-
input.isResult() and output.isParameter(_)
342-
}
343-
}
344-
345-
private class WriterAtWriteAt extends TaintTracking::FunctionModel, Method {
346-
WriterAtWriteAt() {
347-
// func WriteAt(p []byte, off int64) (n int, err error)
348-
this.implements("io", "WriterAt", "WriteAt")
349-
}
350-
351-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
352-
input.isParameter(0) and output.isReceiver()
353-
}
354-
}
355-
356-
private class WriterToWriteTo extends TaintTracking::FunctionModel, Method {
357-
WriterToWriteTo() {
358-
// func WriteTo(w Writer) (n int64, err error)
359-
this.implements("io", "WriterTo", "WriteTo")
360-
}
361-
362-
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
363-
input.isReceiver() and output.isParameter(0)
364-
}
365-
}
366-
}
367-
368149
/** Provides models of commonly used functions in the `io/ioutil` package. */
369150
module IoUtil {
370151
private class IoUtilFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `io` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `io` package. */
8+
module Io {
9+
private class FunctionModels extends TaintTracking::FunctionModel {
10+
FunctionInput inp;
11+
FunctionOutput outp;
12+
13+
FunctionModels() {
14+
// signature: func Copy(dst Writer, src Reader) (written int64, err error)
15+
hasQualifiedName("io", "Copy") and
16+
(inp.isParameter(1) and outp.isParameter(0))
17+
or
18+
// signature: func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
19+
hasQualifiedName("io", "CopyBuffer") and
20+
(inp.isParameter(1) and outp.isParameter(0))
21+
or
22+
// signature: func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
23+
hasQualifiedName("io", "CopyN") and
24+
(inp.isParameter(1) and outp.isParameter(0))
25+
or
26+
// signature: func LimitReader(r Reader, n int64) Reader
27+
hasQualifiedName("io", "LimitReader") and
28+
(inp.isParameter(0) and outp.isResult())
29+
or
30+
// signature: func MultiReader(readers ...Reader) Reader
31+
hasQualifiedName("io", "MultiReader") and
32+
(inp.isParameter(_) and outp.isResult())
33+
or
34+
// signature: func MultiWriter(writers ...Writer) Writer
35+
hasQualifiedName("io", "MultiWriter") and
36+
(inp.isResult() and outp.isParameter(_))
37+
or
38+
// signature: func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
39+
hasQualifiedName("io", "NewSectionReader") and
40+
(inp.isParameter(0) and outp.isResult())
41+
or
42+
// signature: func Pipe() (*PipeReader, *PipeWriter)
43+
hasQualifiedName("io", "Pipe") and
44+
(inp.isResult(1) and outp.isResult(0))
45+
or
46+
// signature: func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
47+
hasQualifiedName("io", "ReadAtLeast") and
48+
(inp.isParameter(0) and outp.isParameter(1))
49+
or
50+
// signature: func ReadFull(r Reader, buf []byte) (n int, err error)
51+
hasQualifiedName("io", "ReadFull") and
52+
(inp.isParameter(0) and outp.isParameter(1))
53+
or
54+
// signature: func TeeReader(r Reader, w Writer) Reader
55+
hasQualifiedName("io", "TeeReader") and
56+
(
57+
inp.isParameter(0) and
58+
(outp.isParameter(1) or outp.isResult())
59+
)
60+
or
61+
// signature: func WriteString(w Writer, s string) (n int, err error)
62+
hasQualifiedName("io", "WriteString") and
63+
(inp.isParameter(1) and outp.isParameter(0))
64+
}
65+
66+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
67+
input = inp and output = outp
68+
}
69+
}
70+
71+
private class MethodModels extends TaintTracking::FunctionModel, Method {
72+
FunctionInput inp;
73+
FunctionOutput outp;
74+
75+
MethodModels() {
76+
// signature: func (*LimitedReader).Read(p []byte) (n int, err error)
77+
this.hasQualifiedName("io", "LimitedReader", "Read") and
78+
(inp.isReceiver() and outp.isParameter(0))
79+
or
80+
// signature: func (*PipeReader).Read(data []byte) (n int, err error)
81+
this.hasQualifiedName("io", "PipeReader", "Read") and
82+
(inp.isReceiver() and outp.isParameter(0))
83+
or
84+
// signature: func (*PipeWriter).Write(data []byte) (n int, err error)
85+
this.hasQualifiedName("io", "PipeWriter", "Write") and
86+
(inp.isParameter(0) and outp.isReceiver())
87+
or
88+
// signature: func (*SectionReader).Read(p []byte) (n int, err error)
89+
this.hasQualifiedName("io", "SectionReader", "Read") and
90+
(inp.isReceiver() and outp.isParameter(0))
91+
or
92+
// signature: func (*SectionReader).ReadAt(p []byte, off int64) (n int, err error)
93+
this.hasQualifiedName("io", "SectionReader", "ReadAt") and
94+
(inp.isReceiver() and outp.isParameter(0))
95+
or
96+
// signature: func (Reader).Read(p []byte) (n int, err error)
97+
this.implements("io", "Reader", "Read") and
98+
(inp.isReceiver() and outp.isParameter(0))
99+
or
100+
// signature: func (ReaderAt).ReadAt(p []byte, off int64) (n int, err error)
101+
this.implements("io", "ReaderAt", "ReadAt") and
102+
(inp.isReceiver() and outp.isParameter(0))
103+
or
104+
// signature: func (ReaderFrom).ReadFrom(r Reader) (n int64, err error)
105+
this.implements("io", "ReaderFrom", "ReadFrom") and
106+
(inp.isParameter(0) and outp.isReceiver())
107+
or
108+
// signature: func (Writer).Write(p []byte) (n int, err error)
109+
this.implements("io", "Writer", "Write") and
110+
(inp.isParameter(0) and outp.isReceiver())
111+
or
112+
// signature: func (WriterAt).WriteAt(p []byte, off int64) (n int, err error)
113+
this.implements("io", "WriterAt", "WriteAt") and
114+
(inp.isParameter(0) and outp.isReceiver())
115+
or
116+
// signature: func (StringWriter).WriteString(s string) (n int, err error)
117+
this.implements("io", "StringWriter", "WriteString") and
118+
(inp.isParameter(0) and outp.isReceiver())
119+
or
120+
// signature: func (WriterTo).WriteTo(w Writer) (n int64, err error)
121+
this.implements("io", "WriterTo", "WriteTo") and
122+
(inp.isReceiver() and outp.isParameter(0))
123+
}
124+
125+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
126+
input = inp and output = outp
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)