Skip to content

Commit 481e3a1

Browse files
committed
default to GOGARBLE=*, stop using GOPRIVATE
We can drop the code that kicked in when GOGARBLE was empty. We can also add the value in addGarbleToHash unconditionally, as we never allow it to be empty. In the tests, remove all GOGARBLE lines where it just meant "obfuscate everything" or "obfuscate the entire main module". cgo.txtar had "obfuscate everything" as a separate step, so remove it entirely. linkname.txtar started failing because the imported package did not import strings, so listPackage errored out. This wasn't a problem when strings itself wasn't obfuscated, as transformLinkname silently left strings.IndexByte untouched. It is a problem when IndexByte does get obfuscated. Make that kind of listPackage error visible, and fix it. reflect.txtar started failing with "unreachable method" runtime throws. It's not clear to me why; it appears that GOGARBLE=* makes the linker think that ExportedMethodName is suddenly unreachable. Work around the problem by making the method explicitly reachable, and leave a TODO as a reminder to investigate. Finally, gogarble.txtar no longer needs to test for GOPRIVATE. The rest of the test is left the same, as we still want the various values for GOGARBLE to continue to work just like before. Fixes #594.
1 parent ec32030 commit 481e3a1

29 files changed

+38
-90
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and adds initial support for the upcoming Go 1.20.
77

88
Noteworthy changes include:
99

10+
* `GOGARBLE=*` is now the default to obfuscate all packages - [#594]
11+
* `GOPRIVATE` is no longer used, being deprecated in [v0.5.0]
1012
* Obfuscate assembly source code filenames - [#605]
1113
* Randomize the lengths of obfuscated names
1214
* Support obfuscating `time` and `syscall`
@@ -157,6 +159,7 @@ Known bugs:
157159
* obfuscating the standard library with `GOPRIVATE=*` is not well supported yet
158160
* `garble test` is temporarily disabled, as it is currently broken
159161

162+
[#594]: https://github.com/burrowers/garble/issues/594
160163
[#605]: https://github.com/burrowers/garble/issues/605
161164

162165
[v0.7.2]: https://github.com/burrowers/garble/releases/tag/v0.7.2

README.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ order to:
3434
* [Obfuscate literals](#literal-obfuscation), if the `-literals` flag is given
3535
* Remove [extra information](#tiny-mode), if the `-tiny` flag is given
3636

37-
The tool obfuscates the packages matching `GOGARBLE`, a comma-separated list of
38-
glob patterns of module path prefixes, as documented in `go help private`.
39-
To obfuscate all the packages in a build, use `GOGARBLE=*`.
40-
When `GOGARBLE` is empty, it assumes the value of `GOPRIVATE`.
41-
When `GOPRIVATE` is also empty, then `GOGARBLE` assumes the value of the current
42-
module path, to obfuscate all packages under the current module.
37+
By default, the tool obfuscates all the packages being built.
38+
You can manually specify which packages to obfuscate via `GOGARBLE`,
39+
a comma-separated list of glob patterns matching package path prefixes.
40+
This format is borrowed from `GOPRIVATE`; see `go help private`.
4341

4442
Note that commands like `garble build` will use the `go` version found in your
4543
`$PATH`. To use different versions of Go, you can

bench_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ func BenchmarkBuild(b *testing.B) {
8484
gocache, err := os.MkdirTemp(b.TempDir(), "gocache-*")
8585
qt.Assert(b, err, qt.IsNil)
8686
env := append(os.Environ(),
87-
"GOGARBLE=*",
8887
"GOCACHE="+gocache,
8988
"GARBLE_WRITE_ALLOCS=true",
9089
)

hash.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@ func addGarbleToHash(inputHash []byte) []byte {
9898
// We also need to add the selected options to the full version string,
9999
// because all of them result in different output. We use spaces to
100100
// separate the env vars and flags, to reduce the chances of collisions.
101-
if cache.GOGARBLE != "" {
102-
fmt.Fprintf(hasher, " GOGARBLE=%s", cache.GOGARBLE)
103-
}
101+
fmt.Fprintf(hasher, " GOGARBLE=%s", cache.GOGARBLE)
104102
appendFlags(hasher, true)
105103
// addGarbleToHash returns the sum buffer, so we need a new copy.
106104
// Otherwise the next use of the global sumBuffer would conflict.

main.go

+18-20
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import (
3636

3737
"golang.org/x/exp/maps"
3838
"golang.org/x/exp/slices"
39-
"golang.org/x/mod/modfile"
4039
"golang.org/x/mod/module"
4140
"golang.org/x/mod/semver"
4241
"golang.org/x/tools/go/ast/astutil"
@@ -998,7 +997,20 @@ func (tf *transformer) transformLinkname(localName, newName string) (string, str
998997

999998
lpkg, err := listPackage(pkgPath)
1000999
if err != nil {
1001-
// Probably a made up name like above, but with a dot.
1000+
// TODO(mvdan): use errors.As or errors.Is instead
1001+
if strings.Contains(err.Error(), "path not found") {
1002+
// Probably a made up name like above, but with a dot.
1003+
return localName, newName
1004+
}
1005+
if strings.Contains(err.Error(), "refusing to list") {
1006+
fmt.Fprintf(os.Stderr,
1007+
"//go:linkname refers to %s - add `import _ %q` so garble can find the package",
1008+
newName, pkgPath)
1009+
return localName, newName
1010+
}
1011+
if err != nil {
1012+
panic(err) // shouldn't happen
1013+
}
10021014
return localName, newName
10031015
}
10041016
if lpkg.ToObfuscate {
@@ -2185,7 +2197,8 @@ func flagSetValue(flags []string, name, value string) []string {
21852197

21862198
func fetchGoEnv() error {
21872199
out, err := exec.Command("go", "env", "-json",
2188-
"GOOS", "GOPRIVATE", "GOMOD", "GOVERSION", "GOCACHE",
2200+
// Keep in sync with sharedCache.GoEnv.
2201+
"GOOS", "GOMOD", "GOVERSION",
21892202
).CombinedOutput()
21902203
if err != nil {
21912204
// TODO: cover this in the tests.
@@ -2201,23 +2214,8 @@ To install Go, see: https://go.dev/doc/install
22012214
return fmt.Errorf(`cannot unmarshal from "go env -json": %w`, err)
22022215
}
22032216
cache.GOGARBLE = os.Getenv("GOGARBLE")
2204-
if cache.GOGARBLE != "" {
2205-
// GOGARBLE is non-empty; nothing to do.
2206-
} else if cache.GoEnv.GOPRIVATE != "" {
2207-
// GOGARBLE is empty and GOPRIVATE is non-empty.
2208-
// Set GOGARBLE to GOPRIVATE's value.
2209-
cache.GOGARBLE = cache.GoEnv.GOPRIVATE
2210-
} else {
2211-
// If GOPRIVATE isn't set and we're in a module, use its module
2212-
// path as a GOPRIVATE default. Include a _test variant too.
2213-
// TODO(mvdan): we shouldn't need the _test variant here,
2214-
// as the import path should not include it; only the package name.
2215-
if mod, err := os.ReadFile(cache.GoEnv.GOMOD); err == nil {
2216-
modpath := modfile.ModulePath(mod)
2217-
if modpath != "" {
2218-
cache.GOGARBLE = modpath + "," + modpath + "_test"
2219-
}
2220-
}
2217+
if cache.GOGARBLE == "" {
2218+
cache.GOGARBLE = "*" // we default to obfuscating everything
22212219
}
22222220
return nil
22232221
}

scripts/check-third-party.sh

-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ modules=(
3838

3939
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4040

41-
export GOGARBLE="*"
42-
4341
exit_code=0
4442

4543
show() {

shared.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ type sharedCache struct {
4444
GOGARBLE string
4545

4646
// Filled directly from "go env".
47-
// Remember to update the exec call when adding or removing names.
47+
// Keep in sync with fetchGoEnv.
4848
GoEnv struct {
4949
GOOS string // i.e. the GOOS build target
5050

51-
GOPRIVATE string
5251
GOMOD string
5352
GOVERSION string
54-
GOCACHE string
5553
}
5654
}
5755

testdata/script/asm.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
# TODO: support arm64, at least
44
[!amd64] skip 'the assembly is only written for amd64'
55

6-
env GOGARBLE=test/main
7-
86
garble build
97
exec ./main
108
cmp stderr main.stderr

testdata/script/cgo.txtar

-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
[!cgo] skip 'this test requires cgo to be enabled'
22

3-
env GOGARBLE=test/main
4-
53
garble build
64
! stderr 'warning' # check that the C toolchain is happy
75
exec ./main
@@ -19,12 +17,6 @@ garble reverse .
1917
cmp stdout reversed.stdout
2018
env GARBLE_TEST_REVERSING=false
2119

22-
env GOGARBLE=*
23-
garble build
24-
exec ./main
25-
cmp stdout main.stdout
26-
env GOGARBLE=test/main
27-
2820
garble -tiny build
2921
exec ./main
3022
cmp stdout main.stdout

testdata/script/crossbuild.txtar

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
[arm] env GOARCH=arm64
1010

1111
# A fairly average Go build, importing some std libraries.
12-
env GOGARBLE='*'
1312
garble build
1413
-- go.mod --
1514
module test/main

testdata/script/debugdir.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
garble -debugdir ./debug1 build
42
exists 'debug1/test/main/imported/imported.go' 'debug1/test/main/main.go' 'debug1/reflect/type.go'
53
exists 'debug1/runtime/map.go' 'debug1/runtime/funcdata.h' 'debug1/runtime/asm.s'

testdata/script/embed.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
garble build
42

53
exec ./main

testdata/script/gogarble.txtar

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
# Ensure that "does not match any packages" works with GOPRIVATE and GOGARBLE.
1+
# Ensure that "does not match any packages" works.
22
env GOGARBLE=match-absolutely/nothing
33
! garble build -o=out ./standalone
44
stderr '^GOGARBLE="match-absolutely/nothing" does not match any packages to be built$'
55

6-
env GOGARBLE=
7-
env GOPRIVATE=match-absolutely/nothing
8-
! garble build -o=out ./standalone
9-
stderr '^GOGARBLE="match-absolutely/nothing" does not match any packages to be built$'
10-
116
# A build where just some packages are obfuscated.
127
env GOGARBLE=test/main/imported
138
garble -literals build -o=out ./importer
@@ -23,6 +18,7 @@ garble build -o=out ./stdimporter
2318

2419
[short] stop # rebuilding std is slow
2520

21+
# Go back to the default of obfuscating all packages.
2622
env GOGARBLE='*'
2723

2824
# Try garbling all of std, given some std packages.

testdata/script/help.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
! garble
42
stderr 'Garble obfuscates Go code'
53
stderr 'garble \[garble flags\] command'

testdata/script/implement.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
garble build
42
exec ./main
53
cmp stdout main.stdout

testdata/script/imports.txtar

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
# Note that this is the only test with a module where we rely on the detection
2-
# of GOGARBLE.
3-
# Also note that, since this is the only test using "real" external modules
4-
# fetched via GOPROXY, go.mod and go.sum should declare the dependencies.
1+
# Since this is the only test using "real" external modules fetched via GOPROXY,
2+
# go.mod and go.sum should declare the dependencies.
53

64
# For now, use a throwaway module download cache instead of the host machine's.
75
# Usually it would be fine to reuse the host's, since we expose exact copies of

testdata/script/ldflags.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
# Note the proper domain, since the dot adds an edge case.
42
#
53
# Also note that there are three forms of -X allowed:

testdata/script/linkname.txtar

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main,big.chungus/meme
2-
31
garble build
42
exec ./main
53
cmp stderr main.stderr
@@ -76,6 +74,7 @@ func main() {
7674
package imported
7775

7876
import (
77+
_ "strings"
7978
_ "unsafe"
8079
)
8180

testdata/script/literals.txtar

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
garble -literals build
42
exec ./main$exe
53
cmp stderr main.stderr
@@ -52,7 +50,6 @@ grep '^\s+\w+ = .*\bappend\(\w+,(\s+\w+\[\d+\][\^\-+]\w+\[\d+\],?)+\)$' debug1/t
5250

5351
# Finally, sanity check that we can build all of std with -literals.
5452
# Analogous to gogarble.txt.
55-
env GOGARBLE='*'
5653
garble -literals build std
5754
-- go.mod --
5855
module test/main

testdata/script/modinfo.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
[exec:git] exec git init -q
42
[exec:git] exec git config user.name "name"
53
[exec:git] exec git config user.email "[email protected]"

testdata/script/plugin.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ skip # TODO: get plugins working properly. See issue #87
22

33
[windows] skip 'Go plugins are not supported on Windows'
44

5-
env GOGARBLE=test/main
6-
75
garble build -buildmode=plugin ./plugin
86
binsubstr plugin.so 'PublicVar' 'PublicFunc'
97
! binsubstr plugin.so 'privateFunc'

testdata/script/position.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
garble build
42
exec ./main
53
! stdout 'garble_main\.go|garble_other_filename|is sorted'

testdata/script/reflect.txtar

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
garble build
42
exec ./main
53
cmp stdout main.stdout
@@ -32,6 +30,8 @@ import (
3230
"test/main/importedpkg2"
3331
)
3432

33+
var Sink interface{}
34+
3535
func main() {
3636
// Fields still work fine when they are not obfuscated.
3737
fmt.Println(importedpkg.ReflectInDefinedVar.ExportedField2)
@@ -41,9 +41,13 @@ func main() {
4141
printfWithoutPackage("%T\n", importedpkg.ReflectTypeOf(2))
4242
printfWithoutPackage("%T\n", importedpkg.ReflectTypeOfIndirect(4))
4343

44+
4445
// More complex use of reflect.
4546
v := importedpkg.ReflectValueOfVar
4647
printfWithoutPackage("%#v\n", v)
48+
// Keep the method from being unreachable, otherwise Call below may panic.
49+
// TODO(mvdan): This only started being necessary with GOGARBLE=*. Why?
50+
Sink = v.ExportedMethodName
4751
method := reflect.ValueOf(&v).MethodByName("ExportedMethodName")
4852
if method.IsValid() {
4953
fmt.Println(method.Call(nil))

testdata/script/reverse.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
# Unknown build flags should result in errors.
42
! garble reverse -badflag=foo .
53
stderr 'flag provided but not defined'

testdata/script/seed-cache.txtar

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
# In the past, this threw off garble's extra cached gob files.
88

99
env SEED1=OQg9kACEECQ
10-
env GOGARBLE=*
1110

1211
# First, ensure that mod1's garbletest.v2 is in the cache.
1312
cd mod1

testdata/script/seed.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
# Note that in this test we use "! bincmp" on plaintext output files,
42
# as a workaround for "cmp" not supporting "! cmp".
53
# TODO: now that obfuscation with -seed is deterministic,

testdata/script/syntax.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE='test/main,private.source'
2-
31
garble build
42
exec ./main$exe
53
cmp stderr main.stderr

testdata/script/tiny.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=test/main
2-
31
# Tiny mode
42
garble -tiny build
53
! binsubstr main$exe 'garble_main.go' 'fmt/print.go'

testdata/script/typeparams.txtar

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
env GOGARBLE=*
2-
31
garble build
42
! binsubstr main$exe ${WORK} 'garble_main.go' 'GenericFunc' 'GenericVector' 'PredeclaredSignedInteger' 'StringableSignedInteger' 'CombineEmbeds' 'GenericParam'
53
-- go.mod --

0 commit comments

Comments
 (0)