Skip to content
Snippets Groups Projects
Commit c43ac38b authored by Roland Shoemaker's avatar Roland Shoemaker Committed by Cherry Mui
Browse files

[release-branch.go1.24] Revert "cmd/go/internal/work: allow @ character in...

[release-branch.go1.24] Revert "cmd/go/internal/work: allow @ character in some -Wl, linker flags on darwin"

This reverts commit e3cd55e9.

This change introduced a security issue as @ flags are first resolved as
files by the darwin linker, before their meaning as flags, allowing the
flag filtering logic to be entirely bypassed.

Thanks to Juho Forsén for reporting this issue.

Fixes #71476
Fixes CVE-2025-22867

Change-Id: I3a4b4a6fc534de105d930b8ed5b9900bc94b0c4e
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1900


Reviewed-by: default avatarRuss Cox <rsc@google.com>
Reviewed-by: default avatarDamien Neil <dneil@google.com>
(cherry picked from commit cc0d725a4168f234ef38859b2d951a50a8fd94b5)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1940


Reviewed-by: default avatarNeal Patel <nealpatel@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/646995


Reviewed-by: default avatarCarlos Amedee <carlos@golang.org>
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
parent 4241f582
No related branches found
No related tags found
No related merge requests found
...@@ -227,21 +227,6 @@ var validLinkerFlags = []*lazyregexp.Regexp{ ...@@ -227,21 +227,6 @@ var validLinkerFlags = []*lazyregexp.Regexp{
re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`), re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
} }
var validLinkerFlagsOnDarwin = []*lazyregexp.Regexp{
// The GNU linker interprets `@file` as "read command-line options from
// file". Thus, we forbid values starting with `@` on linker flags.
// However, this causes a problem when targeting Darwin.
// `@executable_path`, `@loader_path`, and `@rpath` are special values
// used in Mach-O to change the library search path and can be used in
// conjunction with the `-install_name` and `-rpath` linker flags.
// Since the GNU linker does not support Mach-O, targeting Darwin
// implies not using the GNU linker. Therefore, we allow @ in the linker
// flags if and only if cfg.Goos == "darwin" || cfg.Goos == "ios".
re(`-Wl,-dylib_install_name,@rpath(/[^,]*)?`),
re(`-Wl,-install_name,@rpath(/[^,]*)?`),
re(`-Wl,-rpath,@(executable_path|loader_path)(/[^,]*)?`),
}
var validLinkerFlagsWithNextArg = []string{ var validLinkerFlagsWithNextArg = []string{
"-arch", "-arch",
"-F", "-F",
...@@ -264,13 +249,8 @@ func checkCompilerFlags(name, source string, list []string) error { ...@@ -264,13 +249,8 @@ func checkCompilerFlags(name, source string, list []string) error {
} }
func checkLinkerFlags(name, source string, list []string) error { func checkLinkerFlags(name, source string, list []string) error {
validLinkerFlagsForPlatform := validLinkerFlags
if cfg.Goos == "darwin" || cfg.Goos == "ios" {
validLinkerFlagsForPlatform = append(validLinkerFlags, validLinkerFlagsOnDarwin...)
}
checkOverrides := true checkOverrides := true
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlagsForPlatform, validLinkerFlagsWithNextArg, checkOverrides) return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
} }
// checkCompilerFlagsForInternalLink returns an error if 'list' // checkCompilerFlagsForInternalLink returns an error if 'list'
......
...@@ -8,8 +8,6 @@ import ( ...@@ -8,8 +8,6 @@ import (
"os" "os"
"strings" "strings"
"testing" "testing"
"cmd/go/internal/cfg"
) )
var goodCompilerFlags = [][]string{ var goodCompilerFlags = [][]string{
...@@ -247,8 +245,6 @@ var badLinkerFlags = [][]string{ ...@@ -247,8 +245,6 @@ var badLinkerFlags = [][]string{
{"-Wl,--hash-style=foo"}, {"-Wl,--hash-style=foo"},
{"-x", "--c"}, {"-x", "--c"},
{"-x", "@obj"}, {"-x", "@obj"},
{"-Wl,-dylib_install_name,@foo"},
{"-Wl,-install_name,@foo"},
{"-Wl,-rpath,@foo"}, {"-Wl,-rpath,@foo"},
{"-Wl,-R,foo,bar"}, {"-Wl,-R,foo,bar"},
{"-Wl,-R,@foo"}, {"-Wl,-R,@foo"},
...@@ -265,21 +261,6 @@ var badLinkerFlags = [][]string{ ...@@ -265,21 +261,6 @@ var badLinkerFlags = [][]string{
{"./-Wl,--push-state,-R.c"}, {"./-Wl,--push-state,-R.c"},
} }
var goodLinkerFlagsOnDarwin = [][]string{
{"-Wl,-dylib_install_name,@rpath"},
{"-Wl,-dylib_install_name,@rpath/"},
{"-Wl,-dylib_install_name,@rpath/foo"},
{"-Wl,-install_name,@rpath"},
{"-Wl,-install_name,@rpath/"},
{"-Wl,-install_name,@rpath/foo"},
{"-Wl,-rpath,@executable_path"},
{"-Wl,-rpath,@executable_path/"},
{"-Wl,-rpath,@executable_path/foo"},
{"-Wl,-rpath,@loader_path"},
{"-Wl,-rpath,@loader_path/"},
{"-Wl,-rpath,@loader_path/foo"},
}
func TestCheckLinkerFlags(t *testing.T) { func TestCheckLinkerFlags(t *testing.T) {
for _, f := range goodLinkerFlags { for _, f := range goodLinkerFlags {
if err := checkLinkerFlags("test", "test", f); err != nil { if err := checkLinkerFlags("test", "test", f); err != nil {
...@@ -291,31 +272,6 @@ func TestCheckLinkerFlags(t *testing.T) { ...@@ -291,31 +272,6 @@ func TestCheckLinkerFlags(t *testing.T) {
t.Errorf("missing error for %q", f) t.Errorf("missing error for %q", f)
} }
} }
goos := cfg.Goos
cfg.Goos = "darwin"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err != nil {
t.Errorf("unexpected error for %q: %v", f, err)
}
}
cfg.Goos = "ios"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err != nil {
t.Errorf("unexpected error for %q: %v", f, err)
}
}
cfg.Goos = "linux"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err == nil {
t.Errorf("missing error for %q", f)
}
}
cfg.Goos = goos
} }
func TestCheckFlagAllowDisallow(t *testing.T) { func TestCheckFlagAllowDisallow(t *testing.T) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment