Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package runc for openSUSE:Factory checked in at 2021-12-08 22:08:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/runc (Old) and /work/SRC/openSUSE:Factory/.runc.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "runc" Wed Dec 8 22:08:27 2021 rev:42 rq:935875 version:1.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/runc/runc.changes 2021-08-24 10:54:11.404375206 +0200 +++ /work/SRC/openSUSE:Factory/.runc.new.31177/runc.changes 2021-12-08 22:08:37.570853300 +0100 @@ -1,0 +2,26 @@ +Mon Dec 6 04:38:25 UTC 2021 - Aleksa Sarai <[email protected]> + +- Update to runc v1.0.3. Upstream changelog is available from + https://github.com/opencontainers/runc/releases/tag/v1.0.3. CVE-2021-43784 + + * A potential vulnerability was discovered in runc (related to an internal + usage of netlink), however upon further investigation we discovered that + while this bug was exploitable on the master branch of runc, no released + version of runc could be exploited using this bug. The exploit required + being able to create a netlink attribute with a length that would overflow a + uint16 but this was not possible in any released version of runc. For more + information see GHSA-v95c-p5hm-xq8f and CVE-2021-43784. + + Due to an abundance of caution we decided to do an emergency release with + this fix, but to reiterate we do not believe this vulnerability was + possible to exploit. Thanks to Felix Wilhelm from Google Project Zero for + discovering and reporting this vulnerability so quickly. + * Fixed inability to start a container with read-write bind mount of a + read-only fuse host mount. + * Fixed inability to start when read-only /dev in set in spec. + * Fixed not removing sub-cgroups upon container delete, when rootless cgroup + v2 is used with older systemd. + * Fixed returning error from GetStats when hugetlb is unsupported (which + causes excessive logging for kubernetes). + +------------------------------------------------------------------- Old: ---- runc-1.0.2.tar.xz runc-1.0.2.tar.xz.asc New: ---- runc-1.0.3.tar.xz runc-1.0.3.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ runc.spec ++++++ --- /var/tmp/diff_new_pack.BUW2FZ/_old 2021-12-08 22:08:38.050853526 +0100 +++ /var/tmp/diff_new_pack.BUW2FZ/_new 2021-12-08 22:08:38.050853526 +0100 @@ -21,12 +21,12 @@ %define git_version 4144b63817ebcc5b358fc2c8ef95f7cddd709aa7 # Package-wide golang version -%define go_version 1.13 +%define go_version 1.16 %define project github.com/opencontainers/runc Name: runc -Version: 1.0.2 -%define _version 1.0.2 +Version: 1.0.3 +%define _version 1.0.3 Release: 0 Summary: Tool for spawning and running OCI containers License: Apache-2.0 ++++++ runc-1.0.2.tar.xz -> runc-1.0.3.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/.cirrus.yml new/runc-1.0.3/.cirrus.yml --- old/runc-1.0.2/.cirrus.yml 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/.cirrus.yml 2021-12-03 09:17:37.000000000 +0100 @@ -106,7 +106,7 @@ yum config-manager --set-enabled powertools ;; esac - yum install -y -q gcc git iptables jq glibc-static libseccomp-devel make criu + yum install -y -q gcc git iptables jq glibc-static libseccomp-devel make criu fuse-sshfs # install Go curl -fsSL "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" | tar Cxz /usr/local # install bats @@ -118,6 +118,12 @@ cd - # Add a user for rootless tests useradd -u2000 -m -d/home/rootless -s/bin/bash rootless + # Allow root and rootless itself to execute `ssh rootless@localhost` in tests/rootless.sh + ssh-keygen -t ecdsa -N "" -f /root/rootless.key + mkdir -m 0700 -p /home/rootless/.ssh + cp /root/rootless.key /home/rootless/.ssh/id_ecdsa + cat /root/rootless.key.pub >> /home/rootless/.ssh/authorized_keys + chown -R rootless.rootless /home/rootless # set PATH echo 'export PATH=/usr/local/go/bin:/usr/local/bin:$PATH' >> /root/.bashrc # Setup ssh localhost for terminal emulation (script -e did not work) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/.github/workflows/test.yml new/runc-1.0.3/.github/workflows/test.yml --- old/runc-1.0.2/.github/workflows/test.yml 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/.github/workflows/test.yml 2021-12-03 09:17:37.000000000 +0100 @@ -18,7 +18,7 @@ fail-fast: false matrix: # Docker/Moby still builds runc with Go 1.13, so we should still support Go 1.13. - go-version: [1.13.x, 1.15.x, 1.16.x] + go-version: [1.13.x, 1.16.x, 1.17.x] rootless: ["rootless", ""] race: ["-race", ""] @@ -32,7 +32,7 @@ # criu repo sudo add-apt-repository -y ppa:criu/ppa # apt-add-repository runs apt update so we don't have to - sudo apt -q install libseccomp-dev criu + sudo apt -q install libseccomp-dev criu sshfs - name: install go ${{ matrix.go-version }} uses: actions/setup-go@v2 @@ -56,9 +56,10 @@ if: matrix.rootless == 'rootless' run: | sudo useradd -u2000 -m -d/home/rootless -s/bin/bash rootless - # Allow root to execute `ssh rootless@localhost` in tests/rootless.sh + # Allow root and rootless itself to execute `ssh rootless@localhost` in tests/rootless.sh ssh-keygen -t ecdsa -N "" -f $HOME/rootless.key sudo mkdir -m 0700 -p /home/rootless/.ssh + sudo cp $HOME/rootless.key /home/rootless/.ssh/id_ecdsa sudo cp $HOME/rootless.key.pub /home/rootless/.ssh/authorized_keys sudo chown -R rootless.rootless /home/rootless diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/Dockerfile new/runc-1.0.3/Dockerfile --- old/runc-1.0.2/Dockerfile 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/Dockerfile 2021-12-03 09:17:37.000000000 +0100 @@ -32,6 +32,7 @@ libseccomp2 \ pkg-config \ python-minimal \ + sshfs \ sudo \ uidmap \ && apt-get clean \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/VERSION new/runc-1.0.3/VERSION --- old/runc-1.0.2/VERSION 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/VERSION 2021-12-03 09:17:37.000000000 +0100 @@ -1 +1 @@ -1.0.2 +1.0.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/Vagrantfile.fedora34 new/runc-1.0.3/Vagrantfile.fedora34 --- old/runc-1.0.2/Vagrantfile.fedora34 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/Vagrantfile.fedora34 2021-12-03 09:17:37.000000000 +0100 @@ -21,7 +21,7 @@ config exclude kernel,kernel-core config install_weak_deps false update -install iptables gcc make golang-go glibc-static libseccomp-devel bats jq git-core criu +install iptables gcc make golang-go glibc-static libseccomp-devel bats jq git-core criu fuse-sshfs ts run EOF done @@ -30,9 +30,10 @@ # Add a user for rootless tests useradd -u2000 -m -d/home/rootless -s/bin/bash rootless - # Allow root to execute `ssh rootless@localhost` in tests/rootless.sh + # Allow root and rootless itself to execute `ssh rootless@localhost` in tests/rootless.sh ssh-keygen -t ecdsa -N "" -f /root/rootless.key mkdir -m 0700 -p /home/rootless/.ssh + cp /root/rootless.key /home/rootless/.ssh/id_ecdsa cat /root/rootless.key.pub >> /home/rootless/.ssh/authorized_keys chown -R rootless.rootless /home/rootless diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/cgroups/fs2/hugetlb.go new/runc-1.0.3/libcontainer/cgroups/fs2/hugetlb.go --- old/runc-1.0.2/libcontainer/cgroups/fs2/hugetlb.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/cgroups/fs2/hugetlb.go 2021-12-03 09:17:37.000000000 +0100 @@ -30,10 +30,7 @@ } func statHugeTlb(dirPath string, stats *cgroups.Stats) error { - hugePageSizes, err := cgroups.GetHugePageSize() - if err != nil { - return errors.Wrap(err, "failed to fetch hugetlb info") - } + hugePageSizes, _ := cgroups.GetHugePageSize() hugetlbStats := cgroups.HugetlbStats{} for _, pagesize := range hugePageSizes { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/cgroups/systemd/dbus.go new/runc-1.0.3/libcontainer/cgroups/systemd/dbus.go --- old/runc-1.0.2/libcontainer/cgroups/systemd/dbus.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/cgroups/systemd/dbus.go 2021-12-03 09:17:37.000000000 +0100 @@ -4,6 +4,7 @@ import ( "context" + "fmt" "sync" systemdDbus "github.com/coreos/go-systemd/v22/dbus" @@ -54,7 +55,10 @@ conn, err := d.newConnection() if err != nil { - return nil, err + // When dbus-user-session is not installed, we can't detect whether we should try to connect to user dbus or system dbus, so d.dbusRootless is set to false. + // This may fail with a cryptic error "read unix @->/run/systemd/private: read: connection reset by peer: unknown." + // https://github.com/moby/moby/issues/42793 + return nil, fmt.Errorf("failed to connect to dbus (hint: for rootless containers, maybe you need to install dbus-user-session package, see https://github.com/opencontainers/runc/blob/master/docs/cgroup-v2.md): %w", err) } dbusC = conn return conn, nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/cgroups/systemd/v2.go new/runc-1.0.3/libcontainer/cgroups/systemd/v2.go --- old/runc-1.0.2/libcontainer/cgroups/systemd/v2.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/cgroups/systemd/v2.go 2021-12-03 09:17:37.000000000 +0100 @@ -5,7 +5,6 @@ import ( "fmt" "math" - "os" "path/filepath" "strconv" "strings" @@ -307,9 +306,10 @@ return err } - // XXX this is probably not needed, systemd should handle it - err := os.Remove(m.path) - if err != nil && !os.IsNotExist(err) { + // systemd 239 do not remove sub-cgroups. + err := cgroups.RemovePath(m.path) + // cgroups.RemovePath has handled ErrNotExist + if err != nil { return err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/container_linux.go new/runc-1.0.3/libcontainer/container_linux.go --- old/runc-1.0.2/libcontainer/container_linux.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/container_linux.go 2021-12-03 09:17:37.000000000 +0100 @@ -2028,16 +2028,34 @@ return data.Bytes(), nil } +// netlinkError is an error wrapper type for use by custom netlink message +// types. Panics with errors are wrapped in netlinkError so that the recover +// in bootstrapData can distinguish intentional panics. +type netlinkError struct{ error } + // bootstrapData encodes the necessary data in netlink binary format // as a io.Reader. // Consumer can write the data to a bootstrap program // such as one that uses nsenter package to bootstrap the container's // init process correctly, i.e. with correct namespaces, uid/gid // mapping etc. -func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (io.Reader, error) { +func (c *linuxContainer) bootstrapData(cloneFlags uintptr, nsMaps map[configs.NamespaceType]string) (_ io.Reader, Err error) { // create the netlink message r := nl.NewNetlinkRequest(int(InitMsg), 0) + // Our custom messages cannot bubble up an error using returns, instead + // they will panic with the specific error type, netlinkError. In that + // case, recover from the panic and return that as an error. + defer func() { + if r := recover(); r != nil { + if e, ok := r.(netlinkError); ok { + Err = e.error + } else { + panic(r) + } + } + }() + // write cloneFlags r.AddData(&Int32msg{ Type: CloneFlagsAttr, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/integration/checkpoint_test.go new/runc-1.0.3/libcontainer/integration/checkpoint_test.go --- old/runc-1.0.2/libcontainer/integration/checkpoint_test.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/integration/checkpoint_test.go 2021-12-03 09:17:37.000000000 +0100 @@ -133,10 +133,12 @@ ok(t, err) defer remove(imagesDir) + relParentDir, err := filepath.Rel(imagesDir, parentDir) + ok(t, err) checkpointOpts := &libcontainer.CriuOpts{ ImagesDirectory: imagesDir, WorkDirectory: imagesDir, - ParentImage: "../criu-parent", + ParentImage: relParentDir, } dumpLog := filepath.Join(checkpointOpts.WorkDirectory, "dump.log") restoreLog := filepath.Join(checkpointOpts.WorkDirectory, "restore.log") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/message_linux.go new/runc-1.0.3/libcontainer/message_linux.go --- old/runc-1.0.2/libcontainer/message_linux.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/message_linux.go 2021-12-03 09:17:37.000000000 +0100 @@ -3,6 +3,9 @@ package libcontainer import ( + "fmt" + "math" + "github.com/vishvananda/netlink/nl" "golang.org/x/sys/unix" ) @@ -54,6 +57,12 @@ func (msg *Bytemsg) Serialize() []byte { l := msg.Len() + if l > math.MaxUint16 { + // We cannot return nil nor an error here, so we panic with + // a specific type instead, which is handled via recover in + // bootstrapData. + panic(netlinkError{fmt.Errorf("netlink: cannot serialize bytemsg of length %d (larger than UINT16_MAX)", l)}) + } buf := make([]byte, (l+unix.NLA_ALIGNTO-1) & ^(unix.NLA_ALIGNTO-1)) native := nl.NativeEndian() native.PutUint16(buf[0:2], uint16(l)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/libcontainer/rootfs_linux.go new/runc-1.0.3/libcontainer/rootfs_linux.go --- old/runc-1.0.2/libcontainer/rootfs_linux.go 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/libcontainer/rootfs_linux.go 2021-12-03 09:17:37.000000000 +0100 @@ -22,7 +22,6 @@ "github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/userns" "github.com/opencontainers/runc/libcontainer/utils" - libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" @@ -42,7 +41,7 @@ // needsSetupDev returns true if /dev needs to be set up. func needsSetupDev(config *configs.Config) bool { for _, m := range config.Mounts { - if m.Device == "bind" && libcontainerUtils.CleanPath(m.Destination) == "/dev" { + if m.Device == "bind" && utils.CleanPath(m.Destination) == "/dev" { return false } } @@ -154,15 +153,16 @@ // finalizeRootfs sets anything to ro if necessary. You must call // prepareRootfs first. func finalizeRootfs(config *configs.Config) (err error) { - // remount dev as ro if specified + // All tmpfs mounts and /dev were previously mounted as rw + // by mountPropagate. Remount them read-only as requested. for _, m := range config.Mounts { - if libcontainerUtils.CleanPath(m.Destination) == "/dev" { - if m.Flags&unix.MS_RDONLY == unix.MS_RDONLY { - if err := remountReadonly(m); err != nil { - return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination) - } + if m.Flags&unix.MS_RDONLY != unix.MS_RDONLY { + continue + } + if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" { + if err := remountReadonly(m); err != nil { + return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination) } - break } } @@ -432,12 +432,6 @@ return err } } - // Initially mounted rw in mountPropagate, remount to ro if flag set. - if m.Flags&unix.MS_RDONLY != 0 { - if err := remount(m, rootfs); err != nil { - return err - } - } return nil case "bind": if err := prepareBindMount(m, rootfs); err != nil { @@ -1035,7 +1029,22 @@ func remount(m *configs.Mount, rootfs string) error { return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { - return unix.Mount(m.Source, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), "") + flags := uintptr(m.Flags | unix.MS_REMOUNT) + err := unix.Mount(m.Source, procfd, m.Device, flags, "") + if err == nil { + return nil + } + // Check if the source has ro flag... + var s unix.Statfs_t + if err := unix.Statfs(m.Source, &s); err != nil { + return &os.PathError{Op: "statfs", Path: m.Source, Err: err} + } + if s.Flags&unix.MS_RDONLY != unix.MS_RDONLY { + return err + } + // ... and retry the mount with ro flag set. + flags |= unix.MS_RDONLY + return unix.Mount(m.Source, procfd, m.Device, flags, "") }) } @@ -1047,10 +1056,10 @@ flags = m.Flags ) // Delay mounting the filesystem read-only if we need to do further - // operations on it. We need to set up files in "/dev" and tmpfs mounts may - // need to be chmod-ed after mounting. The mount will be remounted ro later - // in finalizeRootfs() if necessary. - if libcontainerUtils.CleanPath(m.Destination) == "/dev" || m.Device == "tmpfs" { + // operations on it. We need to set up files in "/dev", and other tmpfs + // mounts may need to be chmod-ed after mounting. These mounts will be + // remounted ro later in finalizeRootfs(), if necessary. + if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" { flags &= ^unix.MS_RDONLY } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/script/release.sh new/runc-1.0.3/script/release.sh --- old/runc-1.0.2/script/release.sh 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/script/release.sh 2021-12-03 09:17:37.000000000 +0100 @@ -38,7 +38,8 @@ tar xf "$tarball" ( cd "libseccomp-${libseccomp_ver}" - ./configure --prefix="$prefix" --enable-static --disable-shared + ./configure --prefix="$prefix" --libdir="$prefix/lib" \ + --enable-static --disable-shared make install ) mv "$tarball"{,.asc} "$builddir" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/tests/integration/dev.bats new/runc-1.0.3/tests/integration/dev.bats --- old/runc-1.0.2/tests/integration/dev.bats 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/tests/integration/dev.bats 2021-12-03 09:17:37.000000000 +0100 @@ -38,6 +38,10 @@ update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"}] | .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}] + | .process.capabilities.bounding += ["CAP_SYSLOG"] + | .process.capabilities.effective += ["CAP_SYSLOG"] + | .process.capabilities.inheritable += ["CAP_SYSLOG"] + | .process.capabilities.permitted += ["CAP_SYSLOG"] | .process.args |= ["sh"]' runc run -d --console-socket "$CONSOLE_SOCKET" test_deny @@ -72,6 +76,10 @@ update_config ' .linux.resources.devices = [{"allow": false, "access": "rwm"},{"allow": true, "type": "c", "major": 1, "minor": 11, "access": "rw"}] | .linux.devices = [{"path": "/dev/kmsg", "type": "c", "major": 1, "minor": 11}] | .process.args |= ["sh"] + | .process.capabilities.bounding += ["CAP_SYSLOG"] + | .process.capabilities.effective += ["CAP_SYSLOG"] + | .process.capabilities.inheritable += ["CAP_SYSLOG"] + | .process.capabilities.permitted += ["CAP_SYSLOG"] | .hostname = "myhostname"' runc run -d --console-socket "$CONSOLE_SOCKET" test_allow_char diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/tests/integration/mounts.bats new/runc-1.0.3/tests/integration/mounts.bats --- old/runc-1.0.2/tests/integration/mounts.bats 2021-08-20 09:24:11.000000000 +0200 +++ new/runc-1.0.3/tests/integration/mounts.bats 2021-12-03 09:17:37.000000000 +0100 @@ -23,6 +23,7 @@ [[ "${lines[0]}" == *'/tmp/bind/config.json'* ]] } +# https://github.com/opencontainers/runc/issues/2246 @test "runc run [ro tmpfs mount]" { update_config ' .mounts += [{ source: "tmpfs", @@ -34,6 +35,16 @@ runc run test_busybox [ "$status" -eq 0 ] + [[ "${lines[0]}" == *'ro,'* ]] +} + +# https://github.com/opencontainers/runc/issues/3248 +@test "runc run [ro /dev mount]" { + update_config ' .mounts |= map((select(.destination == "/dev") | .options += ["ro"]) // .) + | .process.args |= ["grep", "^tmpfs /dev", "/proc/mounts"]' + + runc run test_busybox + [ "$status" -eq 0 ] [[ "${lines[0]}" == *'ro,'* ]] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/runc-1.0.2/tests/integration/mounts_sshfs.bats new/runc-1.0.3/tests/integration/mounts_sshfs.bats --- old/runc-1.0.2/tests/integration/mounts_sshfs.bats 1970-01-01 01:00:00.000000000 +0100 +++ new/runc-1.0.3/tests/integration/mounts_sshfs.bats 2021-12-03 09:17:37.000000000 +0100 @@ -0,0 +1,40 @@ +#!/usr/bin/env bats + +load helpers + +function setup() { + # Create a ro fuse-sshfs mount; skip the test if it's not working. + local sshfs="sshfs + -o UserKnownHostsFile=/dev/null + -o StrictHostKeyChecking=no + -o PasswordAuthentication=no" + + DIR="$BATS_RUN_TMPDIR/fuse-sshfs" + mkdir -p "$DIR" + + if ! $sshfs -o ro rootless@localhost: "$DIR"; then + skip "test requires working sshfs mounts" + fi + + setup_hello +} + +function teardown() { + # New distros (Fedora 35) do not have fusermount installed + # as a dependency of fuse-sshfs, and good ol' umount works. + fusermount -u "$DIR" || umount "$DIR" + + teardown_bundle +} + +@test "runc run [rw bind mount of a ro fuse sshfs mount]" { + update_config ' .mounts += [{ + type: "bind", + source: "'"$DIR"'", + destination: "/mnt", + options: ["rw", "rprivate", "nosuid", "nodev", "rbind"] + }]' + + runc run test_busybox + [ "$status" -eq 0 ] +}
