]> Cypherpunks repositories - gostls13.git/commit
cmd/compile, cmd/link: disallow linkname of some newly added internal functions
authorCherry Mui <cherryyz@google.com>
Thu, 9 May 2024 21:07:43 +0000 (17:07 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 10 May 2024 17:05:33 +0000 (17:05 +0000)
commit4721f95058878042576ef09562a84e6c93e5c399
tree17540e917269a8631701ee3ab33f38c0c45d4b9a
parentdf4f40b9e07ed9b4d50dc10a445d4b50c37e4daa
cmd/compile, cmd/link: disallow linkname of some newly added internal functions

Go API is defined through exported symbols. When a package is
imported, the compiler ensures that only exported symbols can be
accessed, and the go command ensures that internal packages cannot
be imported. This ensures API integrity. But there is a hole:
using linkname, one can access internal or non-exported symbols.
Linkname is a mechanism to give access of a symbol to a package
without adding it to the public API. It is intended for coupled
packages to share some implementation details, or to break
circular dependencies, and both "push" (definition) and "pull"
(reference) sides are controlled, so they can be updated in sync.
Nevertheless, it is abused as a mechanism to reach into internal
details of other packages uncontrolled by the user, notably the
runtime. As the other package evolves, the code often breaks,
because the linknamed symbol may no longer exist, or change its
signature or semantics.

This CL adds a mechanism to enforce the integrity of linknames.
Generally, "push" linkname is allowed, as the package defining
the symbol explicitly opt in for access outside of the package.
"Pull" linkname is checked and only allowed in some circumstances.
Given that there are existing code that use "pull"-only linkname
to access other package's internals, disallowing it completely is
too much a change at this point in the release cycle. For a start,
implement a hard-coded blocklist, which contains some newly added
internal functions that, if used inappropriately, may break memory
safety or runtime integrity. All blocked symbols are newly added
in Go 1.23. So existing code that builds with Go 1.22 will
continue to build.

For the implementation, when compiling a package, we mark
linknamed symbols in the current package with an attribute. At
link time, marked linknamed symbols are checked against the
blocklist. Care is taken so it distinguishes a linkname reference
in the current package vs. a reference of a linkname from another
package and propagated to the current package (e.g. through
inlining or instantiation).

Symbol references in assembly code are similar to linknames, and
are treated similarly.

Change-Id: I8067efe29c122740cd4f1effd2dec2d839147d5d
Reviewed-on: https://go-review.googlesource.com/c/go/+/584598
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
14 files changed:
src/cmd/compile/internal/noder/reader.go
src/cmd/internal/goobj/objfile.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/objfile.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/link_test.go
src/cmd/link/testdata/linkname/coro.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/coro_asm/asm.s [new file with mode: 0644]
src/cmd/link/testdata/linkname/coro_asm/main.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/coro_var.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/ok.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/p/p.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/push.go [new file with mode: 0644]
src/cmd/link/testdata/linkname/weak.go [new file with mode: 0644]