diff --git a/go/ql/lib/ext/context.model.yml b/go/ql/lib/ext/context.model.yml index b71adeb6b3c7..5df5cb6d6295 100644 --- a/go/ql/lib/ext/context.model.yml +++ b/go/ql/lib/ext/context.model.yml @@ -3,8 +3,14 @@ extensions: pack: codeql/go-all extensible: summaryModel data: + # AfterFunc should be modeled when callback-based library models are supported. - ["context", "", False, "WithCancel", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] - ["context", "", False, "WithDeadline", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithDeadlineCause", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithDeadlineCause", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] - ["context", "", False, "WithTimeout", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithTimeoutCause", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["context", "", False, "WithTimeoutCause", "", "", "Argument[2]", "ReturnValue[0]", "taint", "manual"] - ["context", "", False, "WithValue", "", "", "Argument[0..2]", "ReturnValue", "taint", "manual"] + - ["context", "", False, "WithoutCancel", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["context", "Context", True, "Value", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] diff --git a/go/ql/lib/ext/crypto.tls.model.yml b/go/ql/lib/ext/crypto.tls.model.yml index ecb4c8859946..6ec868eebed8 100644 --- a/go/ql/lib/ext/crypto.tls.model.yml +++ b/go/ql/lib/ext/crypto.tls.model.yml @@ -4,5 +4,19 @@ extensions: extensible: summaryModel data: - ["crypto/tls", "", False, "Client", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "", False, "NewResumptionState", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] - ["crypto/tls", "", False, "NewListener", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "", False, "ParseSessionState", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/tls", "", False, "QUICClient", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "", False, "QUICServer", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["crypto/tls", "", False, "Server", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "ClientSessionState", True, "ResumptionState", "", "", "Argument[receiver]", "ReturnValue[0..1]", "taint", "manual"] + - ["crypto/tls", "Config", True, "DecryptTicket", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/tls", "Config", True, "DecryptTicket", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/tls", "Config", True, "EncryptTicket", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/tls", "Config", True, "EncryptTicket", "", "", "Argument[0..1]", "ReturnValue[0]", "taint", "manual"] + - ["crypto/tls", "QUICConn", True, "ConnectionState", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "QUICConn", True, "HandleData", "", "", "Argument[1]", "Argument[receiver]", "taint", "manual"] + - ["crypto/tls", "QUICConn", True, "NextEvent", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"] + - ["crypto/tls", "QUICConn", True, "SetTransportParameters", "", "", "Argument[0]", "Argument[receiver]", "taint", "manual"] + - ["crypto/tls", "SessionState", True, "Bytes", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/io.fs.model.yml b/go/ql/lib/ext/io.fs.model.yml index 1b9be01aba91..6d8c14253dda 100644 --- a/go/ql/lib/ext/io.fs.model.yml +++ b/go/ql/lib/ext/io.fs.model.yml @@ -4,6 +4,8 @@ extensions: extensible: summaryModel data: - ["io/fs", "", False, "FileInfoToDirEntry", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io/fs", "", False, "FormatDirEntry", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io/fs", "", False, "FormatFileInfo", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io/fs", "", False, "Glob", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] - ["io/fs", "", False, "ReadDir", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] - ["io/fs", "", False, "ReadFile", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/lib/ext/math.big.model.yml b/go/ql/lib/ext/math.big.model.yml index dc09561897c9..1f7ff4ee8c08 100644 --- a/go/ql/lib/ext/math.big.model.yml +++ b/go/ql/lib/ext/math.big.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/go-all extensible: summaryModel data: + - ["math/big", "Int", True, "Float64", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"] - ["math/big", "Int", True, "Int64", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"] diff --git a/go/ql/src/change-notes/2026-09-30-model-go1.21-minor-library-changes.md b/go/ql/src/change-notes/2026-09-30-model-go1.21-minor-library-changes.md new file mode 100644 index 000000000000..38fcf403bb04 --- /dev/null +++ b/go/ql/src/change-notes/2026-09-30-model-go1.21-minor-library-changes.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added data flow models for APIs mentioned in the minor library changes section of the Go 1.21 release notes. diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Context.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Context.go index 5b526f3b8c0a..bce42b1ca3fa 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Context.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Context.go @@ -26,6 +26,35 @@ func TaintStepTest_ContextWithTimeout_B0I0O0(sourceCQL interface{}) interface{} return intoContext957 } +func TaintStepTest_ContextWithDeadlineCauseContext(sourceCQL interface{}) interface{} { + fromContext := sourceCQL.(context.Context) + intoContext, _ := context.WithDeadlineCause(fromContext, time.Time{}, nil) + return intoContext +} + +func TaintStepTest_ContextWithDeadlineCauseError(sourceCQL interface{}) interface{} { + fromError := sourceCQL.(error) + intoContext, _ := context.WithDeadlineCause(nil, time.Time{}, fromError) + return intoContext +} + +func TaintStepTest_ContextWithTimeoutCauseContext(sourceCQL interface{}) interface{} { + fromContext := sourceCQL.(context.Context) + intoContext, _ := context.WithTimeoutCause(fromContext, 0, nil) + return intoContext +} + +func TaintStepTest_ContextWithTimeoutCauseError(sourceCQL interface{}) interface{} { + fromError := sourceCQL.(error) + intoContext, _ := context.WithTimeoutCause(nil, 0, fromError) + return intoContext +} + +func TaintStepTest_ContextWithoutCancel(sourceCQL interface{}) interface{} { + fromContext := sourceCQL.(context.Context) + return context.WithoutCancel(fromContext) +} + func TaintStepTest_ContextWithValue_B0I0O0(sourceCQL interface{}) interface{} { fromContext520 := sourceCQL.(context.Context) intoContext443 := context.WithValue(fromContext520, nil, nil) @@ -163,4 +192,29 @@ func RunAllTaints_Context() { out := TaintStepTest_OldContextContextValue_B0I0O0(source) sink(13, out) } + { + source := newSource(14) + out := TaintStepTest_ContextWithDeadlineCauseContext(source) + sink(14, out) + } + { + source := newSource(15) + out := TaintStepTest_ContextWithDeadlineCauseError(source) + sink(15, out) + } + { + source := newSource(16) + out := TaintStepTest_ContextWithTimeoutCauseContext(source) + sink(16, out) + } + { + source := newSource(17) + out := TaintStepTest_ContextWithTimeoutCauseError(source) + sink(17, out) + } + { + source := newSource(18) + out := TaintStepTest_ContextWithoutCancel(source) + sink(18, out) + } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go index a35f30a1a991..2a5c81c651f0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go @@ -55,6 +55,71 @@ func TaintStepTest_CryptoTlsConnWrite_B0I0O0(sourceCQL interface{}) interface{} return intoConn584 } +func TaintStepTest_CryptoTlsSessionStateBytes(sourceCQL interface{}) interface{} { + out, _ := sourceCQL.(*tls.SessionState).Bytes() + return out +} + +func TaintStepTest_CryptoTlsParseSessionState(sourceCQL interface{}) interface{} { + out, _ := tls.ParseSessionState(sourceCQL.([]byte)) + return out +} + +func TaintStepTest_CryptoTlsNewResumptionStateTicket(sourceCQL interface{}) interface{} { + out, _ := tls.NewResumptionState(sourceCQL.([]byte), nil) + return out +} + +func TaintStepTest_CryptoTlsNewResumptionStateState(sourceCQL interface{}) interface{} { + out, _ := tls.NewResumptionState(nil, sourceCQL.(*tls.SessionState)) + return out +} + +func TaintStepTest_CryptoTlsClientSessionStateResumptionState(sourceCQL interface{}) interface{} { + ticket, _, _ := sourceCQL.(*tls.ClientSessionState).ResumptionState() + return ticket +} + +func TaintStepTest_CryptoTlsConfigEncryptTicketState(sourceCQL interface{}) interface{} { + var config tls.Config + out, _ := config.EncryptTicket(tls.ConnectionState{}, sourceCQL.(*tls.SessionState)) + return out +} + +func TaintStepTest_CryptoTlsConfigDecryptTicket(sourceCQL interface{}) interface{} { + var config tls.Config + out, _ := config.DecryptTicket(sourceCQL.([]byte), tls.ConnectionState{}) + return out +} + +func TaintStepTest_CryptoTlsQUICClient(sourceCQL interface{}) interface{} { + return tls.QUICClient(sourceCQL.(*tls.QUICConfig)) +} + +func TaintStepTest_CryptoTlsQUICServer(sourceCQL interface{}) interface{} { + return tls.QUICServer(sourceCQL.(*tls.QUICConfig)) +} + +func TaintStepTest_CryptoTlsQUICConnHandleData(sourceCQL interface{}) interface{} { + conn := tls.QUICClient(&tls.QUICConfig{}) + conn.HandleData(tls.QUICEncryptionLevelInitial, sourceCQL.([]byte)) + return conn +} + +func TaintStepTest_CryptoTlsQUICConnNextEvent(sourceCQL interface{}) interface{} { + return sourceCQL.(*tls.QUICConn).NextEvent() +} + +func TaintStepTest_CryptoTlsQUICConnConnectionState(sourceCQL interface{}) interface{} { + return sourceCQL.(*tls.QUICConn).ConnectionState() +} + +func TaintStepTest_CryptoTlsQUICConnSetTransportParameters(sourceCQL interface{}) interface{} { + conn := tls.QUICClient(&tls.QUICConfig{}) + conn.SetTransportParameters(sourceCQL.([]byte)) + return conn +} + func RunAllTaints_CryptoTls() { { source := newSource(0) @@ -91,4 +156,69 @@ func RunAllTaints_CryptoTls() { out := TaintStepTest_CryptoTlsConnWrite_B0I0O0(source) sink(6, out) } + { + source := newSource(8) + out := TaintStepTest_CryptoTlsSessionStateBytes(source) + sink(8, out) + } + { + source := newSource(9) + out := TaintStepTest_CryptoTlsParseSessionState(source) + sink(9, out) + } + { + source := newSource(10) + out := TaintStepTest_CryptoTlsNewResumptionStateTicket(source) + sink(10, out) + } + { + source := newSource(11) + out := TaintStepTest_CryptoTlsNewResumptionStateState(source) + sink(11, out) + } + { + source := newSource(12) + out := TaintStepTest_CryptoTlsClientSessionStateResumptionState(source) + sink(12, out) + } + { + source := newSource(13) + out := TaintStepTest_CryptoTlsConfigEncryptTicketState(source) + sink(13, out) + } + { + source := newSource(14) + out := TaintStepTest_CryptoTlsConfigDecryptTicket(source) + sink(14, out) + } + { + source := newSource(15) + out := TaintStepTest_CryptoTlsQUICClient(source) + sink(15, out) + } + { + source := newSource(16) + out := TaintStepTest_CryptoTlsQUICServer(source) + sink(16, out) + } + { + source := newSource(17) + out := TaintStepTest_CryptoTlsQUICConnHandleData(source) + sink(17, out) + } + { + source := newSource(18) + out := TaintStepTest_CryptoTlsQUICConnNextEvent(source) + sink(18, out) + } + { + source := newSource(19) + out := TaintStepTest_CryptoTlsQUICConnConnectionState(source) + sink(19, out) + } + { + source := newSource(20) + out := TaintStepTest_CryptoTlsQUICConnSetTransportParameters(source) + sink(20, out) + } } diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/IoFs.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/IoFs.go index 4b9102008413..e6db16aee2e0 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/IoFs.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/IoFs.go @@ -11,6 +11,16 @@ func walkDirCallback(path string, d fs.DirEntry, _ error) error { } func steps() { + { + source := newSource(17).(fs.DirEntry) + out := fs.FormatDirEntry(source) + sink(17, out) + } + { + source := newSource(18).(fs.FileInfo) + out := fs.FormatFileInfo(source) + sink(18, out) + } { source := newSource(16).(fs.FileInfo) out := fs.FileInfoToDirEntry(source) diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MathBig.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MathBig.go new file mode 100644 index 000000000000..0be95bb7b223 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MathBig.go @@ -0,0 +1,14 @@ +package main + +import "math/big" + +func TaintStepTest_MathBigIntFloat64(sourceCQL interface{}) interface{} { + out, _ := sourceCQL.(*big.Int).Float64() + return out +} + +func RunAllTaints_MathBig() { + source := newSource(0) + out := TaintStepTest_MathBigIntFloat64(source) + sink(0, out) +}