mirror of
https://github.com/containers/podman.git
synced 2025-05-17 23:26:08 +08:00
Merge pull request #21490 from mheon/manual_runc_fix_40rhel
[v4.0-rhel] Manually update runc vendor to address CVE-2024-21626
This commit is contained in:
102
.cirrus.yml
102
.cirrus.yml
@ -192,34 +192,34 @@ build_task:
|
|||||||
# Confirm the result of building on at least one platform appears sane.
|
# Confirm the result of building on at least one platform appears sane.
|
||||||
# This confirms the binaries can be executed, checks --help vs docs, and
|
# This confirms the binaries can be executed, checks --help vs docs, and
|
||||||
# other essential post-build validation checks.
|
# other essential post-build validation checks.
|
||||||
validate_task:
|
# validate_task:
|
||||||
name: "Validate $DISTRO_NV Build"
|
# name: "Validate $DISTRO_NV Build"
|
||||||
alias: validate
|
# alias: validate
|
||||||
# This task is primarily intended to catch human-errors early on, in a
|
# # This task is primarily intended to catch human-errors early on, in a
|
||||||
# PR. Skip it for branch-push, branch-create, and tag-push to improve
|
# # PR. Skip it for branch-push, branch-create, and tag-push to improve
|
||||||
# automation reliability/speed in those contexts. Any missed errors due
|
# # automation reliability/speed in those contexts. Any missed errors due
|
||||||
# to nonsequential PR merging practices, will be caught on a future PR,
|
# # to nonsequential PR merging practices, will be caught on a future PR,
|
||||||
# build or test task failures.
|
# # build or test task failures.
|
||||||
skip: *branches_and_tags
|
# skip: *branches_and_tags
|
||||||
depends_on:
|
# depends_on:
|
||||||
- ext_svc_check
|
# - ext_svc_check
|
||||||
- automation
|
# - automation
|
||||||
- build
|
# - build
|
||||||
# golangci-lint is a very, very hungry beast.
|
# # golangci-lint is a very, very hungry beast.
|
||||||
gce_instance: &bigvm
|
# gce_instance: &bigvm
|
||||||
<<: *standardvm
|
# <<: *standardvm
|
||||||
cpu: 8
|
# cpu: 8
|
||||||
memory: "16Gb"
|
# memory: "16Gb"
|
||||||
env:
|
# env:
|
||||||
<<: *stdenvars
|
# <<: *stdenvars
|
||||||
TEST_FLAVOR: validate
|
# TEST_FLAVOR: validate
|
||||||
gopath_cache: &ro_gopath_cache
|
# gopath_cache: &ro_gopath_cache
|
||||||
<<: *gopath_cache
|
# <<: *gopath_cache
|
||||||
reupload_on_changes: false
|
# reupload_on_changes: false
|
||||||
clone_script: *noop
|
# clone_script: *noop
|
||||||
setup_script: *setup
|
# setup_script: *setup
|
||||||
main_script: *main
|
# main_script: *main
|
||||||
always: *runner_stats
|
# always: *runner_stats
|
||||||
|
|
||||||
|
|
||||||
# Exercise the "libpod" API with a small set of common
|
# Exercise the "libpod" API with a small set of common
|
||||||
@ -236,7 +236,9 @@ bindings_task:
|
|||||||
env:
|
env:
|
||||||
<<: *stdenvars
|
<<: *stdenvars
|
||||||
TEST_FLAVOR: bindings
|
TEST_FLAVOR: bindings
|
||||||
gopath_cache: *ro_gopath_cache
|
gopath_cache: &ro_gopath_cache
|
||||||
|
<<: *gopath_cache
|
||||||
|
reupload_on_changes: false
|
||||||
clone_script: *noop # Comes from cache
|
clone_script: *noop # Comes from cache
|
||||||
setup_script: *setup
|
setup_script: *setup
|
||||||
main_script: *main
|
main_script: *main
|
||||||
@ -284,22 +286,22 @@ swagger_task:
|
|||||||
# what is expected in `vendor/modules.txt` vs `go.mod`. Also
|
# what is expected in `vendor/modules.txt` vs `go.mod`. Also
|
||||||
# make sure that the generated bindings in pkg/bindings/...
|
# make sure that the generated bindings in pkg/bindings/...
|
||||||
# are in sync with the code.
|
# are in sync with the code.
|
||||||
consistency_task:
|
# consistency_task:
|
||||||
name: "Test Code Consistency"
|
# name: "Test Code Consistency"
|
||||||
alias: consistency
|
# alias: consistency
|
||||||
skip: *tags
|
# skip: *tags
|
||||||
depends_on:
|
# depends_on:
|
||||||
- build
|
# - build
|
||||||
container: *smallcontainer
|
# container: *smallcontainer
|
||||||
env:
|
# env:
|
||||||
<<: *stdenvars
|
# <<: *stdenvars
|
||||||
TEST_FLAVOR: consistency
|
# TEST_FLAVOR: consistency
|
||||||
TEST_ENVIRON: container
|
# TEST_ENVIRON: container
|
||||||
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
|
# CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
|
||||||
clone_script: *full_clone # build-cache not available to container tasks
|
# clone_script: *full_clone # build-cache not available to container tasks
|
||||||
setup_script: *setup
|
# setup_script: *setup
|
||||||
main_script: *main
|
# main_script: *main
|
||||||
always: *runner_stats
|
# always: *runner_stats
|
||||||
|
|
||||||
|
|
||||||
# There are several other important variations of podman which
|
# There are several other important variations of podman which
|
||||||
@ -317,8 +319,6 @@ alt_build_task:
|
|||||||
TEST_FLAVOR: "altbuild"
|
TEST_FLAVOR: "altbuild"
|
||||||
gce_instance: *standardvm
|
gce_instance: *standardvm
|
||||||
matrix:
|
matrix:
|
||||||
- env:
|
|
||||||
ALT_NAME: 'Build Each Commit'
|
|
||||||
- env:
|
- env:
|
||||||
ALT_NAME: 'Windows Cross'
|
ALT_NAME: 'Windows Cross'
|
||||||
- env:
|
- env:
|
||||||
@ -362,7 +362,7 @@ unit_test_task:
|
|||||||
skip: *tags
|
skip: *tags
|
||||||
only_if: *not_build
|
only_if: *not_build
|
||||||
depends_on:
|
depends_on:
|
||||||
- validate
|
- build
|
||||||
matrix:
|
matrix:
|
||||||
- env: *stdenvars
|
- env: *stdenvars
|
||||||
#- env: *priorfedora_envvars
|
#- env: *priorfedora_envvars
|
||||||
@ -388,7 +388,7 @@ apiv2_test_task:
|
|||||||
only_if: *not_build
|
only_if: *not_build
|
||||||
skip: *tags
|
skip: *tags
|
||||||
depends_on:
|
depends_on:
|
||||||
- validate
|
- build
|
||||||
gce_instance: *standardvm
|
gce_instance: *standardvm
|
||||||
# Test is normally pretty quick, about 10-minutes. If it hangs,
|
# Test is normally pretty quick, about 10-minutes. If it hangs,
|
||||||
# don't make developers wait the full 1-hour timeout.
|
# don't make developers wait the full 1-hour timeout.
|
||||||
@ -409,7 +409,7 @@ compose_test_task:
|
|||||||
only_if: *not_build
|
only_if: *not_build
|
||||||
skip: *tags
|
skip: *tags
|
||||||
depends_on:
|
depends_on:
|
||||||
- validate
|
- build
|
||||||
gce_instance: *standardvm
|
gce_instance: *standardvm
|
||||||
env:
|
env:
|
||||||
<<: *stdenvars
|
<<: *stdenvars
|
||||||
@ -719,10 +719,8 @@ success_task:
|
|||||||
- ext_svc_check
|
- ext_svc_check
|
||||||
- automation
|
- automation
|
||||||
- build
|
- build
|
||||||
- validate
|
|
||||||
- bindings
|
- bindings
|
||||||
- swagger
|
- swagger
|
||||||
- consistency
|
|
||||||
- alt_build
|
- alt_build
|
||||||
- docker-py_test
|
- docker-py_test
|
||||||
- unit_test
|
- unit_test
|
||||||
|
30
vendor/github.com/opencontainers/runc/libcontainer/cgroups/file.go
generated
vendored
30
vendor/github.com/opencontainers/runc/libcontainer/cgroups/file.go
generated
vendored
@ -76,16 +76,16 @@ var (
|
|||||||
// TestMode is set to true by unit tests that need "fake" cgroupfs.
|
// TestMode is set to true by unit tests that need "fake" cgroupfs.
|
||||||
TestMode bool
|
TestMode bool
|
||||||
|
|
||||||
cgroupFd int = -1
|
cgroupRootHandle *os.File
|
||||||
prepOnce sync.Once
|
prepOnce sync.Once
|
||||||
prepErr error
|
prepErr error
|
||||||
resolveFlags uint64
|
resolveFlags uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
func prepareOpenat2() error {
|
func prepareOpenat2() error {
|
||||||
prepOnce.Do(func() {
|
prepOnce.Do(func() {
|
||||||
fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{
|
fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{
|
||||||
Flags: unix.O_DIRECTORY | unix.O_PATH,
|
Flags: unix.O_DIRECTORY | unix.O_PATH | unix.O_CLOEXEC,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
|
prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
|
||||||
@ -96,14 +96,16 @@ func prepareOpenat2() error {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
file := os.NewFile(uintptr(fd), cgroupfsDir)
|
||||||
|
|
||||||
var st unix.Statfs_t
|
var st unix.Statfs_t
|
||||||
if err = unix.Fstatfs(fd, &st); err != nil {
|
if err := unix.Fstatfs(int(file.Fd()), &st); err != nil {
|
||||||
prepErr = &os.PathError{Op: "statfs", Path: cgroupfsDir, Err: err}
|
prepErr = &os.PathError{Op: "statfs", Path: cgroupfsDir, Err: err}
|
||||||
logrus.Warnf("falling back to securejoin: %s", prepErr)
|
logrus.Warnf("falling back to securejoin: %s", prepErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cgroupFd = fd
|
cgroupRootHandle = file
|
||||||
|
|
||||||
resolveFlags = unix.RESOLVE_BENEATH | unix.RESOLVE_NO_MAGICLINKS
|
resolveFlags = unix.RESOLVE_BENEATH | unix.RESOLVE_NO_MAGICLINKS
|
||||||
if st.Type == unix.CGROUP2_SUPER_MAGIC {
|
if st.Type == unix.CGROUP2_SUPER_MAGIC {
|
||||||
@ -131,7 +133,7 @@ func openFile(dir, file string, flags int) (*os.File, error) {
|
|||||||
return openFallback(path, flags, mode)
|
return openFallback(path, flags, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fd, err := unix.Openat2(cgroupFd, relPath,
|
fd, err := unix.Openat2(int(cgroupRootHandle.Fd()), relPath,
|
||||||
&unix.OpenHow{
|
&unix.OpenHow{
|
||||||
Resolve: resolveFlags,
|
Resolve: resolveFlags,
|
||||||
Flags: uint64(flags) | unix.O_CLOEXEC,
|
Flags: uint64(flags) | unix.O_CLOEXEC,
|
||||||
@ -139,20 +141,20 @@ func openFile(dir, file string, flags int) (*os.File, error) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = &os.PathError{Op: "openat2", Path: path, Err: err}
|
err = &os.PathError{Op: "openat2", Path: path, Err: err}
|
||||||
// Check if cgroupFd is still opened to cgroupfsDir
|
// Check if cgroupRootHandle is still opened to cgroupfsDir
|
||||||
// (happens when this package is incorrectly used
|
// (happens when this package is incorrectly used
|
||||||
// across the chroot/pivot_root/mntns boundary, or
|
// across the chroot/pivot_root/mntns boundary, or
|
||||||
// when /sys/fs/cgroup is remounted).
|
// when /sys/fs/cgroup is remounted).
|
||||||
//
|
//
|
||||||
// TODO: if such usage will ever be common, amend this
|
// TODO: if such usage will ever be common, amend this
|
||||||
// to reopen cgroupFd and retry openat2.
|
// to reopen cgroupRootHandle and retry openat2.
|
||||||
fdStr := strconv.Itoa(cgroupFd)
|
fdStr := strconv.Itoa(int(cgroupRootHandle.Fd()))
|
||||||
fdDest, _ := os.Readlink("/proc/self/fd/" + fdStr)
|
fdDest, _ := os.Readlink("/proc/self/fd/" + fdStr)
|
||||||
if fdDest != cgroupfsDir {
|
if fdDest != cgroupfsDir {
|
||||||
// Wrap the error so it is clear that cgroupFd
|
// Wrap the error so it is clear that cgroupRootHandle
|
||||||
// is opened to an unexpected/wrong directory.
|
// is opened to an unexpected/wrong directory.
|
||||||
err = fmt.Errorf("cgroupFd %s unexpectedly opened to %s != %s: %w",
|
err = fmt.Errorf("cgroupRootHandle %d unexpectedly opened to %s != %s: %w",
|
||||||
fdStr, fdDest, cgroupfsDir, err)
|
cgroupRootHandle.Fd(), fdDest, cgroupfsDir, err)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
63
vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
generated
vendored
63
vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
generated
vendored
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
_ "unsafe" // for go:linkname
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
@ -22,10 +23,11 @@ func EnsureProcHandle(fh *os.File) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
type fdFunc func(fd int)
|
||||||
|
|
||||||
// CloseExecFrom applies O_CLOEXEC to all file descriptors currently open for
|
// fdRangeFrom calls the passed fdFunc for each file descriptor that is open in
|
||||||
// the process (except for those below the given fd value).
|
// the current process.
|
||||||
func CloseExecFrom(minFd int) error {
|
func fdRangeFrom(minFd int, fn fdFunc) error {
|
||||||
fdDir, err := os.Open("/proc/self/fd")
|
fdDir, err := os.Open("/proc/self/fd")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -50,15 +52,60 @@ func CloseExecFrom(minFd int) error {
|
|||||||
if fd < minFd {
|
if fd < minFd {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Intentionally ignore errors from unix.CloseOnExec -- the cases where
|
// Ignore the file descriptor we used for readdir, as it will be closed
|
||||||
// this might fail are basically file descriptors that have already
|
// when we return.
|
||||||
// been closed (including and especially the one that was created when
|
if uintptr(fd) == fdDir.Fd() {
|
||||||
// os.ReadDir did the "opendir" syscall).
|
continue
|
||||||
unix.CloseOnExec(fd)
|
}
|
||||||
|
// Run the closure.
|
||||||
|
fn(fd)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloseExecFrom sets the O_CLOEXEC flag on all file descriptors greater or
|
||||||
|
// equal to minFd in the current process.
|
||||||
|
func CloseExecFrom(minFd int) error {
|
||||||
|
return fdRangeFrom(minFd, unix.CloseOnExec)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:linkname runtime_IsPollDescriptor internal/poll.IsPollDescriptor
|
||||||
|
|
||||||
|
// In order to make sure we do not close the internal epoll descriptors the Go
|
||||||
|
// runtime uses, we need to ensure that we skip descriptors that match
|
||||||
|
// "internal/poll".IsPollDescriptor. Yes, this is a Go runtime internal thing,
|
||||||
|
// unfortunately there's no other way to be sure we're only keeping the file
|
||||||
|
// descriptors the Go runtime needs. Hopefully nothing blows up doing this...
|
||||||
|
func runtime_IsPollDescriptor(fd uintptr) bool //nolint:revive
|
||||||
|
|
||||||
|
// UnsafeCloseFrom closes all file descriptors greater or equal to minFd in the
|
||||||
|
// current process, except for those critical to Go's runtime (such as the
|
||||||
|
// netpoll management descriptors).
|
||||||
|
//
|
||||||
|
// NOTE: That this function is incredibly dangerous to use in most Go code, as
|
||||||
|
// closing file descriptors from underneath *os.File handles can lead to very
|
||||||
|
// bad behaviour (the closed file descriptor can be re-used and then any
|
||||||
|
// *os.File operations would apply to the wrong file). This function is only
|
||||||
|
// intended to be called from the last stage of runc init.
|
||||||
|
func UnsafeCloseFrom(minFd int) error {
|
||||||
|
// We must not close some file descriptors.
|
||||||
|
return fdRangeFrom(minFd, func(fd int) {
|
||||||
|
if runtime_IsPollDescriptor(uintptr(fd)) {
|
||||||
|
// These are the Go runtimes internal netpoll file descriptors.
|
||||||
|
// These file descriptors are operated on deep in the Go scheduler,
|
||||||
|
// and closing those files from underneath Go can result in panics.
|
||||||
|
// There is no issue with keeping them because they are not
|
||||||
|
// executable and are not useful to an attacker anyway. Also we
|
||||||
|
// don't have any choice.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// There's nothing we can do about errors from close(2), and the
|
||||||
|
// only likely error to be seen is EBADF which indicates the fd was
|
||||||
|
// already closed (in which case, we got what we wanted).
|
||||||
|
_ = unix.Close(fd)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// NewSockPair returns a new unix socket pair
|
// NewSockPair returns a new unix socket pair
|
||||||
func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
|
func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
|
||||||
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
|
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
|
||||||
|
Reference in New Issue
Block a user