aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2024-05-14 00:01:49 -0400
committerCherry Mui <cherryyz@google.com>2024-05-15 19:57:43 +0000
commitc4772d30bfbed6cfbfdf92066990b5c6dc4065bb (patch)
tree0b3c762ff38080831c20aff0d8ef9020fa698620 /src/syscall
parent849770dec9191475ffed23f0d0985d8222c51e53 (diff)
downloadgo-c4772d30bfbed6cfbfdf92066990b5c6dc4065bb.tar.gz
go-c4772d30bfbed6cfbfdf92066990b5c6dc4065bb.zip
cmd/link: disallow pull-only linknames
As mentioned in CL 584598, linkname is a mechanism that, when abused, can break API integrity and even safety of Go programs. CL 584598 is a first step to restrict the use of linknames, by implementing a blocklist. This CL takes a step further, tightening up the restriction by allowing linkname references ("pull") only when the definition side explicitly opts into it, by having a linkname on the definition (possibly to itself). This way, it is at least clear on the definition side that the symbol, despite being unexported, is accessed outside of the package. Unexported symbols without linkname can now be actually private. This is similar to the symbol visibility rule used by gccgo for years (which defines unexported non-linknamed symbols as C static symbols). As there can be pull-only linknames in the wild that may be broken by this change, we currently only enforce this rule for symbols defined in the standard library. Push linknames are added in the standard library to allow things build. Linkname references to external (non-Go) symbols are still allowed, as their visibility is controlled by the C symbol visibility rules and enforced by the C (static or dynamic) linker. Assembly symbols are treated similar to linknamed symbols. This is controlled by -checklinkname linker flag, currently not enabled by default. A follow-up CL will enable it by default. Change-Id: I07344f5c7a02124dbbef0fbc8fec3b666a4b2b0e Reviewed-on: https://go-review.googlesource.com/c/go/+/585358 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/fs_wasip1.go6
-rw-r--r--src/syscall/linkname_bsd.go15
-rw-r--r--src/syscall/linkname_darwin.go23
-rw-r--r--src/syscall/linkname_libc.go12
-rw-r--r--src/syscall/linkname_openbsd.go15
-rw-r--r--src/syscall/syscall_linux.go3
6 files changed, 74 insertions, 0 deletions
diff --git a/src/syscall/fs_wasip1.go b/src/syscall/fs_wasip1.go
index f19e8f3b3c..fc361ee898 100644
--- a/src/syscall/fs_wasip1.go
+++ b/src/syscall/fs_wasip1.go
@@ -288,12 +288,18 @@ func fd_fdstat_get(fd int32, buf unsafe.Pointer) Errno
//go:noescape
func fd_fdstat_set_flags(fd int32, flags fdflags) Errno
+// fd_fdstat_get_flags is accessed from internal/syscall/unix
+//go:linkname fd_fdstat_get_flags
+
func fd_fdstat_get_flags(fd int) (uint32, error) {
var stat fdstat
errno := fd_fdstat_get(int32(fd), unsafe.Pointer(&stat))
return uint32(stat.fdflags), errnoErr(errno)
}
+// fd_fdstat_get_type is accessed from net
+//go:linkname fd_fdstat_get_type
+
func fd_fdstat_get_type(fd int) (uint8, error) {
var stat fdstat
errno := fd_fdstat_get(int32(fd), unsafe.Pointer(&stat))
diff --git a/src/syscall/linkname_bsd.go b/src/syscall/linkname_bsd.go
new file mode 100644
index 0000000000..65ef900241
--- /dev/null
+++ b/src/syscall/linkname_bsd.go
@@ -0,0 +1,15 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+
+package syscall
+
+import _ "unsafe"
+
+// used by internal/syscall/unix
+//go:linkname ioctlPtr
+
+// used by x/net/route
+//go:linkname sysctl
diff --git a/src/syscall/linkname_darwin.go b/src/syscall/linkname_darwin.go
new file mode 100644
index 0000000000..2ed83a4fad
--- /dev/null
+++ b/src/syscall/linkname_darwin.go
@@ -0,0 +1,23 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import _ "unsafe"
+
+// used by os
+//go:linkname closedir
+//go:linkname readdir_r
+
+// used by internal/poll
+//go:linkname fdopendir
+
+// used by internal/syscall/unix
+//go:linkname unlinkat
+//go:linkname openat
+//go:linkname fstatat
+
+// used by cmd/link
+//go:linkname msync
+//go:linkname fcntl
diff --git a/src/syscall/linkname_libc.go b/src/syscall/linkname_libc.go
new file mode 100644
index 0000000000..1e7b4880d6
--- /dev/null
+++ b/src/syscall/linkname_libc.go
@@ -0,0 +1,12 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || (openbsd && !mips64) || solaris
+
+package syscall
+
+import _ "unsafe"
+
+// used by internal/poll
+//go:linkname writev
diff --git a/src/syscall/linkname_openbsd.go b/src/syscall/linkname_openbsd.go
new file mode 100644
index 0000000000..5f5c517ab5
--- /dev/null
+++ b/src/syscall/linkname_openbsd.go
@@ -0,0 +1,15 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build openbsd && !mips64
+
+package syscall
+
+import _ "unsafe"
+
+// used by internal/syscall/unix
+//go:linkname unlinkat
+//go:linkname openat
+//go:linkname fstatat
+//go:linkname getentropy
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index f35e78c26a..28727dc98a 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -1284,6 +1284,9 @@ func Munmap(b []byte) (err error) {
//sys Mlockall(flags int) (err error)
//sys Munlockall() (err error)
+// prlimit is accessed from x/sys/unix.
+//go:linkname prlimit
+
// prlimit changes a resource limit. We use a single definition so that
// we can tell StartProcess to not restore the original NOFILE limit.
// This is unexported but can be called from x/sys/unix.