mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Add a taint-tracking model for copy.
This commit is contained in:
@@ -97,9 +97,18 @@ private newtype TFunctionOutput =
|
||||
// one among several results
|
||||
exists(SignatureType s | exists(s.getResultType(index)))
|
||||
}
|
||||
or
|
||||
TOutParameter(int index) {
|
||||
// the receiver parameter
|
||||
index = -1
|
||||
or
|
||||
// another parameter
|
||||
exists(SignatureType s | exists(s.getParameterType(index)))
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract representation of an output of a function, which is one of its results.
|
||||
* An abstract representation of an output of a function, which is one of its results
|
||||
* or a parameter with mutable type.
|
||||
*/
|
||||
class FunctionOutput extends TFunctionOutput {
|
||||
/** Holds if this represents the (single) result of a function. */
|
||||
@@ -112,6 +121,16 @@ class FunctionOutput extends TFunctionOutput {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if this represents the receiver of a function. */
|
||||
predicate isReceiver() {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Holds if this represents the `i`th parameter of a function. */
|
||||
predicate isParameter(int i) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Gets the data-flow node corresponding to this output for the call `c`. */
|
||||
final DataFlow::Node getNode(DataFlow::CallNode c) { result = getExitNode(c) }
|
||||
|
||||
@@ -176,3 +195,39 @@ private class OutResult extends FunctionOutput, TOutResult {
|
||||
index >= 0 and result = "result " + index
|
||||
}
|
||||
}
|
||||
|
||||
/** A result position of a function, viewed as an output. */
|
||||
private class OutParameter extends FunctionOutput, TOutParameter {
|
||||
int index;
|
||||
|
||||
OutParameter() {
|
||||
this = TOutParameter(index)
|
||||
}
|
||||
|
||||
override predicate isReceiver() {
|
||||
index = -1
|
||||
}
|
||||
|
||||
override predicate isParameter(int i) {
|
||||
i = index and i >= 0
|
||||
}
|
||||
|
||||
override DataFlow::Node getEntryNode(FuncDef f) {
|
||||
// there is no generic way of assigning to a parameter; operations that taint a parameter
|
||||
// have to be handled on a case-by-case basis
|
||||
none()
|
||||
}
|
||||
|
||||
override DataFlow::Node getExitNode(DataFlow::CallNode c) {
|
||||
exists(DataFlow::ArgumentNode arg |
|
||||
arg.argumentOf(c.asExpr(), index) and
|
||||
result.(DataFlow::PostUpdateNode).getPreUpdateNode() = arg
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
index = -1 and result = "result"
|
||||
or
|
||||
index >= 0 and result = "result " + index
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,18 @@ class StringMethod extends TaintTracking::FunctionModel, Method {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A model of the built-in `copy` function, which propagates taint from its second argument
|
||||
* to its first.
|
||||
*/
|
||||
private class CopyFunction extends TaintTracking::FunctionModel {
|
||||
CopyFunction() { this = Builtin::copy() }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp.isParameter(1) and outp.isParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides models of commonly used functions in the `path/filepath` package. */
|
||||
module PathFilePath {
|
||||
/** A path-manipulating function in the `path/filepath` package. */
|
||||
|
||||
@@ -37,6 +37,18 @@
|
||||
| main.go:34:2:34:6 | test1 | main.go:3:6:3:10 | function test1 |
|
||||
| main.go:34:8:34:12 | test2 | main.go:14:6:14:10 | function test2 |
|
||||
| main.go:34:19:34:23 | test2 | main.go:14:6:14:10 | function test2 |
|
||||
| main.go:38:2:38:2 | definition of s | main.go:39:15:39:15 | s |
|
||||
| main.go:38:2:38:2 | definition of s | main.go:40:15:40:15 | s |
|
||||
| main.go:38:2:38:2 | definition of s | main.go:42:7:42:7 | s |
|
||||
| main.go:38:7:38:20 | composite literal | main.go:38:2:38:2 | definition of s |
|
||||
| main.go:39:2:39:3 | definition of s1 | main.go:40:18:40:19 | s1 |
|
||||
| main.go:39:8:39:13 | append | file://:0:0:0:0 | function append |
|
||||
| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | definition of s1 |
|
||||
| main.go:40:8:40:13 | append | file://:0:0:0:0 | function append |
|
||||
| main.go:41:2:41:3 | definition of s4 | main.go:42:10:42:11 | s4 |
|
||||
| main.go:41:8:41:11 | make | file://:0:0:0:0 | function make |
|
||||
| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | definition of s4 |
|
||||
| main.go:42:2:42:5 | copy | file://:0:0:0:0 | function copy |
|
||||
| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | definition of s |
|
||||
| strings.go:8:12:8:12 | definition of s | strings.go:9:24:9:24 | s |
|
||||
| strings.go:8:12:8:12 | definition of s | strings.go:10:27:10:27 | s |
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[0] |
|
||||
| main.go:26:11:26:17 | type assertion | main.go:26:2:26:17 | ... := ...[1] |
|
||||
| main.go:42:10:42:11 | s4 | main.go:38:2:38:2 | definition of s |
|
||||
| strings.go:9:24:9:24 | s | strings.go:9:8:9:38 | call to Replace |
|
||||
| strings.go:9:32:9:34 | "_" | strings.go:9:8:9:38 | call to Replace |
|
||||
| strings.go:10:27:10:27 | s | strings.go:10:8:10:42 | call to ReplaceAll |
|
||||
|
||||
@@ -33,3 +33,11 @@ func test3(b bool, x interface{}) string {
|
||||
func main() {
|
||||
test1(test2()(), test2())
|
||||
}
|
||||
|
||||
func test9() {
|
||||
s := []int{1, 2, 3}
|
||||
s1 := append(s, 4, 5, 6)
|
||||
s2 := append(s, s1...)
|
||||
s4 := make([]int, 4)
|
||||
copy(s, s4)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user