Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package runc for openSUSE:Factory checked in at 2026-06-29 17:30:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/runc (Old) and /work/SRC/openSUSE:Factory/.runc.new.11887 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "runc" Mon Jun 29 17:30:03 2026 rev:80 rq:1362242 version:1.4.2 Changes: -------- --- /work/SRC/openSUSE:Factory/runc/runc.changes 2026-03-30 18:31:04.270501350 +0200 +++ /work/SRC/openSUSE:Factory/.runc.new.11887/runc.changes 2026-06-29 17:30:38.502611058 +0200 @@ -1,0 +2,7 @@ +Wed May 27 07:23:06 UTC 2026 - Madhankumar Chellamuthu <[email protected]> + +- Update to runc v1.4.2. Upstream changelog is available from + <https://github.com/opencontainers/runc/releases/tag/v1.4.2>. +- runc.keyring has been updated to match the new version from upstream. + +------------------------------------------------------------------- Old: ---- runc-1.4.1.tar.xz runc-1.4.1.tar.xz.asc New: ---- runc-1.4.2.tar.xz runc-1.4.2.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ runc.spec ++++++ --- /var/tmp/diff_new_pack.obsUVb/_old 2026-06-29 17:30:39.078630916 +0200 +++ /var/tmp/diff_new_pack.obsUVb/_new 2026-06-29 17:30:39.086631193 +0200 @@ -27,7 +27,7 @@ %define project github.com/opencontainers/runc Name: runc -Version: 1.4.1 +Version: 1.4.2 %define upstream_version %{version} Release: 0 Summary: Tool for spawning and running OCI containers ++++++ runc-1.4.1.tar.xz -> runc-1.4.2.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/.github/workflows/validate.yml new/runc-1.4.2/.github/workflows/validate.yml --- old/runc-1.4.1/.github/workflows/validate.yml 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/.github/workflows/validate.yml 2026-04-03 00:52:45.000000000 +0200 @@ -263,6 +263,50 @@ ./bootstrap-get-images.sh > get-images.sh git diff --exit-code + conmon: + runs-on: ubuntu-24.04 + steps: + - name: checkout + uses: actions/checkout@v6 + + - name: install runc and conmon deps + # XXX maybe switch to conmon/hack/github-actions-setup if the burden + # to maintain the list of needed packages here is too much to handle. + run: | + sudo apt update + sudo apt -y install libseccomp-dev libglib2.0-dev libsystemd-dev socat + + - name: install Go + uses: actions/setup-go@v6 + with: + go-version: "${{ env.GO_VERSION }}" + + - name: build runc + run: make + + - name: setup bats + uses: bats-core/[email protected] + with: + bats-version: 1.13.0 # As required by conmon in hack/github-actions-setup. + support-install: false + assert-install: false + detik-install: false + file-install: false + + - name: checkout conmon + uses: actions/checkout@v6 + with: + repository: containers/conmon + path: conmon + ref: v2.2.1 + + - name: build conmon + run: cd conmon && make + + - name: run conmon tests + run: | + RUNTIME_BINARY=$(pwd)/runc ./conmon/test/run-tests.sh -j $(nproc) + all-done: needs: - check-go @@ -270,6 +314,7 @@ - codespell - commit - compile-buildtags + - conmon - deps - get-images - keyring diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/CHANGELOG.md new/runc-1.4.2/CHANGELOG.md --- old/runc-1.4.1/CHANGELOG.md 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/CHANGELOG.md 2026-04-03 00:52:45.000000000 +0200 @@ -6,6 +6,19 @@ ## [Unreleased 1.4.z] +## [1.4.2] - 2026-04-02 + +> Я — Земля! Я своих провожаю питомцев. + +### Fixed ### +- A regression in runc v1.3.0 which can result in a stuck `runc exec` or + `runc run` when the container process runs for a short time. (#5208, + #5210, #5216) +- Mount sources that need to be open on the host are now closed earlier during + container start, reducing the total amount of used file descriptors and + helping to avoid hitting the open files limit when handling many such mounts. + (#5177, #5201) + ## [1.4.1] - 2026-03-12 > La guerre n'est pas une aventure. La guerre est une maladie. Comme le typhus. @@ -90,6 +103,9 @@ ### Changed - libct: switch to `(*CPUSet).Fill`. (#4927) - docs/spec-conformance.md: update for spec v1.3.0. (#4948) +- Errors from `runc init` have historically been quite painful to understand + and debug, we have made several improvements to make them more comprehensive + and thus useful when debugging issues. (#5040, #4951, #4928) [CVE-2025-52881]: https://github.com/opencontainers/runc/security/advisories/GHSA-cgrx-mc8f-2prm @@ -1463,7 +1479,8 @@ [1.3.0-rc.1]: https://github.com/opencontainers/runc/compare/v1.2.0...v1.3.0-rc.1 <!-- 1.4.z patch releases --> -[Unreleased 1.4.z]: https://github.com/opencontainers/runc/compare/v1.4.1...release-1.4 +[Unreleased 1.4.z]: https://github.com/opencontainers/runc/compare/v1.4.2...release-1.4 +[1.4.2]: https://github.com/opencontainers/runc/compare/v1.4.1...v1.4.2 [1.4.1]: https://github.com/opencontainers/runc/compare/v1.4.0...v1.4.1 [1.4.0]: https://github.com/opencontainers/runc/compare/v1.4.0-rc.3...v1.4.0 [1.4.0-rc.3]: https://github.com/opencontainers/runc/compare/v1.4.0-rc.2...v1.4.0-rc.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/VERSION new/runc-1.4.2/VERSION --- old/runc-1.4.1/VERSION 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/VERSION 2026-04-03 00:52:45.000000000 +0200 @@ -1 +1 @@ -1.4.1 +1.4.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/libcontainer/mount_linux.go new/runc-1.4.2/libcontainer/mount_linux.go --- old/runc-1.4.1/libcontainer/mount_linux.go 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/libcontainer/mount_linux.go 2026-04-03 00:52:45.000000000 +0200 @@ -110,7 +110,7 @@ if e.source != "" { out += "src=" + e.source + ", " - if e.srcFile != nil { + if e.srcFile != nil && e.srcFile.file != nil { out += "srcType=" + string(e.srcFile.Type) + ", " out += "srcFd=" + strconv.Itoa(int(e.srcFile.file.Fd())) + ", " } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/libcontainer/rootfs_linux.go new/runc-1.4.2/libcontainer/rootfs_linux.go --- old/runc-1.4.1/libcontainer/rootfs_linux.go 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/libcontainer/rootfs_linux.go 2026-04-03 00:52:45.000000000 +0200 @@ -97,6 +97,60 @@ return true } +// setupAndMountToRootfs sets up the mount for a single mount point and mounts it to the rootfs. +func setupAndMountToRootfs(pipe *syncSocket, config *configs.Config, mountConfig *mountConfig, m *configs.Mount) error { + entry := mountEntry{Mount: m} + // Figure out whether we need to request runc to give us an + // open_tree(2)-style mountfd. For idmapped mounts, this is always + // necessary. For bind-mounts, this is only necessary if we cannot + // resolve the parent mount (this is only hit if you are running in a + // userns -- but for rootless the host-side thread can't help). + wantSourceFile := m.IsIDMapped() + if m.IsBind() && !config.RootlessEUID { + if _, err := os.Stat(m.Source); err != nil { + wantSourceFile = true + } + } + if wantSourceFile { + // Request a source file from the host. + if err := writeSyncArg(pipe, procMountPlease, m); err != nil { + return fmt.Errorf("failed to request mountfd for %q: %w", m.Source, err) + } + sync, err := readSyncFull(pipe, procMountFd) + if err != nil { + return fmt.Errorf("mountfd request for %q failed: %w", m.Source, err) + } + if sync.File == nil { + return fmt.Errorf("mountfd request for %q: response missing attached fd", m.Source) + } + defer sync.File.Close() + // Sanity-check to make sure we didn't get the wrong fd back. Note + // that while m.Source might contain symlinks, the (*os.File).Name + // is based on the path provided to os.OpenFile, not what it + // resolves to. So this should never happen. + if sync.File.Name() != m.Source { + return fmt.Errorf("returned mountfd for %q doesn't match requested mount configuration: mountfd path is %q", m.Source, sync.File.Name()) + } + // Unmarshal the procMountFd argument (the file is sync.File). + var src *mountSource + if sync.Arg == nil { + return fmt.Errorf("sync %q is missing an argument", sync.Type) + } + if err := json.Unmarshal(*sync.Arg, &src); err != nil { + return fmt.Errorf("invalid mount fd response argument %q: %w", string(*sync.Arg), err) + } + if src == nil { + return fmt.Errorf("mountfd request for %q: no mount source info received", m.Source) + } + src.file = sync.File + entry.srcFile = src + } + if err := mountToRootfs(mountConfig, entry); err != nil { + return fmt.Errorf("error mounting %q to rootfs at %q: %w", m.Source, m.Destination, err) + } + return nil +} + // prepareRootfs sets up the devices, mount points, and filesystems for use // inside a new mount namespace. It doesn't set anything as ro. You must call // finalizeRootfs after this function to finish setting up the rootfs. @@ -114,54 +168,8 @@ cgroupns: config.Namespaces.Contains(configs.NEWCGROUP), } for _, m := range config.Mounts { - entry := mountEntry{Mount: m} - // Figure out whether we need to request runc to give us an - // open_tree(2)-style mountfd. For idmapped mounts, this is always - // necessary. For bind-mounts, this is only necessary if we cannot - // resolve the parent mount (this is only hit if you are running in a - // userns -- but for rootless the host-side thread can't help). - wantSourceFile := m.IsIDMapped() - if m.IsBind() && !config.RootlessEUID { - if _, err := os.Stat(m.Source); err != nil { - wantSourceFile = true - } - } - if wantSourceFile { - // Request a source file from the host. - if err := writeSyncArg(pipe, procMountPlease, m); err != nil { - return fmt.Errorf("failed to request mountfd for %q: %w", m.Source, err) - } - sync, err := readSyncFull(pipe, procMountFd) - if err != nil { - return fmt.Errorf("mountfd request for %q failed: %w", m.Source, err) - } - if sync.File == nil { - return fmt.Errorf("mountfd request for %q: response missing attached fd", m.Source) - } - defer sync.File.Close() - // Sanity-check to make sure we didn't get the wrong fd back. Note - // that while m.Source might contain symlinks, the (*os.File).Name - // is based on the path provided to os.OpenFile, not what it - // resolves to. So this should never happen. - if sync.File.Name() != m.Source { - return fmt.Errorf("returned mountfd for %q doesn't match requested mount configuration: mountfd path is %q", m.Source, sync.File.Name()) - } - // Unmarshal the procMountFd argument (the file is sync.File). - var src *mountSource - if sync.Arg == nil { - return fmt.Errorf("sync %q is missing an argument", sync.Type) - } - if err := json.Unmarshal(*sync.Arg, &src); err != nil { - return fmt.Errorf("invalid mount fd response argument %q: %w", string(*sync.Arg), err) - } - if src == nil { - return fmt.Errorf("mountfd request for %q: no mount source info received", m.Source) - } - src.file = sync.File - entry.srcFile = src - } - if err := mountToRootfs(mountConfig, entry); err != nil { - return fmt.Errorf("error mounting %q to rootfs at %q: %w", m.Source, m.Destination, err) + if err := setupAndMountToRootfs(pipe, config, mountConfig, m); err != nil { + return err } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/signals.go new/runc-1.4.2/signals.go --- old/runc-1.4.1/signals.go 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/signals.go 2026-04-03 00:52:45.000000000 +0200 @@ -26,14 +26,17 @@ } } handler := make(chan *signalHandler) + + // Ensure that we have a large buffer size so that we do not miss any + // signals in case we are not processing them fast enough. + s := make(chan os.Signal, signalBufferSize) + // signal.Notify is actually quite expensive, as it has to configure the // signal mask and add signal handlers for all signals (all ~65 of them). // So, defer this to a background thread while doing the rest of the io/tty - // setup. + // setup, except for SIGCHLD which is very important (see #5208). + signal.Notify(s, unix.SIGCHLD) go func() { - // ensure that we have a large buffer size so that we do not miss any - // signals in case we are not processing them fast enough. - s := make(chan os.Signal, signalBufferSize) // handle all signals for the process. signal.Notify(s) handler <- &signalHandler{ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.4.1/tests/integration/idmap.bats new/runc-1.4.2/tests/integration/idmap.bats --- old/runc-1.4.1/tests/integration/idmap.bats 2026-03-12 21:23:25.000000000 +0100 +++ new/runc-1.4.2/tests/integration/idmap.bats 2026-04-03 00:52:45.000000000 +0200 @@ -104,7 +104,27 @@ function setup_idmap_basic_mount() { mountname="${1:-1}" - setup_idmap_single_mount 0:100000:65536 0:100000:65536 "$mountname" + destname="${2:-}" + setup_idmap_single_mount 0:100000:65536 0:100000:65536 "$mountname" "$destname" +} + +@test "Check mount source fds are cleaned up with idmapped mounts [userns]" { + setup_idmap_userns + for i in {1..10}; do + setup_idmap_basic_mount 1 "1$i" + setup_idmap_basic_mount 2 "2$i" + done + + update_config '.process.args = ["sh", "-c", "stat -c =%u=%g= /tmp/mount-11/foo.txt"]' + update_config '.process.rlimits = [{ + "type": "RLIMIT_NOFILE", + "soft": 20, + "hard": 20 + }]' + + runc run test_debian + [ "$status" -eq 0 ] + [[ "$output" == *"=0=0="* ]] } @test "simple idmap mount [userns]" {
