From 96b15e0ac5f4ae74b22f3ee4a47d9e2192546073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Fri, 14 Jan 2022 23:20:28 +0000 Subject: [PATCH] support GOGARBLE=* with -literals again We recently made an important change when obfuscating the runtime, so that if it's missing any linkname packages in ListedPackages, it does an extra "go list" call to obtain their information. This works very well, but we missed an edge case. In main.go, we disable flagLiterals for the runtime package, but not for other packages like sync/atomic. And, since the runtime's extra "go list" has to compute GarbleActionIDs, it uses the list of garble flags via appendFlags. Unfortunately, it thinks "-literals" isn't set, when it is, and the other packages see it as being set. This discrepancy results in link time errors, as each end of the linkname obfuscates with a different hash: > garble -literals build [stderr] # test/main jccGkbFG.(*yijmzGHo).String: relocation target jccGkbFG.e_77sflf not defined jQg9GEkg.(*NLxfRPAP).pB5p2ZP0: relocation target jQg9GEkg.ce66Fmzl not defined jQg9GEkg.(*NLxfRPAP).pB5p2ZP0: relocation target jQg9GEkg.e5kPa1qY not defined jQg9GEkg.(*NLxfRPAP).pB5p2ZP0: relocation target jQg9GEkg.aQ_3sL3Q not defined jQg9GEkg.(*NLxfRPAP).pB5p2ZP0: relocation target jQg9GEkg.zls3wmws not defined jQg9GEkg.(*NLxfRPAP).pB5p2ZP0: relocation target jQg9GEkg.g69WgKIS not defined To fix the problem, treat flagLiterals as read-only after flag.Parse, just like we already do with the other flags except flagDebugDir. The code that turned flagLiterals to false is no longer needed, as literals.Obfuscate is only called when ToObfuscate is true, and ToObfuscate is false for runtimeAndDeps already. --- main.go | 11 ++++------- testdata/scripts/literals.txt | 8 ++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/main.go b/main.go index 4383d42..64b1384 100644 --- a/main.go +++ b/main.go @@ -718,13 +718,6 @@ func transformCompile(args []string) ([]string, error) { return nil, err } - // We can't obfuscate literals in the runtime and its dependencies, - // because obfuscated literals sometimes escape to heap, - // and that's not allowed in the runtime itself. - if runtimeAndDeps[curPkg.ImportPath] { - flagLiterals = false - } - // Literal obfuscation uses math/rand, so seed it deterministically. randSeed := flagSeed.bytes if len(randSeed) == 0 { @@ -1361,6 +1354,10 @@ func (tf *transformer) recordType(t types.Type) { func (tf *transformer) transformGo(file *ast.File) *ast.File { // Only obfuscate the literals here if the flag is on // and if the package in question is to be obfuscated. + // + // We can't obfuscate literals in the runtime and its dependencies, + // because obfuscated literals sometimes escape to heap, + // and that's not allowed in the runtime itself. if flagLiterals && curPkg.ToObfuscate { file = literals.Obfuscate(file, tf.info, fset) } diff --git a/testdata/scripts/literals.txt b/testdata/scripts/literals.txt index 09a578d..4be97f4 100644 --- a/testdata/scripts/literals.txt +++ b/testdata/scripts/literals.txt @@ -1,4 +1,4 @@ -env GOGARBLE=test/main +env GOGARBLE=* garble -literals build exec ./main$exe @@ -61,7 +61,11 @@ go 1.17 -- main.go -- package main -import "test/main/imported" +import ( + _ "runtime/debug" + + "test/main/imported" +) type structTest struct { field string