mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Implement standard library models for Go 1.20
This commit is contained in:
@@ -65,6 +65,7 @@ import semmle.go.frameworks.stdlib.Syscall
|
||||
import semmle.go.frameworks.stdlib.TextScanner
|
||||
import semmle.go.frameworks.stdlib.TextTabwriter
|
||||
import semmle.go.frameworks.stdlib.TextTemplate
|
||||
import semmle.go.frameworks.stdlib.Unsafe
|
||||
|
||||
/** A `String()` method. */
|
||||
class StringMethod extends TaintTracking::FunctionModel, Method {
|
||||
|
||||
@@ -11,6 +11,15 @@ module Bytes {
|
||||
FunctionOutput outp;
|
||||
|
||||
FunctionModels() {
|
||||
hasQualifiedName("bytes", "Clone") and
|
||||
(inp.isParameter(0) and outp.isResult())
|
||||
or
|
||||
hasQualifiedName("bytes", "Cut") and
|
||||
(inp.isParameter(0) and outp.isResult([0, 1]))
|
||||
or
|
||||
hasQualifiedName("bytes", ["CutPrefix", "CutSuffix"]) and
|
||||
(inp.isParameter(0) and outp.isResult(0))
|
||||
or
|
||||
// signature: func Fields(s []byte) [][]byte
|
||||
hasQualifiedName("bytes", "Fields") and
|
||||
(inp.isParameter(0) and outp.isResult())
|
||||
|
||||
@@ -22,6 +22,10 @@ module Errors {
|
||||
// signature: func Unwrap(err error) error
|
||||
hasQualifiedName("errors", "Unwrap") and
|
||||
(inp.isParameter(0) and outp.isResult())
|
||||
or
|
||||
// signature: func Join(errs ...error) error
|
||||
hasQualifiedName("errors", "Join") and
|
||||
(inp.isParameter(_) and outp.isResult())
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
|
||||
@@ -11,6 +11,9 @@ module Sync {
|
||||
FunctionOutput outp;
|
||||
|
||||
MethodModels() {
|
||||
hasQualifiedName("sync", "Map", "CompareAndSwap") and
|
||||
(inp.isParameter(2) and outp.isReceiver())
|
||||
or
|
||||
// signature: func (*Map) Load(key interface{}) (value interface{}, ok bool)
|
||||
hasQualifiedName("sync", "Map", "Load") and
|
||||
(inp.isReceiver() and outp.isResult(0))
|
||||
@@ -28,6 +31,13 @@ module Sync {
|
||||
hasQualifiedName("sync", "Map", "Store") and
|
||||
(inp.isParameter(_) and outp.isReceiver())
|
||||
or
|
||||
hasQualifiedName("sync", "Map", "Swap") and
|
||||
(
|
||||
inp.isReceiver() and outp.isResult(0)
|
||||
or
|
||||
inp.isParameter(_) and outp.isReceiver()
|
||||
)
|
||||
or
|
||||
// signature: func (*Pool) Get() interface{}
|
||||
hasQualifiedName("sync", "Pool", "Get") and
|
||||
(inp.isReceiver() and outp.isResult())
|
||||
|
||||
22
go/ql/lib/semmle/go/frameworks/stdlib/Unsafe.qll
Normal file
22
go/ql/lib/semmle/go/frameworks/stdlib/Unsafe.qll
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `unsafe` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/** Provides models of commonly used functions in the `unsafe` package. */
|
||||
module Unsafe {
|
||||
private class FunctionModels extends TaintTracking::FunctionModel {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
FunctionModels() {
|
||||
hasQualifiedName("unsafe", ["String", "StringData", "Slice", "SliceData"]) and
|
||||
(inp.isParameter(0) and outp.isResult())
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,6 +316,39 @@ func TaintStepTest_BytesReaderWriteTo_B0I0O0(sourceCQL interface{}) interface{}
|
||||
return intoWriter197
|
||||
}
|
||||
|
||||
func TaintStepTest_Clone(sourceCQL interface{}) interface{} {
|
||||
fromReader628 := sourceCQL.([]byte)
|
||||
return bytes.Clone(fromReader628)
|
||||
}
|
||||
|
||||
func TaintStepTest_Cutleft(sourceCQL interface{}) interface{} {
|
||||
fromReader628 := sourceCQL.([]byte)
|
||||
sep := []byte{}
|
||||
left, _, _ := bytes.Cut(fromReader628, sep)
|
||||
return left
|
||||
}
|
||||
|
||||
func TaintStepTest_Cutright(sourceCQL interface{}) interface{} {
|
||||
fromReader628 := sourceCQL.([]byte)
|
||||
sep := []byte{}
|
||||
_, right, _ := bytes.Cut(fromReader628, sep)
|
||||
return right
|
||||
}
|
||||
|
||||
func TaintStepTest_CutPrefix(sourceCQL interface{}) interface{} {
|
||||
fromReader628 := sourceCQL.([]byte)
|
||||
sep := []byte{}
|
||||
result, _ := bytes.CutPrefix(fromReader628, sep)
|
||||
return result
|
||||
}
|
||||
|
||||
func TaintStepTest_CutSuffix(sourceCQL interface{}) interface{} {
|
||||
fromReader628 := sourceCQL.([]byte)
|
||||
sep := []byte{}
|
||||
result, _ := bytes.CutSuffix(fromReader628, sep)
|
||||
return result
|
||||
}
|
||||
|
||||
func RunAllTaints_Bytes() {
|
||||
{
|
||||
source := newSource(0)
|
||||
@@ -567,4 +600,29 @@ func RunAllTaints_Bytes() {
|
||||
out := TaintStepTest_BytesReaderWriteTo_B0I0O0(source)
|
||||
sink(49, out)
|
||||
}
|
||||
{
|
||||
source := newSource(50)
|
||||
out := TaintStepTest_Cutleft(source)
|
||||
sink(50, out)
|
||||
}
|
||||
{
|
||||
source := newSource(51)
|
||||
out := TaintStepTest_Cutright(source)
|
||||
sink(51, out)
|
||||
}
|
||||
{
|
||||
source := newSource(52)
|
||||
out := TaintStepTest_CutPrefix(source)
|
||||
sink(52, out)
|
||||
}
|
||||
{
|
||||
source := newSource(53)
|
||||
out := TaintStepTest_CutSuffix(source)
|
||||
sink(53, out)
|
||||
}
|
||||
{
|
||||
source := newSource(54)
|
||||
out := TaintStepTest_Clone(source)
|
||||
sink(54, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,18 @@ func TaintStepTest_ErrorsUnwrap_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
return intoError957
|
||||
}
|
||||
|
||||
func TaintStepTest_ErrorsJoin1(sourceCQL interface{}) interface{} {
|
||||
fromError784 := sourceCQL.(error)
|
||||
intoError957 := errors.Join(fromError784, errors.New(""))
|
||||
return intoError957
|
||||
}
|
||||
|
||||
func TaintStepTest_ErrorsJoin2(sourceCQL interface{}) interface{} {
|
||||
fromError784 := sourceCQL.(error)
|
||||
intoError957 := errors.Join(errors.New(""), fromError784)
|
||||
return intoError957
|
||||
}
|
||||
|
||||
func RunAllTaints_Errors() {
|
||||
{
|
||||
source := newSource(0)
|
||||
@@ -39,4 +51,14 @@ func RunAllTaints_Errors() {
|
||||
out := TaintStepTest_ErrorsUnwrap_B0I0O0(source)
|
||||
sink(2, out)
|
||||
}
|
||||
{
|
||||
source := newSource(3)
|
||||
out := TaintStepTest_ErrorsJoin1(source)
|
||||
sink(3, out)
|
||||
}
|
||||
{
|
||||
source := newSource(4)
|
||||
out := TaintStepTest_ErrorsJoin2(source)
|
||||
sink(4, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,30 @@ func TaintStepTest_SyncMapStore_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
return intoMap881
|
||||
}
|
||||
|
||||
func TaintStepTest_SyncMapSwapinkey(sourceCQL interface{}) interface{} {
|
||||
var m sync.Map
|
||||
m.Swap(sourceCQL, "value")
|
||||
return m
|
||||
}
|
||||
|
||||
func TaintStepTest_SyncMapSwapinvalue(sourceCQL interface{}) interface{} {
|
||||
var m sync.Map
|
||||
m.Swap("key", sourceCQL)
|
||||
return m
|
||||
}
|
||||
|
||||
func TaintStepTest_SyncMapSwapout(sourceCQL interface{}) interface{} {
|
||||
m := sourceCQL.(sync.Map)
|
||||
oldVal, _ := m.Swap("key", "value")
|
||||
return oldVal
|
||||
}
|
||||
|
||||
func TaintStepTest_SyncMapCompareAndSwap(sourceCQL interface{}) interface{} {
|
||||
var m sync.Map
|
||||
m.CompareAndSwap("key", "compareTo", sourceCQL)
|
||||
return m
|
||||
}
|
||||
|
||||
func TaintStepTest_SyncPoolGet_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromPool186 := sourceCQL.(sync.Pool)
|
||||
intoInterface284 := fromPool186.Get()
|
||||
@@ -122,4 +146,24 @@ func RunAllTaints_Sync() {
|
||||
out := TaintStepTest_SyncPoolPut_B0I0O0(source)
|
||||
sink(9, out)
|
||||
}
|
||||
{
|
||||
source := newSource(10)
|
||||
out := TaintStepTest_SyncMapSwapinkey(source)
|
||||
sink(10, out)
|
||||
}
|
||||
{
|
||||
source := newSource(11)
|
||||
out := TaintStepTest_SyncMapSwapinvalue(source)
|
||||
sink(11, out)
|
||||
}
|
||||
{
|
||||
source := newSource(12)
|
||||
out := TaintStepTest_SyncMapSwapout(source)
|
||||
sink(12, out)
|
||||
}
|
||||
{
|
||||
source := newSource(13)
|
||||
out := TaintStepTest_SyncMapCompareAndSwap(source)
|
||||
sink(13, out)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func TaintStepTest_UnsafeSlice(sourceCQL interface{}) interface{} {
|
||||
s := sourceCQL.(*byte)
|
||||
return unsafe.Slice(s, 1)
|
||||
}
|
||||
|
||||
func TaintStepTest_UnsafeSliceData(sourceCQL interface{}) interface{} {
|
||||
s := sourceCQL.([]byte)
|
||||
return unsafe.SliceData(s)
|
||||
}
|
||||
|
||||
func TaintStepTest_UnsafeString(sourceCQL interface{}) interface{} {
|
||||
s := sourceCQL.(*byte)
|
||||
return unsafe.String(s, 1)
|
||||
}
|
||||
|
||||
func TaintStepTest_UnsafeStringData(sourceCQL interface{}) interface{} {
|
||||
s := sourceCQL.(string)
|
||||
return unsafe.StringData(s)
|
||||
}
|
||||
|
||||
func RunAllTaints_Sync() {
|
||||
{
|
||||
source := newSource(0)
|
||||
out := TaintStepTest_UnsafeSlice(source)
|
||||
sink(0, out)
|
||||
}
|
||||
{
|
||||
source := newSource(1)
|
||||
out := TaintStepTest_UnsafeSliceData(source)
|
||||
sink(1, out)
|
||||
}
|
||||
{
|
||||
source := newSource(2)
|
||||
out := TaintStepTest_UnsafeString(source)
|
||||
sink(2, out)
|
||||
}
|
||||
{
|
||||
source := newSource(3)
|
||||
out := TaintStepTest_UnsafeStringData(source)
|
||||
sink(3, out)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user