golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.84k stars 17.51k forks source link

x/sys/unix: Workaround `xnu` kernel bug when making `procargs2` syscall using `SysctlRaw` #60047

Open wheelerlaw opened 1 year ago

wheelerlaw commented 1 year ago

What version of Go are you using (go version)?

$ go version
go version go1.20.3 darwin/amd64

Does this issue reproduce with the latest release?

Yes, on macOS Catalina

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/wheeler/Library/Caches/go-build"
GOENV="/Users/wheeler/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/wheeler/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/wheeler/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.20.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/v7/4gsbfcxj10190bg9qzr8ys_h0000gw/T/go-build2062273463=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Called unix.SysctlRaw() to get the args of a process on Catalina (through the use of the github.com/elastic/go-sysinfo package)

I have created a small demo test in my fork of go-sysinfo that demonstrates the issue. Note: this must be run on macOS Catalina in order to the issue to be reproduced.

What did you expect to see?

The unix.SysctlRaw() function return the args of a process on Catalina.

What did you see instead?

I noticed that using unix.SysctlRaw() to call the kern.procargs2 syscall on macOS Catalina does not return the args for a process due to a couple bugs in xnu:

  1. In the first syscall, the calculation of the size of the args is done incorrectly, as it does not account for the 17 byte string executable_path= that prefixes name of the executable. This size is then used to allocate a buffer which is where the args are copied into.
  2. In the second syscall, it writes zeros in the buffer instead of the executable name and its arguments due to a bug in the handling of a buffer that is too small.

More details about this issue is documented in the fixed version of xnu's kern_sysctl.c.

These bugs are not going to be fixed in Catalina because Apple has discontinued support for the OS. However, Catalina is still technically a supported platform for the latest version of Go, so I went ahead and created a patch in the x/sys package that works around the xnu kernel bug. I'm not sure how to submit it but I am looking for feedback on it.

cherrymui commented 1 year ago

@wheelerlaw for submitting your patch, see https://go.dev/doc/contribute for how to contribute. Thanks.

anton-kuklin commented 1 year ago

@wheelerlaw do you need help with this one? Should I takeover?

wheelerlaw commented 1 year ago

@wheelerlaw do you need help with this one? Should I takeover?

Sorry, been a busy few weeks moving apartments, I will get a patch submitted sometime this weekend.