Merge pull request #18034 from owen-mc/go/mad/package-level-variables

Go: Allow package-level variables in models-as-data models
This commit is contained in:
Owen Mansel-Chan 2024-11-19 19:49:02 +00:00 коммит произвёл GitHub
Родитель 5a18f1ff07 dd87b1a9de
Коммит f21439a6e3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
18 изменённых файлов: 48 добавлений и 12 удалений

Просмотреть файл

@ -53,6 +53,7 @@ extensions:
- ["os", "", False, "Open", "", "", "ReturnValue[0]", "file", "manual"]
- ["os", "", False, "OpenFile", "", "", "ReturnValue[0]", "file", "manual"]
- ["os", "", False, "ReadFile", "", "", "ReturnValue[0]", "file", "manual"]
- ["os", "", False, "Stdin", "", "", "", "stdin", "manual"]
- ["os", "", False, "UserCacheDir", "", "", "ReturnValue[0]", "environment", "manual"]
- ["os", "", False, "UserConfigDir", "", "", "ReturnValue[0]", "environment", "manual"]
- ["os", "", False, "UserHomeDir", "", "", "ReturnValue[0]", "environment", "manual"]

Просмотреть файл

@ -38,7 +38,8 @@
* first 6 columns, and the `output` column specifies how data leaves the
* element selected by the first 6 columns. An `input` can be either "",
* "Argument[n]", or "Argument[n1..n2]":
* - "": Selects a write to the selected element in case this is a field.
* - "": Selects a write to the selected element in case this is a field or
* package-level variable.
* - "Argument[n]": Selects an argument in a call to the selected element.
* The arguments are zero-indexed, and `receiver` specifies the receiver.
* - "Argument[n1..n2]": Similar to "Argument[n]" but selects any argument
@ -47,7 +48,7 @@
* An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter",
* "Parameter[n]", "Parameter[n1..n2]", , "ReturnValue", "ReturnValue[n]", or
* "ReturnValue[n1..n2]":
* - "": Selects a read of a selected field.
* - "": Selects a read of a selected field or package-level variable.
* - "Argument[n]": Selects the post-update value of an argument in a call to the
* selected element. That is, the value of the argument after the call returns.
* The arguments are zero-indexed, and `receiver` specifies the receiver.

Просмотреть файл

@ -399,6 +399,13 @@ module SourceSinkInterpretationInput implements
c = "" and
pragma[only_bind_into](e) = getElementWithQualifier(frn.getField(), frn.getBase())
)
or
// A package-scope (or universe-scope) variable
exists(Variable v | not v instanceof Field |
c = "" and
n.(DataFlow::ReadNode).reads(v) and
pragma[only_bind_into](e).asEntity() = v
)
)
}
@ -420,6 +427,17 @@ module SourceSinkInterpretationInput implements
fw.writesField(base, f, node.asNode()) and
pragma[only_bind_into](e) = getElementWithQualifier(f, base)
)
or
// A package-scope (or universe-scope) variable
exists(Node n, SourceOrSinkElement e, DataFlow::Write w, Variable v |
n = node.asNode() and
e = mid.asElement() and
not v instanceof Field
|
c = "" and
w.writes(v, n) and
pragma[only_bind_into](e).asEntity() = v
)
}
}

Просмотреть файл

@ -43,12 +43,4 @@ module Os {
input = inp and output = outp
}
}
private class Stdin extends SourceNode {
Stdin() {
exists(Variable osStdin | osStdin.hasQualifiedName("os", "Stdin") | this = osStdin.getARead())
}
override string getThreatModel() { result = "stdin" }
}
}

Просмотреть файл

@ -35,10 +35,12 @@ extensions:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data:
- ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"]

Просмотреть файл

@ -43,3 +43,4 @@ invalidModelRow
| test.go:199:17:199:20 | arg1 | qltest |
| test.go:199:23:199:26 | arg2 | qltest |
| test.go:199:29:199:32 | arg3 | qltest |
| test.go:202:22:202:25 | temp | qltest |

Просмотреть файл

@ -3,6 +3,7 @@ extensions:
pack: codeql/go-all
extensible: sinkModel
data:
- ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkMethod", "", "", "Argument[receiver]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"]

Просмотреть файл

@ -21,3 +21,4 @@ invalidModelRow
| test.go:183:17:183:24 | call to Src1 | qltest |
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:201:10:201:28 | selection of SourceVariable | qltest |

Просмотреть файл

@ -3,9 +3,10 @@ extensions:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src2", "", "", "ReturnValue", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src2", "", "", "ReturnValue", "qltest-w-subtypes", "manual"]
- ["github.com/nonexistent/test", "A", False, "SrcArg", "", "", "Argument[0]", "qltest-arg", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src3", "", "", "ReturnValue[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]

Просмотреть файл

@ -197,6 +197,9 @@ func simpleflow() {
arg3 := src
arg4 := src
b.SinkManyArgs(arg1, arg2, arg3, arg4) // $ hasTaintFlow="arg1" hasTaintFlow="arg2" hasTaintFlow="arg3"
temp := test.SourceVariable
test.SinkVariable = temp // $ hasTaintFlow="temp"
}
type mapstringstringtype map[string]string

Просмотреть файл

@ -72,3 +72,6 @@ func (c C) Get() string { return "" }
func (c *C) SetThroughPointer(f string) {}
func (c *C) GetThroughPointer() string { return "" }
var SourceVariable string
var SinkVariable string

Просмотреть файл

@ -35,10 +35,12 @@ extensions:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
data:
- ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"]

Просмотреть файл

@ -49,3 +49,4 @@ invalidModelRow
| test.go:205:10:205:26 | call to min | qltest |
| test.go:206:10:206:26 | call to min | qltest |
| test.go:207:10:207:26 | call to min | qltest |
| test.go:210:22:210:25 | temp | qltest |

Просмотреть файл

@ -3,6 +3,7 @@ extensions:
pack: codeql/go-all
extensible: sinkModel
data:
- ["github.com/nonexistent/test", "", False, "SinkVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "Sink1", "", "", "Argument[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkMethod", "", "", "Argument[receiver]", "qltest", "manual"]
- ["github.com/nonexistent/test", "B", False, "SinkManyArgs", "", "", "Argument[0..2]", "qltest", "manual"]

Просмотреть файл

@ -21,3 +21,4 @@ invalidModelRow
| test.go:183:17:183:24 | call to Src1 | qltest |
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:209:10:209:28 | selection of SourceVariable | qltest |

Просмотреть файл

@ -3,9 +3,10 @@ extensions:
pack: codeql/go-all
extensible: sourceModel
data:
- ["github.com/nonexistent/test", "", False, "SourceVariable", "", "", "", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src1", "", "", "ReturnValue", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src2", "", "", "ReturnValue", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src2", "", "", "ReturnValue", "qltest-w-subtypes", "manual"]
- ["github.com/nonexistent/test", "A", False, "SrcArg", "", "", "Argument[0]", "qltest-arg", "manual"]
- ["github.com/nonexistent/test", "A", False, "Src3", "", "", "ReturnValue[0]", "qltest", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]
- ["github.com/nonexistent/test", "A", True, "Src3", "", "", "ReturnValue[1]", "qltest-w-subtypes", "manual"]

Просмотреть файл

@ -205,6 +205,9 @@ func simpleflow() {
b.Sink1(min(srcInt, 0, 1)) // $ hasValueFlow="call to min"
b.Sink1(min(0, srcInt, 1)) // $ hasValueFlow="call to min"
b.Sink1(min(0, 1, srcInt)) // $ hasValueFlow="call to min"
temp := test.SourceVariable
test.SinkVariable = temp // $ hasValueFlow="temp"
}
type mapstringstringtype map[string]string

Просмотреть файл

@ -72,3 +72,6 @@ func (c C) Get() string { return "" }
func (c *C) SetThroughPointer(f string) {}
func (c *C) GetThroughPointer() string { return "" }
var SourceVariable string
var SinkVariable string