Repository: opencontainers/runc
Pull request #4430 (2024-10-09 04:14:27)

go: update github.com/cyphar/filepath-securejoin to v0.3.4
This includes a fix to avoid doing import "testing" in non-_test.go code.

Upstream changelog:

```md
github.com/cyphar/filepath-securejoin v0.3.4

This release primarily includes a fix that blocked using
filepath-securejoin in Kubernetes.

- Previously, some testing mocks we had resulted in us doing import "testing"
  in non-_test.go code, which made some downstreams like Kubernetes unhappy.
  This has been fixed. (#32)

Thanks to all of the contributors who made this release possible:

 * Aleksa Sarai <cyphar@cyphar.com>
 * Stephen Kitt <skitt@redhat.com>

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
```

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>


Patch:
diff --git a/go.mod b/go.mod
index 478c04dc..3e548bdb 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/cilium/ebpf v0.16.0
 	github.com/containerd/console v1.0.4
 	github.com/coreos/go-systemd/v22 v22.5.0
-	github.com/cyphar/filepath-securejoin v0.3.3
+	github.com/cyphar/filepath-securejoin v0.3.4
 	github.com/docker/go-units v0.5.0
 	github.com/godbus/dbus/v5 v5.1.0
 	github.com/moby/sys/mountinfo v0.7.1
diff --git a/go.sum b/go.sum
index d515898b..0f11aa5b 100644
--- a/go.sum
+++ b/go.sum
@@ -9,8 +9,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8
 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
 github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
 github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/cyphar/filepath-securejoin v0.3.3 h1:lofZkCEVFIBe0KcdQOzFs8Soy9oaHOWl4gGtPI+gCFc=
-github.com/cyphar/filepath-securejoin v0.3.3/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
+github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
+github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
diff --git a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
index 23f7bc7f..04b5685a 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
+++ b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [Unreleased] ##
 
+## [0.3.4] - 2024-10-09 ##
+
+### Fixed ###
+- Previously, some testing mocks we had resulted in us doing `import "testing"`
+  in non-`_test.go` code, which made some downstreams like Kubernetes unhappy.
+  This has been fixed. (#32)
+
 ## [0.3.3] - 2024-09-30 ##
 
 ### Fixed ###
@@ -157,7 +164,8 @@ This is our first release of `github.com/cyphar/filepath-securejoin`,
 containing a full implementation with a coverage of 93.5% (the only missing
 cases are the error cases, which are hard to mocktest at the moment).
 
-[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...HEAD
+[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.4...HEAD
+[0.3.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...v0.3.4
 [0.3.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.2...v0.3.3
 [0.3.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.1...v0.3.2
 [0.3.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.0...v0.3.1
diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md
index 253956f8..eaeb53fc 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/README.md
+++ b/vendor/github.com/cyphar/filepath-securejoin/README.md
@@ -1,5 +1,6 @@
 ## `filepath-securejoin` ##
 
+[![Go Documentation](https://pkg.go.dev/badge/github.com/cyphar/filepath-securejoin.svg)](https://pkg.go.dev/github.com/cyphar/filepath-securejoin)
 [![Build Status](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml/badge.svg)](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml)
 
 ### Old API ###
@@ -85,7 +86,7 @@ more secure. In particular:
   or avoid being tricked by a `/proc` that is not legitimate. This is done
   using [`openat2`][openat2.2] for all users, and privileged users will also be
   further protected by using [`fsopen`][fsopen.2] and [`open_tree`][open_tree.2]
-  (Linux 4.18 or later).
+  (Linux 5.2 or later).
 
 [openat2.2]: https://www.man7.org/linux/man-pages/man2/openat2.2.html
 [fsopen.2]: https://github.com/brauner/man-pages-md/blob/main/fsopen.md
diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION
index 1c09c74e..42045aca 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/VERSION
+++ b/vendor/github.com/cyphar/filepath-securejoin/VERSION
@@ -1,1 +1,1 @@
-0.3.3
+0.3.4
diff --git a/vendor/github.com/cyphar/filepath-securejoin/doc.go b/vendor/github.com/cyphar/filepath-securejoin/doc.go
new file mode 100644
index 00000000..1ec7d065
--- /dev/null
+++ b/vendor/github.com/cyphar/filepath-securejoin/doc.go
@@ -0,0 +1,39 @@
+// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
+// Copyright (C) 2017-2024 SUSE LLC. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package securejoin implements a set of helpers to make it easier to write Go
+// code that is safe against symlink-related escape attacks. The primary idea
+// is to let you resolve a path within a rootfs directory as if the rootfs was
+// a chroot.
+//
+// securejoin has two APIs, a "legacy" API and a "modern" API.
+//
+// The legacy API is [SecureJoin] and [SecureJoinVFS]. These methods are
+// **not** safe against race conditions where an attacker changes the
+// filesystem after (or during) the [SecureJoin] operation.
+//
+// The new API is made up of [OpenInRoot] and [MkdirAll] (and derived
+// functions). These are safe against racing attackers and have several other
+// protections that are not provided by the legacy API. There are many more
+// operations that most programs expect to be able to do safely, but we do not
+// provide explicit support for them because we want to encourage users to
+// switch to [libpathrs](https://github.com/openSUSE/libpathrs) which is a
+// cross-language next-generation library that is entirely designed around
+// operating on paths safely.
+//
+// securejoin has been used by several container runtimes (Docker, runc,
+// Kubernetes, etc) for quite a few years as a de-facto standard for operating
+// on container filesystem paths "safely". However, most users still use the
+// legacy API which is unsafe against various attacks (there is a fairly long
+// history of CVEs in dependent as a result). Users should switch to the modern
+// API as soon as possible (or even better, switch to libpathrs).
+//
+// This project was initially intended to be included in the Go standard
+// library, but [it was rejected](https://go.dev/issue/20126). There is now a
+// [new Go proposal](https://go.dev/issue/67002) for a safe path resolution API
+// that shares some of the goals of filepath-securejoin. However, that design
+// is intended to work like `openat2(RESOLVE_BENEATH)` which does not fit the
+// usecase of container runtimes and most system tools.
+package securejoin
diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go
index ca4ce1f2..e0ee3f2b 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/join.go
+++ b/vendor/github.com/cyphar/filepath-securejoin/join.go
@@ -3,11 +3,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package securejoin is an implementation of the hopefully-soon-to-be-included
-// SecureJoin helper that is meant to be part of the "path/filepath" package.
-// The purpose of this project is to provide a PoC implementation to make the
-// SecureJoin proposal (https://github.com/golang/go/issues/20126) more
-// tangible.
 package securejoin
 
 import (
diff --git a/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
index ac083f21..949fb5f2 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
+++ b/vendor/github.com/cyphar/filepath-securejoin/openat_linux.go
@@ -42,10 +42,6 @@ func fstatatFile(dir *os.File, path string, flags int) (unix.Stat_t, error) {
 	return stat, nil
 }
 
-func fstatFile(fd *os.File) (unix.Stat_t, error) {
-	return fstatatFile(fd, "", unix.AT_EMPTY_PATH)
-}
-
 func readlinkatFile(dir *os.File, path string) (string, error) {
 	size := 4096
 	for {
diff --git a/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
index fa7929a5..8cc827d7 100644
--- a/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
+++ b/vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go
@@ -134,7 +134,7 @@ func clonePrivateProcMount() (_ *os.File, Err error) {
 	// we can be sure there are no over-mounts and so if the root is valid then
 	// we're golden. Otherwise, we have to deal with over-mounts.
 	procfsHandle, err := openTree(nil, "/proc", unix.OPEN_TREE_CLONE)
-	if err != nil || testingForcePrivateProcRootOpenTreeAtRecursive(procfsHandle) {
+	if err != nil || hookForcePrivateProcRootOpenTreeAtRecursive(procfsHandle) {
 		procfsHandle, err = openTree(nil, "/proc", unix.OPEN_TREE_CLONE|unix.AT_RECURSIVE)
 	}
 	if err != nil {
@@ -152,13 +152,13 @@ func clonePrivateProcMount() (_ *os.File, Err error) {
 }
 
 func privateProcRoot() (*os.File, error) {
-	if !hasNewMountApi() || testingForceGetProcRootUnsafe() {
+	if !hasNewMountApi() || hookForceGetProcRootUnsafe() {
 		return nil, fmt.Errorf("new mount api: %w", unix.ENOTSUP)
 	}
 	// Try to create a new procfs mount from scratch if we can. This ensures we
 	// can get a procfs mount even if /proc is fake (for whatever reason).
 	procRoot, err := newPrivateProcMount()
-	if err != nil || testingForcePrivateProcRootOpenTree(procRoot) {
+	if err != nil || hookForcePrivateProcRootOpenTree(procRoot) {
 		// Try to clone /proc then...
 		procRoot, err = clonePrivateProcMount()
 	}
@@ -227,10 +227,10 @@ func procThreadSelf(procRoot *os.File, subpath string) (_ *os.File, _ procThread
 
 	// Figure out what prefix we want to use.
 	threadSelf := "thread-self/"
-	if !hasProcThreadSelf() || testingForceProcSelfTask() {
+	if !hasProcThreadSelf() || hookForceProcSelfTask() {
 		/// Pre-3.17 kernels don't have /proc/thread-self, so do it manually.
 		threadSelf = "self/task/" + strconv.Itoa(unix.Gettid()) + "/"
-		if _, err := fstatatFile(procRoot, threadSelf, unix.AT_SYMLINK_NOFOLLOW); err != nil || testingForceProcSelf() {
+		if _, err := fstatatFile(procRoot, threadSelf, unix.AT_SYMLINK_NOFOLLOW); err != nil || hookForceProcSelf() {
 			// In this case, we running in a pid namespace that doesn't match
 			// the /proc mount we have. This can happen inside runc.
 			//
@@ -424,3 +424,17 @@ func checkProcSelfFdPath(path string, file *os.File) error {
 	}
 	return nil
 }
+
+// Test hooks used in the procfs tests to verify that the fallback logic works.
+// See testing_mocks_linux_test.go and procfs_linux_test.go for more details.
+var (
+	hookForcePrivateProcRootOpenTree            = hookDummyFile
+	hookForcePrivateProcRootOpenTreeAtRecursive = hookDummyFile
+	hookForceGetProcRootUnsafe                  = hookDummy
+
+	hookForceProcSelfTask = hookDummy
+	hookForceProcSelf     = hookDummy
+)
+
+func hookDummy() bool               { return false }
+func hookDummyFile(_ *os.File) bool { return false }
diff --git a/vendor/modules.txt b/vendor/modules.txt
index bd1228e3..ded326d7 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -25,7 +25,7 @@ github.com/coreos/go-systemd/v22/dbus
 # github.com/cpuguy83/go-md2man/v2 v2.0.2
 ## explicit; go 1.11
 github.com/cpuguy83/go-md2man/v2/md2man
-# github.com/cyphar/filepath-securejoin v0.3.3
+# github.com/cyphar/filepath-securejoin v0.3.4
 ## explicit; go 1.21
 github.com/cyphar/filepath-securejoin
 # github.com/docker/go-units v0.5.0


Test patch:
diff --git a/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go b/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go
deleted file mode 100644
index a3aedf03..00000000
--- a/vendor/github.com/cyphar/filepath-securejoin/testing_mocks_linux.go
+++ /dev/null
@@ -1,68 +0,0 @@
-//go:build linux
-
-// Copyright (C) 2024 SUSE LLC. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package securejoin
-
-import (
-	"os"
-	"testing"
-)
-
-type forceGetProcRootLevel int
-
-const (
-	forceGetProcRootDefault             forceGetProcRootLevel = iota
-	forceGetProcRootOpenTree                                  // force open_tree()
-	forceGetProcRootOpenTreeAtRecursive                       // force open_tree(AT_RECURSIVE)
-	forceGetProcRootUnsafe                                    // force open()
-)
-
-var testingForceGetProcRoot *forceGetProcRootLevel
-
-func testingCheckClose(check bool, f *os.File) bool {
-	if check {
-		if f != nil {
-			_ = f.Close()
-		}
-		return true
-	}
-	return false
-}
-
-func testingForcePrivateProcRootOpenTree(f *os.File) bool {
-	return testing.Testing() && testingForceGetProcRoot != nil &&
-		testingCheckClose(*testingForceGetProcRoot >= forceGetProcRootOpenTree, f)
-}
-
-func testingForcePrivateProcRootOpenTreeAtRecursive(f *os.File) bool {
-	return testing.Testing() && testingForceGetProcRoot != nil &&
-		testingCheckClose(*testingForceGetProcRoot >= forceGetProcRootOpenTreeAtRecursive, f)
-}
-
-func testingForceGetProcRootUnsafe() bool {
-	return testing.Testing() && testingForceGetProcRoot != nil &&
-		*testingForceGetProcRoot >= forceGetProcRootUnsafe
-}
-
-type forceProcThreadSelfLevel int
-
-const (
-	forceProcThreadSelfDefault forceProcThreadSelfLevel = iota
-	forceProcSelfTask
-	forceProcSelf
-)
-
-var testingForceProcThreadSelf *forceProcThreadSelfLevel
-
-func testingForceProcSelfTask() bool {
-	return testing.Testing() && testingForceProcThreadSelf != nil &&
-		*testingForceProcThreadSelf >= forceProcSelfTask
-}
-
-func testingForceProcSelf() bool {
-	return testing.Testing() && testingForceProcThreadSelf != nil &&
-		*testingForceProcThreadSelf >= forceProcSelf
-}