Skip to content

Commit 51bf2cf

Browse files
rolandshoemakercherrymui
authored andcommitted
Revert "cmd/go/internal/work: allow @ character in some -Wl, linker flags on darwin"
This reverts CL 638075 (commit e3cd55e). 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: Russ Cox <[email protected]> Reviewed-by: Damien Neil <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/646996 Reviewed-by: Carlos Amedee <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 220fe79 commit 51bf2cf

File tree

2 files changed

+1
-65
lines changed

2 files changed

+1
-65
lines changed

src/cmd/go/internal/work/security.go

+1-21
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,6 @@ var validLinkerFlags = []*lazyregexp.Regexp{
227227
re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
228228
}
229229

230-
var validLinkerFlagsOnDarwin = []*lazyregexp.Regexp{
231-
// The GNU linker interprets `@file` as "read command-line options from
232-
// file". Thus, we forbid values starting with `@` on linker flags.
233-
// However, this causes a problem when targeting Darwin.
234-
// `@executable_path`, `@loader_path`, and `@rpath` are special values
235-
// used in Mach-O to change the library search path and can be used in
236-
// conjunction with the `-install_name` and `-rpath` linker flags.
237-
// Since the GNU linker does not support Mach-O, targeting Darwin
238-
// implies not using the GNU linker. Therefore, we allow @ in the linker
239-
// flags if and only if cfg.Goos == "darwin" || cfg.Goos == "ios".
240-
re(`-Wl,-dylib_install_name,@rpath(/[^,]*)?`),
241-
re(`-Wl,-install_name,@rpath(/[^,]*)?`),
242-
re(`-Wl,-rpath,@(executable_path|loader_path)(/[^,]*)?`),
243-
}
244-
245230
var validLinkerFlagsWithNextArg = []string{
246231
"-arch",
247232
"-F",
@@ -264,13 +249,8 @@ func checkCompilerFlags(name, source string, list []string) error {
264249
}
265250

266251
func checkLinkerFlags(name, source string, list []string) error {
267-
validLinkerFlagsForPlatform := validLinkerFlags
268-
if cfg.Goos == "darwin" || cfg.Goos == "ios" {
269-
validLinkerFlagsForPlatform = append(validLinkerFlags, validLinkerFlagsOnDarwin...)
270-
}
271-
272252
checkOverrides := true
273-
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlagsForPlatform, validLinkerFlagsWithNextArg, checkOverrides)
253+
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
274254
}
275255

276256
// checkCompilerFlagsForInternalLink returns an error if 'list'

src/cmd/go/internal/work/security_test.go

-44
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import (
88
"os"
99
"strings"
1010
"testing"
11-
12-
"cmd/go/internal/cfg"
1311
)
1412

1513
var goodCompilerFlags = [][]string{
@@ -247,8 +245,6 @@ var badLinkerFlags = [][]string{
247245
{"-Wl,--hash-style=foo"},
248246
{"-x", "--c"},
249247
{"-x", "@obj"},
250-
{"-Wl,-dylib_install_name,@foo"},
251-
{"-Wl,-install_name,@foo"},
252248
{"-Wl,-rpath,@foo"},
253249
{"-Wl,-R,foo,bar"},
254250
{"-Wl,-R,@foo"},
@@ -265,21 +261,6 @@ var badLinkerFlags = [][]string{
265261
{"./-Wl,--push-state,-R.c"},
266262
}
267263

268-
var goodLinkerFlagsOnDarwin = [][]string{
269-
{"-Wl,-dylib_install_name,@rpath"},
270-
{"-Wl,-dylib_install_name,@rpath/"},
271-
{"-Wl,-dylib_install_name,@rpath/foo"},
272-
{"-Wl,-install_name,@rpath"},
273-
{"-Wl,-install_name,@rpath/"},
274-
{"-Wl,-install_name,@rpath/foo"},
275-
{"-Wl,-rpath,@executable_path"},
276-
{"-Wl,-rpath,@executable_path/"},
277-
{"-Wl,-rpath,@executable_path/foo"},
278-
{"-Wl,-rpath,@loader_path"},
279-
{"-Wl,-rpath,@loader_path/"},
280-
{"-Wl,-rpath,@loader_path/foo"},
281-
}
282-
283264
func TestCheckLinkerFlags(t *testing.T) {
284265
for _, f := range goodLinkerFlags {
285266
if err := checkLinkerFlags("test", "test", f); err != nil {
@@ -291,31 +272,6 @@ func TestCheckLinkerFlags(t *testing.T) {
291272
t.Errorf("missing error for %q", f)
292273
}
293274
}
294-
295-
goos := cfg.Goos
296-
297-
cfg.Goos = "darwin"
298-
for _, f := range goodLinkerFlagsOnDarwin {
299-
if err := checkLinkerFlags("test", "test", f); err != nil {
300-
t.Errorf("unexpected error for %q: %v", f, err)
301-
}
302-
}
303-
304-
cfg.Goos = "ios"
305-
for _, f := range goodLinkerFlagsOnDarwin {
306-
if err := checkLinkerFlags("test", "test", f); err != nil {
307-
t.Errorf("unexpected error for %q: %v", f, err)
308-
}
309-
}
310-
311-
cfg.Goos = "linux"
312-
for _, f := range goodLinkerFlagsOnDarwin {
313-
if err := checkLinkerFlags("test", "test", f); err == nil {
314-
t.Errorf("missing error for %q", f)
315-
}
316-
}
317-
318-
cfg.Goos = goos
319275
}
320276

321277
func TestCheckFlagAllowDisallow(t *testing.T) {

0 commit comments

Comments
 (0)