Add a taint-tracking model for copy.

This commit is contained in:
Max Schaefer
2020-03-05 11:55:46 +00:00
parent 3f8d2117d8
commit 4f061005cb
5 changed files with 89 additions and 1 deletions

View File

@@ -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
}
}

View File

@@ -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. */

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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)
}