Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: CLONE_NEWTIME can't be used with SysProcAttr.Cloneflags #49779

Open
ysksuzuki opened this issue Nov 24, 2021 · 6 comments
Open

syscall: CLONE_NEWTIME can't be used with SysProcAttr.Cloneflags #49779

ysksuzuki opened this issue Nov 24, 2021 · 6 comments
Labels
help wanted NeedsInvestigation OS-Linux
Milestone

Comments

@ysksuzuki
Copy link

@ysksuzuki ysksuzuki commented Nov 24, 2021

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

$ go version
go version go1.17.1 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/yusuke/.cache/go-build"
GOENV="/home/yusuke/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/yusuke/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/yusuke/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.1"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/yusuke/go/src/github.com/ysksuzuki/containers-from-scratch/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2997449259=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Run a command with Cloneflags unix.CLONE_NEWTIME and check if the process is in a different time namespace from its parent.

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3]...)
        cmd.Stdin = os.Stdin
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.SysProcAttr = &unix.SysProcAttr{
                Cloneflags:   unix.CLONE_NEWTIME,
        }

        cmd.Run()
}

What did you expect to see?

The process is in an isolated time namespace from its parent.

What did you see instead?

The process is in the same time namespace as its parent.

forkAndExecInChild uses SYS_CLONE but CLONE_NEWTIME can be used only with the clone3() system call.
https://github.com/golang/go/blob/go1.17.3/src/syscall/exec_linux.go#L218

torvalds/linux@769071a

All available clone flags have been used, so CLONE_NEWTIME uses the highest
bit of CSIGNAL. It means that it can be used only with the unshare() and
the clone3() system calls.
@heschi
Copy link
Contributor

@heschi heschi commented Nov 24, 2021

cc @ianlancetaylor

@heschi heschi added this to the Go1.19 milestone Nov 24, 2021
@heschi heschi added the NeedsInvestigation label Nov 24, 2021
@seankhliao seankhliao changed the title CLONE_NEWTIME can't be used with exec.Command and SysProcAttr.Cloneflags os/exec: CLONE_NEWTIME can't be used with exec.Command and SysProcAttr.Cloneflags Nov 24, 2021
@ianlancetaylor ianlancetaylor removed this from the Go1.19 milestone Nov 24, 2021
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Nov 24, 2021
@ianlancetaylor ianlancetaylor changed the title os/exec: CLONE_NEWTIME can't be used with exec.Command and SysProcAttr.Cloneflags syscall: CLONE_NEWTIME can't be used with SysProcAttr.Cloneflags Nov 24, 2021
@tklauser
Copy link
Member

@tklauser tklauser commented Nov 25, 2021

The clone3 syscall was added in Linux kernel version 5.3 (https://man7.org/linux/man-pages/man2/clone.2.html#VERSIONS). As of Go 1.18 the minimal supported Linux kernel version is 2.6.32 , see #45964. So it looks like we cannot use clone3 unconditionally, but would need to still fall back to clone (and drop CLONE_NEWTIME) in case clone3 returns ENOSYS (i.e. on Linux kernel < 5.3).

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Nov 26, 2021

Sounds right, but if CLONE_NEWTIME is specified and clone3 fails, we should probably fail the fork/exec in that case.

@jeremychase
Copy link

@jeremychase jeremychase commented Apr 8, 2022

I looked into this and am unsure how to proceed because SYS_CLONE3 is not yet in src/syscall/zsysnum_linux_arm64.go, nor any other file. I was able to rebuild src/syscall/zsysnum_linux_arm64.go on my machine using ./mksysnum_linux.pl /usr/include/asm-generic/unistd.h > zsysnum_linux_arm64.go. However, that relies on my machine's headers and I'm not clear how to build the other zsysnum_linux_* files.

Some helpful background on time namespaces that might help someone looking at this:

  • The time_namespaces(7) man page is very informative.
  • The current namespace for a process is a symlink at /proc/{pid}/ns/time and the namespace for any children is at /proc/{pid}/ns/time_for_children. Use readlink to inspect them, for example to see the current process's time namespace: readlink /proc/$$/ns/time

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Apr 8, 2022

See also #51246.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Apr 8, 2022

We don't have a good way to rebuild the files in syscall. We don't worry about it because the syscall package is frozen (http://golang.org/s/go1.4-syscall). For purposes of this work it would be OK to manually copy the required constants and types from golang.org/x/sys/unix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted NeedsInvestigation OS-Linux
Projects
None yet
Development

No branches or pull requests

5 participants