Move to stdlib, extend and refactor the Io module

This commit is contained in:
Slavomir
2020-09-15 17:14:24 +02:00
parent fee596ac83
commit 45dfc2bcf2
3 changed files with 435 additions and 220 deletions

View File

@@ -29,6 +29,7 @@ import semmle.go.frameworks.stdlib.EncodingPem
import semmle.go.frameworks.stdlib.EncodingXml
import semmle.go.frameworks.stdlib.Html
import semmle.go.frameworks.stdlib.HtmlTemplate
import semmle.go.frameworks.stdlib.Io
import semmle.go.frameworks.stdlib.Path
import semmle.go.frameworks.stdlib.PathFilepath
import semmle.go.frameworks.stdlib.Reflect
@@ -145,226 +146,6 @@ module Fmt {
}
}
/** Provides models of commonly used functions in the `io` package. */
module Io {
private class Copy extends TaintTracking::FunctionModel {
Copy() {
// func Copy(dst Writer, src Reader) (written int64, err error)
// func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
// func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
hasQualifiedName("io", "Copy") or
hasQualifiedName("io", "CopyBuffer") or
hasQualifiedName("io", "CopyN")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(1) and output.isParameter(0)
}
}
private class Pipe extends TaintTracking::FunctionModel {
Pipe() {
// func Pipe() (*PipeReader, *PipeWriter)
hasQualifiedName("io", "Pipe")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isResult(0) and output.isResult(1)
}
}
private class ReadAtLeast extends TaintTracking::FunctionModel {
ReadAtLeast() {
// func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
// func ReadFull(r Reader, buf []byte) (n int, err error)
hasQualifiedName("io", "ReadAtLeast") or
hasQualifiedName("io", "ReadFull")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isParameter(1)
}
}
private class WriteString extends TaintTracking::FunctionModel {
WriteString() {
// func WriteString(w Writer, s string) (n int, err error)
this.hasQualifiedName("io", "WriteString")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(1) and output.isParameter(0)
}
}
private class ByteReaderReadByte extends TaintTracking::FunctionModel, Method {
ByteReaderReadByte() {
// func ReadByte() (byte, error)
this.implements("io", "ByteReader", "ReadByte")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReceiver() and output.isResult(0)
}
}
private class ByteWriterWriteByte extends TaintTracking::FunctionModel, Method {
ByteWriterWriteByte() {
// func WriteByte(c byte) error
this.implements("io", "ByteWriter", "WriteByte")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReceiver()
}
}
private class ReaderRead extends TaintTracking::FunctionModel, Method {
ReaderRead() {
// func Read(p []byte) (n int, err error)
this.implements("io", "Reader", "Read")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReceiver() and output.isParameter(0)
}
}
private class LimitReader extends TaintTracking::FunctionModel {
LimitReader() {
// func LimitReader(r Reader, n int64) Reader
this.hasQualifiedName("io", "LimitReader")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isResult()
}
}
private class MultiReader extends TaintTracking::FunctionModel {
MultiReader() {
// func MultiReader(readers ...Reader) Reader
this.hasQualifiedName("io", "MultiReader")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(_) and output.isResult()
}
}
private class TeeReader extends TaintTracking::FunctionModel {
TeeReader() {
// func TeeReader(r Reader, w Writer) Reader
this.hasQualifiedName("io", "TeeReader")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isResult()
or
input.isParameter(0) and output.isParameter(1)
}
}
private class ReaderAtReadAt extends TaintTracking::FunctionModel, Method {
ReaderAtReadAt() {
// func ReadAt(p []byte, off int64) (n int, err error)
this.implements("io", "ReaderAt", "ReadAt")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReceiver() and output.isParameter(0)
}
}
private class ReaderFromReadFrom extends TaintTracking::FunctionModel, Method {
ReaderFromReadFrom() {
// func ReadFrom(r Reader) (n int64, err error)
this.implements("io", "ReaderFrom", "ReadFrom")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReceiver()
}
}
private class RuneReaderReadRune extends TaintTracking::FunctionModel, Method {
RuneReaderReadRune() {
// func ReadRune() (r rune, size int, err error)
this.implements("io", "RuneReader", "ReadRune")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReceiver() and output.isResult(0)
}
}
private class NewSectionReader extends TaintTracking::FunctionModel {
NewSectionReader() {
// func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
this.hasQualifiedName("io", "NewSectionReader")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isResult()
}
}
private class StringWriterWriteString extends TaintTracking::FunctionModel, Method {
StringWriterWriteString() {
// func WriteString(s string) (n int, err error)
this.implements("io", "StringWriter", "WriteString")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReceiver()
}
}
private class WriterWrite extends TaintTracking::FunctionModel, Method {
WriterWrite() {
// func Write(p []byte) (n int, err error)
this.implements("io", "Writer", "Write")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReceiver()
}
}
private class MultiWriter extends TaintTracking::FunctionModel {
MultiWriter() {
// func MultiWriter(writers ...Writer) Writer
hasQualifiedName("io", "MultiWriter")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isResult() and output.isParameter(_)
}
}
private class WriterAtWriteAt extends TaintTracking::FunctionModel, Method {
WriterAtWriteAt() {
// func WriteAt(p []byte, off int64) (n int, err error)
this.implements("io", "WriterAt", "WriteAt")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and output.isReceiver()
}
}
private class WriterToWriteTo extends TaintTracking::FunctionModel, Method {
WriterToWriteTo() {
// func WriteTo(w Writer) (n int64, err error)
this.implements("io", "WriterTo", "WriteTo")
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isReceiver() and output.isParameter(0)
}
}
}
/** Provides models of commonly used functions in the `io/ioutil` package. */
module IoUtil {
private class IoUtilFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode {

View File

@@ -0,0 +1,129 @@
/**
* Provides classes modeling security-relevant aspects of the `io` package.
*/
import go
/** Provides models of commonly used functions in the `io` package. */
module Io {
private class FunctionModels extends TaintTracking::FunctionModel {
FunctionInput inp;
FunctionOutput outp;
FunctionModels() {
// signature: func Copy(dst Writer, src Reader) (written int64, err error)
hasQualifiedName("io", "Copy") and
(inp.isParameter(1) and outp.isParameter(0))
or
// signature: func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
hasQualifiedName("io", "CopyBuffer") and
(inp.isParameter(1) and outp.isParameter(0))
or
// signature: func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
hasQualifiedName("io", "CopyN") and
(inp.isParameter(1) and outp.isParameter(0))
or
// signature: func LimitReader(r Reader, n int64) Reader
hasQualifiedName("io", "LimitReader") and
(inp.isParameter(0) and outp.isResult())
or
// signature: func MultiReader(readers ...Reader) Reader
hasQualifiedName("io", "MultiReader") and
(inp.isParameter(_) and outp.isResult())
or
// signature: func MultiWriter(writers ...Writer) Writer
hasQualifiedName("io", "MultiWriter") and
(inp.isResult() and outp.isParameter(_))
or
// signature: func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
hasQualifiedName("io", "NewSectionReader") and
(inp.isParameter(0) and outp.isResult())
or
// signature: func Pipe() (*PipeReader, *PipeWriter)
hasQualifiedName("io", "Pipe") and
(inp.isResult(1) and outp.isResult(0))
or
// signature: func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
hasQualifiedName("io", "ReadAtLeast") and
(inp.isParameter(0) and outp.isParameter(1))
or
// signature: func ReadFull(r Reader, buf []byte) (n int, err error)
hasQualifiedName("io", "ReadFull") and
(inp.isParameter(0) and outp.isParameter(1))
or
// signature: func TeeReader(r Reader, w Writer) Reader
hasQualifiedName("io", "TeeReader") and
(
inp.isParameter(0) and
(outp.isParameter(1) or outp.isResult())
)
or
// signature: func WriteString(w Writer, s string) (n int, err error)
hasQualifiedName("io", "WriteString") and
(inp.isParameter(1) and outp.isParameter(0))
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
private class MethodModels extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
MethodModels() {
// signature: func (*LimitedReader).Read(p []byte) (n int, err error)
this.hasQualifiedName("io", "LimitedReader", "Read") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (*PipeReader).Read(data []byte) (n int, err error)
this.hasQualifiedName("io", "PipeReader", "Read") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (*PipeWriter).Write(data []byte) (n int, err error)
this.hasQualifiedName("io", "PipeWriter", "Write") and
(inp.isParameter(0) and outp.isReceiver())
or
// signature: func (*SectionReader).Read(p []byte) (n int, err error)
this.hasQualifiedName("io", "SectionReader", "Read") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (*SectionReader).ReadAt(p []byte, off int64) (n int, err error)
this.hasQualifiedName("io", "SectionReader", "ReadAt") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (Reader).Read(p []byte) (n int, err error)
this.implements("io", "Reader", "Read") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (ReaderAt).ReadAt(p []byte, off int64) (n int, err error)
this.implements("io", "ReaderAt", "ReadAt") and
(inp.isReceiver() and outp.isParameter(0))
or
// signature: func (ReaderFrom).ReadFrom(r Reader) (n int64, err error)
this.implements("io", "ReaderFrom", "ReadFrom") and
(inp.isParameter(0) and outp.isReceiver())
or
// signature: func (Writer).Write(p []byte) (n int, err error)
this.implements("io", "Writer", "Write") and
(inp.isParameter(0) and outp.isReceiver())
or
// signature: func (WriterAt).WriteAt(p []byte, off int64) (n int, err error)
this.implements("io", "WriterAt", "WriteAt") and
(inp.isParameter(0) and outp.isReceiver())
or
// signature: func (StringWriter).WriteString(s string) (n int, err error)
this.implements("io", "StringWriter", "WriteString") and
(inp.isParameter(0) and outp.isReceiver())
or
// signature: func (WriterTo).WriteTo(w Writer) (n int64, err error)
this.implements("io", "WriterTo", "WriteTo") and
(inp.isReceiver() and outp.isParameter(0))
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}

View File

@@ -0,0 +1,305 @@
// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT.
package main
import "io"
func TaintStepTest_IoCopy_B0I0O0(sourceCQL interface{}) interface{} {
fromReader656 := sourceCQL.(io.Reader)
var intoWriter414 io.Writer
io.Copy(intoWriter414, fromReader656)
return intoWriter414
}
func TaintStepTest_IoCopyBuffer_B0I0O0(sourceCQL interface{}) interface{} {
fromReader518 := sourceCQL.(io.Reader)
var intoWriter650 io.Writer
io.CopyBuffer(intoWriter650, fromReader518, nil)
return intoWriter650
}
func TaintStepTest_IoCopyN_B0I0O0(sourceCQL interface{}) interface{} {
fromReader784 := sourceCQL.(io.Reader)
var intoWriter957 io.Writer
io.CopyN(intoWriter957, fromReader784, 0)
return intoWriter957
}
func TaintStepTest_IoLimitReader_B0I0O0(sourceCQL interface{}) interface{} {
fromReader520 := sourceCQL.(io.Reader)
intoReader443 := io.LimitReader(fromReader520, 0)
return intoReader443
}
func TaintStepTest_IoMultiReader_B0I0O0(sourceCQL interface{}) interface{} {
fromReader127 := sourceCQL.(io.Reader)
intoReader483 := io.MultiReader(fromReader127)
return intoReader483
}
func TaintStepTest_IoMultiWriter_B0I0O0(sourceCQL interface{}) interface{} {
fromWriter989 := sourceCQL.(io.Writer)
var intoWriter982 io.Writer
intermediateCQL := io.MultiWriter(intoWriter982)
link(fromWriter989, intermediateCQL)
return intoWriter982
}
func TaintStepTest_IoNewSectionReader_B0I0O0(sourceCQL interface{}) interface{} {
fromReaderAt417 := sourceCQL.(io.ReaderAt)
intoSectionReader584 := io.NewSectionReader(fromReaderAt417, 0, 0)
return intoSectionReader584
}
func TaintStepTest_IoPipe_B0I0O0(sourceCQL interface{}) interface{} {
fromPipeWriter991 := sourceCQL.(*io.PipeWriter)
intoPipeReader881, intermediateCQL := io.Pipe()
link(fromPipeWriter991, intermediateCQL)
return intoPipeReader881
}
func TaintStepTest_IoReadAtLeast_B0I0O0(sourceCQL interface{}) interface{} {
fromReader186 := sourceCQL.(io.Reader)
var intoByte284 []byte
io.ReadAtLeast(fromReader186, intoByte284, 0)
return intoByte284
}
func TaintStepTest_IoReadFull_B0I0O0(sourceCQL interface{}) interface{} {
fromReader908 := sourceCQL.(io.Reader)
var intoByte137 []byte
io.ReadFull(fromReader908, intoByte137)
return intoByte137
}
func TaintStepTest_IoTeeReader_B0I0O0(sourceCQL interface{}) interface{} {
fromReader494 := sourceCQL.(io.Reader)
var intoWriter873 io.Writer
io.TeeReader(fromReader494, intoWriter873)
return intoWriter873
}
func TaintStepTest_IoTeeReader_B0I0O1(sourceCQL interface{}) interface{} {
fromReader599 := sourceCQL.(io.Reader)
intoReader409 := io.TeeReader(fromReader599, nil)
return intoReader409
}
func TaintStepTest_IoWriteString_B0I0O0(sourceCQL interface{}) interface{} {
fromString246 := sourceCQL.(string)
var intoWriter898 io.Writer
io.WriteString(intoWriter898, fromString246)
return intoWriter898
}
func TaintStepTest_IoLimitedReaderRead_B0I0O0(sourceCQL interface{}) interface{} {
fromLimitedReader598 := sourceCQL.(io.LimitedReader)
var intoByte631 []byte
fromLimitedReader598.Read(intoByte631)
return intoByte631
}
func TaintStepTest_IoPipeReaderRead_B0I0O0(sourceCQL interface{}) interface{} {
fromPipeReader165 := sourceCQL.(io.PipeReader)
var intoByte150 []byte
fromPipeReader165.Read(intoByte150)
return intoByte150
}
func TaintStepTest_IoPipeWriterWrite_B0I0O0(sourceCQL interface{}) interface{} {
fromByte340 := sourceCQL.([]byte)
var intoPipeWriter471 io.PipeWriter
intoPipeWriter471.Write(fromByte340)
return intoPipeWriter471
}
func TaintStepTest_IoSectionReaderRead_B0I0O0(sourceCQL interface{}) interface{} {
fromSectionReader290 := sourceCQL.(io.SectionReader)
var intoByte758 []byte
fromSectionReader290.Read(intoByte758)
return intoByte758
}
func TaintStepTest_IoSectionReaderReadAt_B0I0O0(sourceCQL interface{}) interface{} {
fromSectionReader396 := sourceCQL.(io.SectionReader)
var intoByte707 []byte
fromSectionReader396.ReadAt(intoByte707, 0)
return intoByte707
}
func TaintStepTest_IoReaderRead_B0I0O0(sourceCQL interface{}) interface{} {
fromReader912 := sourceCQL.(io.Reader)
var intoByte718 []byte
fromReader912.Read(intoByte718)
return intoByte718
}
func TaintStepTest_IoReaderAtReadAt_B0I0O0(sourceCQL interface{}) interface{} {
fromReaderAt972 := sourceCQL.(io.ReaderAt)
var intoByte633 []byte
fromReaderAt972.ReadAt(intoByte633, 0)
return intoByte633
}
func TaintStepTest_IoReaderFromReadFrom_B0I0O0(sourceCQL interface{}) interface{} {
fromReader316 := sourceCQL.(io.Reader)
var intoReaderFrom145 io.ReaderFrom
intoReaderFrom145.ReadFrom(fromReader316)
return intoReaderFrom145
}
func TaintStepTest_IoWriterWrite_B0I0O0(sourceCQL interface{}) interface{} {
fromByte817 := sourceCQL.([]byte)
var intoWriter474 io.Writer
intoWriter474.Write(fromByte817)
return intoWriter474
}
func TaintStepTest_IoWriterAtWriteAt_B0I0O0(sourceCQL interface{}) interface{} {
fromByte832 := sourceCQL.([]byte)
var intoWriterAt378 io.WriterAt
intoWriterAt378.WriteAt(fromByte832, 0)
return intoWriterAt378
}
func TaintStepTest_IoStringWriterWriteString_B0I0O0(sourceCQL interface{}) interface{} {
fromString541 := sourceCQL.(string)
var intoStringWriter139 io.StringWriter
intoStringWriter139.WriteString(fromString541)
return intoStringWriter139
}
func TaintStepTest_IoWriterToWriteTo_B0I0O0(sourceCQL interface{}) interface{} {
fromWriterTo814 := sourceCQL.(io.WriterTo)
var intoWriter768 io.Writer
fromWriterTo814.WriteTo(intoWriter768)
return intoWriter768
}
func RunAllTaints_Io() {
{
source := newSource(0)
out := TaintStepTest_IoCopy_B0I0O0(source)
sink(0, out)
}
{
source := newSource(1)
out := TaintStepTest_IoCopyBuffer_B0I0O0(source)
sink(1, out)
}
{
source := newSource(2)
out := TaintStepTest_IoCopyN_B0I0O0(source)
sink(2, out)
}
{
source := newSource(3)
out := TaintStepTest_IoLimitReader_B0I0O0(source)
sink(3, out)
}
{
source := newSource(4)
out := TaintStepTest_IoMultiReader_B0I0O0(source)
sink(4, out)
}
{
source := newSource(5)
out := TaintStepTest_IoMultiWriter_B0I0O0(source)
sink(5, out)
}
{
source := newSource(6)
out := TaintStepTest_IoNewSectionReader_B0I0O0(source)
sink(6, out)
}
{
source := newSource(7)
out := TaintStepTest_IoPipe_B0I0O0(source)
sink(7, out)
}
{
source := newSource(8)
out := TaintStepTest_IoReadAtLeast_B0I0O0(source)
sink(8, out)
}
{
source := newSource(9)
out := TaintStepTest_IoReadFull_B0I0O0(source)
sink(9, out)
}
{
source := newSource(10)
out := TaintStepTest_IoTeeReader_B0I0O0(source)
sink(10, out)
}
{
source := newSource(11)
out := TaintStepTest_IoTeeReader_B0I0O1(source)
sink(11, out)
}
{
source := newSource(12)
out := TaintStepTest_IoWriteString_B0I0O0(source)
sink(12, out)
}
{
source := newSource(13)
out := TaintStepTest_IoLimitedReaderRead_B0I0O0(source)
sink(13, out)
}
{
source := newSource(14)
out := TaintStepTest_IoPipeReaderRead_B0I0O0(source)
sink(14, out)
}
{
source := newSource(15)
out := TaintStepTest_IoPipeWriterWrite_B0I0O0(source)
sink(15, out)
}
{
source := newSource(16)
out := TaintStepTest_IoSectionReaderRead_B0I0O0(source)
sink(16, out)
}
{
source := newSource(17)
out := TaintStepTest_IoSectionReaderReadAt_B0I0O0(source)
sink(17, out)
}
{
source := newSource(18)
out := TaintStepTest_IoReaderRead_B0I0O0(source)
sink(18, out)
}
{
source := newSource(19)
out := TaintStepTest_IoReaderAtReadAt_B0I0O0(source)
sink(19, out)
}
{
source := newSource(20)
out := TaintStepTest_IoReaderFromReadFrom_B0I0O0(source)
sink(20, out)
}
{
source := newSource(21)
out := TaintStepTest_IoWriterWrite_B0I0O0(source)
sink(21, out)
}
{
source := newSource(22)
out := TaintStepTest_IoWriterAtWriteAt_B0I0O0(source)
sink(22, out)
}
{
source := newSource(23)
out := TaintStepTest_IoStringWriterWriteString_B0I0O0(source)
sink(23, out)
}
{
source := newSource(24)
out := TaintStepTest_IoWriterToWriteTo_B0I0O0(source)
sink(24, out)
}
}