avoid go:linkname warnings when building on tip

Packages like os and sync have started using go:linknames pointing to
packages outside their dependency tree, much like runtime already did.
This started causing warnings to be printed while obfuscsating std:

    > exec garble build -o=out_rebuild ./stdimporter
    [stderr]
    # sync
    //go:linkname refers to syscall.hasWaitingReaders - add `import _ "syscall"` for garble to find the package
    # os
    //go:linkname refers to net.newUnixFile - add `import _ "net"` for garble to find the package
    > bincmp out_rebuild out
    PASS

Relax the restriction in listPackage so that any package in std
is now allowed to list packages in runtimeLinknamed,
which makes the warnings and any potential problems go away.
Also make these std test cases check that no warnings are printed,
since I only happened to notice this problem by chance.
pull/755/head
Daniel Martí 1 year ago
parent 0f2b59d794
commit da5ddfa45d

@ -91,7 +91,7 @@ jobs:
- uses: actions/checkout@v3
- name: Install Go
env:
GO_COMMIT: aeb0644bd33e67f24e2411a651ac9ff72ddc96b4 # 2023-05-19
GO_COMMIT: 363713223385476b87dc5f26d267df8c67d13006 # 2023-06-03
run: |
cd $HOME
mkdir $HOME/gotip

@ -397,12 +397,15 @@ func listPackage(path string) (*listedPackage, error) {
pkg, ok := sharedCache.ListedPackages[path]
// The runtime may list any package in std, even those it doesn't depend on.
// This is due to how it linkname-implements std packages,
// A std package may list any other package in std, even those it doesn't depend on.
// This is due to how runtime linkname-implements std packages,
// such as sync/atomic or reflect, without importing them in any way.
// If ListedPackages lacks such a package we fill it with "std".
// Note that this is also allowed for runtime sub-packages.
if curPkg.ImportPath == "runtime" || strings.HasPrefix(curPkg.ImportPath, "runtime/") {
// A few other cases don't involve runtime, like time/tzdata linknaming to time,
// but luckily those few cases are covered by runtimeLinknamed as well.
//
// If ListedPackages lacks such a package we fill it via runtimeLinknamed.
// TODO: can we instead add runtimeLinknamed to the top-level "go list" args?
if curPkg.Standard {
if ok {
return pkg, nil
}
@ -429,7 +432,7 @@ func listPackage(path string) (*listedPackage, error) {
}
pkg, ok := sharedCache.ListedPackages[path]
if !ok {
panic(fmt.Sprintf("runtime listed a std package we can't find: %s", path))
panic(fmt.Sprintf("std listed another std package that we can't find: %s", path))
}
listedRuntimeLinknamed = true
log.Printf("listed %d missing runtime-linknamed packages in %s", len(missing), debugSince(startTime))
@ -439,7 +442,7 @@ func listPackage(path string) (*listedPackage, error) {
return nil, fmt.Errorf("list %s: %w", path, ErrNotFound)
}
// Packages other than runtime can list any package,
// Packages outside std can list any package,
// as long as they depend on it directly or indirectly.
for _, dep := range curPkg.Deps {
if dep == pkg.ImportPath {

@ -29,11 +29,13 @@ env GOGARBLE='*'
# 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.
exec garble build std
! stderr . # no warnings
# Link a binary importing net/http, which will catch whether or not we
# support ImportMap when linking.
# Also ensure we are obfuscating low-level std packages.
exec garble build -o=out ./stdimporter
! stderr . # no warnings
! binsubstr out 'http.ListenAndServe' 'debug.WriteHeapDump' 'time.Now' 'syscall.Listen'
# The same low-level std packages appear in plain sight in regular builds.

Loading…
Cancel
Save