fix link errors when importing crypto/ecdsa (#262)

First, we had some link errors such as:

	cannot find package J6OzO8GN (using -importcfg)

This was caused by the code that writes an updated importcfg, which did
not handle import maps well. That code is now fixed, and we also add an
obfuscatedImportPath method for clarity.

Once fixed, we ran into other link errors:

	Pw3g97ww.addVW: relocation target Pw3g97ww.addVWlarge not defined

After some digging, the cause of those is assembly code that we do not
yet support obfuscating. #261 tracks that.

Meanwhile, to fix "GOPRIVATE=* garble build" and to be able to have a
test for the original import path bug, we add the packages which use
that form of assembly code to runtimeRelated - math/big and
crypto/sha512. There might be more, but these were the ones found by
trying to link crypto/tls, a fairly common dependency.

Fixes #256.
pull/264/head
Daniel Martí 3 years ago committed by GitHub
parent 99887c13c2
commit 1267e2eced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -407,8 +407,8 @@ func transformAsm(args []string) ([]string, error) {
curPkgPathFull = cache.MainImportPath
}
newPkgPath := hashWith(cache.ListedPackages[curPkgPathFull].GarbleActionID, curPkgPath)
flags = flagSetValue(flags, "-p", newPkgPath)
lpkg := cache.ListedPackages[curPkgPathFull]
flags = flagSetValue(flags, "-p", lpkg.obfuscatedImportPath())
}
return append(flags, paths...), nil
@ -553,7 +553,7 @@ func transformCompile(args []string) ([]string, error) {
// package path.
newPkgPath := curPkgPath
if curPkgPath != "main" && isPrivate(curPkgPath) {
newPkgPath = hashWith(curPkg.GarbleActionID, curPkgPath)
newPkgPath = curPkg.obfuscatedImportPath()
flags = flagSetValue(flags, "-p", newPkgPath)
}
@ -588,11 +588,6 @@ func transformCompile(args []string) ([]string, error) {
default:
file = tf.transformGo(file)
// Uncomment for some quick debugging. Do not delete.
// fmt.Fprintf(os.Stderr, "\n-- %s/%s --\n", curPkgPath, origName)
// if err := printConfig.Fprint(os.Stderr, fset, file); err != nil {
// return nil, err
// }
ast.Inspect(file, func(node ast.Node) bool {
imp, ok := node.(*ast.ImportSpec)
if !ok {
@ -613,7 +608,7 @@ func transformCompile(args []string) ([]string, error) {
if err != nil {
panic(err) // should never happen
}
newPath := hashWith(lpkg.GarbleActionID, path)
newPath := lpkg.obfuscatedImportPath()
imp.Path.Value = strconv.Quote(newPath)
if imp.Name == nil {
imp.Name = &ast.Ident{Name: lpkg.Name}
@ -625,6 +620,12 @@ func transformCompile(args []string) ([]string, error) {
file.Name.Name = newPkgPath
}
// Uncomment for some quick debugging. Do not delete.
// fmt.Fprintf(os.Stderr, "\n-- %s/%s --\n", curPkgPath, origName)
// if err := printConfig.Fprint(os.Stderr, fset, file); err != nil {
// return nil, err
// }
tempFile, err := ioutil.TempFile(sharedTempDir, name+".*.go")
if err != nil {
return nil, err
@ -736,7 +737,7 @@ func (tf *transformer) handleDirectives(comments []string) {
newName := hashWith(lpkg.GarbleActionID, name)
newPkgPath := pkgPath
if pkgPath != "main" {
newPkgPath = hashWith(lpkg.GarbleActionID, pkgPath)
newPkgPath = lpkg.obfuscatedImportPath()
}
fields[2] = newPkgPath + "." + newName
comments[i] = strings.Join(fields, " ")
@ -820,6 +821,15 @@ var runtimeRelated = map[string]bool{
// Go 1.15's "net" package depends on "math/rand", but 1.16's does not.
// Keep it here to support 1.15.
"math/rand": true,
// These packages call pure Go functions from assembly functions.
// We obfuscate the pure Go function name, breaking the assembly.
// We do not deal with that edge case just yet, so for now,
// never obfuscate these packages.
// TODO: remove once we fix issue 261.
"math/big": true,
"crypto/sha512": true,
"crypto": true,
}
// isPrivate checks if GOPRIVATE matches path.
@ -913,22 +923,29 @@ func processImportCfg(flags []string) (newImportCfg string, _ error) {
return "", err
}
for beforePath, afterPath := range importMap {
if isPrivate(beforePath) {
pkg, err := listPackage(beforePath)
if isPrivate(afterPath) {
lpkg, err := listPackage(beforePath)
if err != nil {
panic(err) // shouldn't happen
}
afterPath = hashWith(pkg.GarbleActionID, afterPath)
// Note that beforePath is not the canonical path.
// For beforePath="vendor/foo", afterPath and
// lpkg.ImportPath can be just "foo".
// Don't use obfuscatedImportPath here.
beforePath = hashWith(lpkg.GarbleActionID, beforePath)
afterPath = lpkg.obfuscatedImportPath()
}
fmt.Fprintf(newCfg, "importmap %s=%s\n", beforePath, afterPath)
}
for impPath, pkg := range importCfgEntries {
if isPrivate(impPath) {
pkg, err := listPackage(impPath)
lpkg, err := listPackage(impPath)
if err != nil {
panic(err) // shouldn't happen
}
impPath = hashWith(pkg.GarbleActionID, impPath)
impPath = lpkg.obfuscatedImportPath()
}
fmt.Fprintf(newCfg, "packagefile %s=%s\n", impPath, pkg.packagefile)
}

@ -176,6 +176,14 @@ type listedPackage struct {
private bool
}
func (p *listedPackage) obfuscatedImportPath() string {
if p.Name == "main" || !isPrivate(p.ImportPath) {
return p.ImportPath
}
newPath := hashWith(p.GarbleActionID, p.ImportPath)
return newPath
}
// setListedPackages gets information about the current package
// and all of its dependencies
func setListedPackages(patterns []string) error {

@ -6,7 +6,9 @@ env GOPRIVATE=test/main/imported
! garble build ./importer
stderr '^public package "test/main/importer" can''t depend on obfuscated package "test/main/imported" \(matched via GOPRIVATE="test/main/imported"\)$'
[short] stop
[short] stop # rebuilding std is slow
env GOPRIVATE='*'
# Try garbling all of std, given some std packages.
# No need for a main package here; building the std packages directly works the
@ -15,9 +17,12 @@ stderr '^public package "test/main/importer" can''t depend on obfuscated package
# packages so we must properly support ImportMap.
# Plus, some packages like net make heavy use of complex features like Cgo.
# Note that we won't obfuscate a few std packages just yet, mainly those around runtime.
env GOPRIVATE='*'
garble build std
# Link a binary importing crypto/ecdsa, which will catch whether or not we
# support ImportMap when linking.
garble build -o=out ./stdimporter
-- go.mod --
module test/main
@ -36,3 +41,13 @@ var _ = imported.Name
package imported
var Name = "value"
-- stdimporter/main.go --
package main
import (
"crypto/ecdsa"
)
func main() {
ecdsa.Verify(nil, nil, nil, nil)
}

Loading…
Cancel
Save