mirror of
https://github.com/golang/go.git
synced 2025-05-06 08:03:03 +00:00
[release-branch.go1.21] cmd/go: disallow -lto_library in LDFLAGS
The darwin linker allows setting the LTO library with the -lto_library flag. This wasn't caught by our "safe linker flags" check because it was covered by the -lx flag used for linking libraries. This change adds a specific check for excluded flags which otherwise satisfy our existing checks. Loading a mallicious LTO library would allow an attacker to cause the linker to execute abritrary code when "go build" was called. Thanks to Juho Forsén of Mattermost for reporting this issue. Fixes #67119 Fixes #67121 Fixes CVE-2024-24787 Change-Id: I77ac8585efbdbdfd5f39c39ed623b9408a0f9eaf Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1380 Reviewed-by: Russ Cox <rsc@google.com> Reviewed-by: Damien Neil <dneil@google.com> (cherry picked from commit 9a79141fbbca1105e5c786f15e38741ca7843290) Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1401 Reviewed-by: Tatiana Bradley <tatianabradley@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/583795 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
78d89b2b67
commit
a79ea27e36
@ -141,6 +141,12 @@ var validCompilerFlagsWithNextArg = []string{
|
|||||||
"-x",
|
"-x",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var invalidLinkerFlags = []*lazyregexp.Regexp{
|
||||||
|
// On macOS this means the linker loads and executes the next argument.
|
||||||
|
// Have to exclude separately because -lfoo is allowed in general.
|
||||||
|
re(`-lto_library`),
|
||||||
|
}
|
||||||
|
|
||||||
var validLinkerFlags = []*lazyregexp.Regexp{
|
var validLinkerFlags = []*lazyregexp.Regexp{
|
||||||
re(`-F([^@\-].*)`),
|
re(`-F([^@\-].*)`),
|
||||||
re(`-l([^@\-].*)`),
|
re(`-l([^@\-].*)`),
|
||||||
@ -231,12 +237,12 @@ var validLinkerFlagsWithNextArg = []string{
|
|||||||
|
|
||||||
func checkCompilerFlags(name, source string, list []string) error {
|
func checkCompilerFlags(name, source string, list []string) error {
|
||||||
checkOverrides := true
|
checkOverrides := true
|
||||||
return checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
|
return checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkLinkerFlags(name, source string, list []string) error {
|
func checkLinkerFlags(name, source string, list []string) error {
|
||||||
checkOverrides := true
|
checkOverrides := true
|
||||||
return checkFlags(name, source, list, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
|
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkCompilerFlagsForInternalLink returns an error if 'list'
|
// checkCompilerFlagsForInternalLink returns an error if 'list'
|
||||||
@ -245,7 +251,7 @@ func checkLinkerFlags(name, source string, list []string) error {
|
|||||||
// external linker).
|
// external linker).
|
||||||
func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
|
func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
|
||||||
checkOverrides := false
|
checkOverrides := false
|
||||||
if err := checkFlags(name, source, list, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
|
if err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Currently the only flag on the allow list that causes problems
|
// Currently the only flag on the allow list that causes problems
|
||||||
@ -258,7 +264,7 @@ func checkCompilerFlagsForInternalLink(name, source string, list []string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkFlags(name, source string, list []string, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
|
func checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
|
||||||
// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
|
// Let users override rules with $CGO_CFLAGS_ALLOW, $CGO_CFLAGS_DISALLOW, etc.
|
||||||
var (
|
var (
|
||||||
allow *regexp.Regexp
|
allow *regexp.Regexp
|
||||||
@ -290,6 +296,11 @@ Args:
|
|||||||
if allow != nil && allow.FindString(arg) == arg {
|
if allow != nil && allow.FindString(arg) == arg {
|
||||||
continue Args
|
continue Args
|
||||||
}
|
}
|
||||||
|
for _, re := range invalid {
|
||||||
|
if re.FindString(arg) == arg { // must be complete match
|
||||||
|
goto Bad
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, re := range valid {
|
for _, re := range valid {
|
||||||
if re.FindString(arg) == arg { // must be complete match
|
if re.FindString(arg) == arg { // must be complete match
|
||||||
continue Args
|
continue Args
|
||||||
|
17
src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt
vendored
Normal file
17
src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[!GOOS:darwin] skip
|
||||||
|
[!cgo] skip
|
||||||
|
|
||||||
|
! go build
|
||||||
|
stderr 'invalid flag in #cgo LDFLAGS: -lto_library'
|
||||||
|
|
||||||
|
-- go.mod --
|
||||||
|
module ldflag
|
||||||
|
|
||||||
|
-- main.go --
|
||||||
|
package main
|
||||||
|
|
||||||
|
// #cgo CFLAGS: -flto
|
||||||
|
// #cgo LDFLAGS: -lto_library bad.dylib
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func main() {}
|
Loading…
x
Reference in New Issue
Block a user