Skip to content

os: OpenRoot follows symlinks #71806

Closed
Closed
@glycerine

Description

@glycerine

Go version

go version 1.24.0

Output of go env in your module/workspace:

see below.

What did you do?

Reading #67002 and https://go.dev/doc/go1.24#directory-limited-filesystem-access, I was under the impression that the new os.Root was supposed to return an error on root.Open() of a symlink to /etc/ and then opening /etc/passwd.

On MacOS Sonoma 14.0, go 1.24.0 amd64:

uname -a
Darwin jbook.chimera-bass.ts.net 23.0.0 Darwin Kernel Version 23.0.0: Fri Sep 15 14\
:42:42 PDT 2023; root:xnu-10002.1.13~1/RELEASE_X86_64 x86_64

jaten@Js-MacBook-Pro ~/trash/root $ ln -s /etc symlink
ln -s /etc symlink
jaten@Js-MacBook-Pro ~/trash/root $ go run root.go
go run root.go
read file, got: '##
# User Database
# 
# Note that this file is consulted directly only when the system is running
# in single-user mode.  At other times this information is provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional information about
# Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
... the rest of my /etc/passwd file elided for security reasons...
'
jaten@Js-MacBook-Pro ~/trash/root $ go version
go version
go version go1.24.0 darwin/amd64
jaten@Js-MacBook-Pro ~/trash/root $ cat root.go
cat root.go
package main

import (
	"fmt"
	"os"
)

func main() {
	root, err := os.OpenRoot("symlink")
	if err != nil {
		panic(err)
	}
	fd, err := root.Open("passwd")
	if err != nil {
		panic(err)
	}
	buf := make([]byte, 1<<20)
	n, err := fd.Read(buf)
	if err != nil {
		panic(err)
	}
	fmt.Printf("read file, got: '%v'\n", string(buf[:n]))
}
jaten@Js-MacBook-Pro ~/trash/root $

jaten@Js-MacBook-Pro ~/trash/root $ go env
go env
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE='auto'
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/jaten/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/jaten/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/b6/q5ms8t4x5cjcpcpyjrb1h91c0000gn/T/go-build4060061549=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD=''
GOMODCACHE='/Users/jaten/go/pkg/mod'
GONOPROXY='github.com/glycerine/*'
GONOSUMDB='github.com/glycerine/*'
GOOS='darwin'
GOPATH='/Users/jaten/go'
GOPRIVATE='github.com/glycerine/*'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='off'
GOTELEMETRYDIR='/Users/jaten/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.24.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you see happen?

See above.

What did you expect to see?

Not to be able to access /etc/password from an os.Root in /Users/jaten/trash/root.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.DocumentationIssues describing a change to documentation.NeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions