aboutsummaryrefslogtreecommitdiff
path: root/src/syscall/exec_linux_test.go
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2023-03-08 12:49:10 +0100
committerGopher Robot <gobot@golang.org>2023-03-13 19:26:17 +0000
commit7c019c62fb32db42e946b15763217518a521404e (patch)
treedd8fe777935c6082a9419d5316e61e05ccfb685b /src/syscall/exec_linux_test.go
parent778627f33187d874440ce1f353bb4d7bce55304a (diff)
downloadgo-7c019c62fb32db42e946b15763217518a521404e.tar.xz
syscall: use clone3 syscall with CLONE_NEWTIME
CLONE_NEWTIME can only be used with the clone3 and unshare system calls, see https://github.com/torvalds/linux/commit/769071ac9f20b6a447410c7eaa55d1a5233ef40c: > 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. The clone3 syscall was added in Linux kernel version 5.3 and CLONE_NEWTIME was added in version 5.6. However, it was non-functional until version 6.3 (and stable versions with the corresponding fix [1]). [1] https://lore.kernel.org/lkml/20230308105126.10107-1-tklauser@distanz.ch/ In case CLONE_NEWTIME is set in SysProcAttr.Cloneflags on an unsupported kernel version, the fork/exec call will fail. Fixes #49779 Change-Id: Ic3ecfc2b601bafaab12b1805d7f9512955a8c7e2 Reviewed-on: https://go-review.googlesource.com/c/go/+/474356 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/syscall/exec_linux_test.go')
-rw-r--r--src/syscall/exec_linux_test.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index e0aa3fe996..06b9495be2 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -487,6 +487,52 @@ func TestUseCgroupFDHelper(*testing.T) {
fmt.Print(string(selfCg))
}
+func TestCloneTimeNamespace(t *testing.T) {
+ testenv.MustHaveExec(t)
+
+ if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" {
+ timens, err := os.Readlink("/proc/self/ns/time")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(2)
+ }
+ fmt.Print(string(timens))
+ os.Exit(0)
+ }
+
+ exe, err := os.Executable()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ cmd := testenv.Command(t, exe, "-test.run=TestCloneTimeNamespace")
+ cmd.Env = append(cmd.Environ(), "GO_WANT_HELPER_PROCESS=1")
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Cloneflags: syscall.CLONE_NEWTIME,
+ }
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ if isNotSupported(err) {
+ // CLONE_NEWTIME does not appear to be supported.
+ t.Skipf("skipping, CLONE_NEWTIME not supported: %v", err)
+ }
+ t.Fatalf("Cmd failed with err %v, output: %s", err, out)
+ }
+
+ // Inode numer of the time namespaces should be different.
+ // Based on https://man7.org/linux/man-pages/man7/time_namespaces.7.html#EXAMPLES
+ timens, err := os.Readlink("/proc/self/ns/time")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ parentTimeNS := string(timens)
+ childTimeNS := string(out)
+ if childTimeNS == parentTimeNS {
+ t.Fatalf("expected child time namespace to be different from parent time namespace: %s", parentTimeNS)
+ }
+}
+
type capHeader struct {
version uint32
pid int32