diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
index 270a34e9c7cf7fbd689f85114c6a1d0f87b434d6..db49eb6488c4f860cdee8ef54590cc118bf9109e 100644
--- a/src/cmd/go/internal/work/security.go
+++ b/src/cmd/go/internal/work/security.go
@@ -141,6 +141,12 @@ var validCompilerFlagsWithNextArg = []string{
 	"-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{
 	re(`-F([^@\-].*)`),
 	re(`-l([^@\-].*)`),
@@ -231,12 +237,12 @@ var validLinkerFlagsWithNextArg = []string{
 
 func checkCompilerFlags(name, source string, list []string) error {
 	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 {
 	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'
@@ -245,7 +251,7 @@ func checkLinkerFlags(name, source string, list []string) error {
 // external linker).
 func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
 	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
 	}
 	// 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
 }
 
-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.
 	var (
 		allow    *regexp.Regexp
@@ -290,6 +296,11 @@ Args:
 		if allow != nil && allow.FindString(arg) == arg {
 			continue Args
 		}
+		for _, re := range invalid {
+			if re.FindString(arg) == arg { // must be complete match
+				goto Bad
+			}
+		}
 		for _, re := range valid {
 			if re.FindString(arg) == arg { // must be complete match
 				continue Args
diff --git a/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt b/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d7acefdbad63864c7628a7812dd520b405675dab
--- /dev/null
+++ b/src/cmd/go/testdata/script/darwin_lto_library_ldflag.txt
@@ -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() {}
\ No newline at end of file