From 29356f30f7ca6a7fe69532f005448b275dfd4c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Wed, 10 Nov 2021 00:39:46 +0000 Subject: [PATCH] update runtimeAndDeps for Go 1.18 In particular, internal/abi now has some actual code, so obfuscating those literals was breaking as expected. Document how to update the list in the future as well. The change above gets "go test" to just one test failure on: go version devel go1.18-578ada410d Tue Nov 9 22:58:24 2021 +0000 linux/amd64 We also move the doc about why we disable GarbleLiterals, so that it's next to where the disabling happens. While here, we also rename GarbleLiterals to ObfuscateLiterals, as we have been trying to move away from "to garble" as a verb. Finally, limit the verbosity of diffoscope. One test was failing for me, and diffoscope printed thousands of lines. Not particularly useful when I'm trying to skim test results. Usually, seeing a few dozen lines of output is enough. Updates #385. --- hash.go | 2 +- main.go | 35 ++++++++++++++++++++++------------- main_test.go | 5 ++++- shared.go | 16 ++++++++-------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/hash.go b/hash.go index 289a95b..cf453d7 100644 --- a/hash.go +++ b/hash.go @@ -95,7 +95,7 @@ func addGarbleToHash(inputHash []byte) []byte { if cache.GoEnv.GOPRIVATE != "" { fmt.Fprintf(h, " GOPRIVATE=%s", cache.GoEnv.GOPRIVATE) } - if opts.GarbleLiterals { + if opts.ObfuscateLiterals { fmt.Fprintf(h, " -literals") } if opts.Tiny { diff --git a/main.go b/main.go index 53103b4..2bfa195 100644 --- a/main.go +++ b/main.go @@ -46,15 +46,15 @@ var ( ) var ( - flagGarbleLiterals bool - flagGarbleTiny bool - flagDebugDir string - flagSeed string + flagObfuscateLiterals bool + flagGarbleTiny bool + flagDebugDir string + flagSeed string ) func init() { flagSet.Usage = usage - flagSet.BoolVar(&flagGarbleLiterals, "literals", false, "Obfuscate literals such as strings") + flagSet.BoolVar(&flagObfuscateLiterals, "literals", false, "Obfuscate literals such as strings") flagSet.BoolVar(&flagGarbleTiny, "tiny", false, "Optimize for binary size, losing some ability to reverse the process") flagSet.StringVar(&flagDebugDir, "debugdir", "", "Write the obfuscated source to a directory, e.g. -debugdir=out") flagSet.StringVar(&flagSeed, "seed", "", "Provide a base64-encoded seed, e.g. -seed=o9WDTZ4CN4w\nFor a random seed, provide -seed=random") @@ -622,8 +622,11 @@ 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] { - opts.GarbleLiterals = false + opts.ObfuscateLiterals = false } // Literal obfuscation uses math/rand, so seed it deterministically. @@ -792,14 +795,20 @@ var cannotObfuscate = map[string]bool{ "crypto/x509/internal/macos": true, } -// 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. +// Obtained from "go list -deps runtime" on Go master (1.18) as of Nov 2021. +// Note that the same command on Go 1.17 results in a subset of this list. var runtimeAndDeps = map[string]bool{ - "runtime": true, - "runtime/internal/sys": true, + "internal/goarch": true, + "unsafe": true, + "internal/abi": true, "internal/cpu": true, + "internal/bytealg": true, + "internal/goexperiment": true, + "internal/goos": true, "runtime/internal/atomic": true, + "runtime/internal/math": true, + "runtime/internal/sys": true, + "runtime": true, } // isPrivate checks if a package import path should be considered private, @@ -1080,7 +1089,7 @@ func (tf *transformer) prefillIgnoreObjects(files []*ast.File) { tf.ignoreObjects = make(map[types.Object]bool) visit := func(node ast.Node) bool { - if opts.GarbleLiterals { + if opts.ObfuscateLiterals { literals.RecordUsedAsConstants(node, tf.info, tf.ignoreObjects) } @@ -1242,7 +1251,7 @@ func (tf *transformer) recordType(t types.Type) { // transformGo obfuscates the provided Go syntax file. func (tf *transformer) transformGo(file *ast.File) *ast.File { - if opts.GarbleLiterals { + if opts.ObfuscateLiterals { file = literals.Obfuscate(file, tf.info, fset, tf.ignoreObjects) } diff --git a/main_test.go b/main_test.go index ae3a9a9..12af7d0 100644 --- a/main_test.go +++ b/main_test.go @@ -146,7 +146,10 @@ func bincmp(ts *testscript.TestScript, neg bool, args []string) { ts.Logf("diffoscope is not installing; skipping binary diff") } else { // We'll error below; ignore the exec error here. - ts.Exec("diffoscope", ts.MkAbs(args[0]), ts.MkAbs(args[1])) + ts.Exec("diffoscope", + "--diff-context", "2", // down from 7 by default + "--max-text-report-size", "4096", // no limit (in bytes) by default; avoid huge output + ts.MkAbs(args[0]), ts.MkAbs(args[1])) } sizeDiff := len(data2) - len(data1) ts.Fatalf("%s and %s differ; diffoscope above, size diff: %+d", diff --git a/shared.go b/shared.go index 9de87ad..89fcc52 100644 --- a/shared.go +++ b/shared.go @@ -90,11 +90,11 @@ func saveSharedCache() (string, error) { // flagOptions are derived from the flags type flagOptions struct { - GarbleLiterals bool - Tiny bool - GarbleDir string - DebugDir string - Seed []byte + ObfuscateLiterals bool + Tiny bool + GarbleDir string + DebugDir string + Seed []byte } // setFlagOptions sets flagOptions from the user supplied flags. @@ -108,9 +108,9 @@ func setFlagOptions() error { panic("opts set twice?") } opts = &flagOptions{ - GarbleDir: wd, - GarbleLiterals: flagGarbleLiterals, - Tiny: flagGarbleTiny, + GarbleDir: wd, + ObfuscateLiterals: flagObfuscateLiterals, + Tiny: flagGarbleTiny, } if flagSeed == "random" {