Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package conmon for openSUSE:Factory checked in at 2022-05-14 22:53:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/conmon (Old) and /work/SRC/openSUSE:Factory/.conmon.new.1538 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "conmon" Sat May 14 22:53:46 2022 rev:23 rq:976687 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/conmon/conmon.changes 2021-09-26 21:49:05.834806513 +0200 +++ /work/SRC/openSUSE:Factory/.conmon.new.1538/conmon.changes 2022-05-14 22:54:23.683158320 +0200 @@ -1,0 +2,16 @@ +Thu May 5 15:46:07 UTC 2022 - Ferdinand Thiessen <r...@fthiessen.de> + +- Update to version 2.1.0 + * logging: buffer partial messages to journald + * exit: close all fds >= 3 + * fix: cgroup: Free memory_cgroup_file_path if open fails. + Call g_free instead of free. +- Update to version 2.0.32 + * Fix: Avoid mainfd_std{in,out} sharing the same file descriptor. + *exit_command: Fix: unset subreaper attribute before running exit command +- Update to version 2.0.31 + * logging: new mode -l passthrough + * ctr_logs: use container name or ID as SYSLOG_IDENTIFIER for journald + * conmon: Fix: free userdata files before exec cleanup + +------------------------------------------------------------------- Old: ---- conmon-2.0.30.tar.xz New: ---- conmon-2.1.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ conmon.spec ++++++ --- /var/tmp/diff_new_pack.s0vivA/_old 2022-05-14 22:54:24.079158815 +0200 +++ /var/tmp/diff_new_pack.s0vivA/_new 2022-05-14 22:54:24.083158820 +0200 @@ -1,7 +1,7 @@ # # spec file for package conmon # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: conmon -Version: 2.0.30 +Version: 2.1.0 Release: 0 Summary: An OCI container runtime monitor License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.s0vivA/_old 2022-05-14 22:54:24.111158855 +0200 +++ /var/tmp/diff_new_pack.s0vivA/_new 2022-05-14 22:54:24.115158860 +0200 @@ -4,8 +4,8 @@ <param name="scm">git</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">[v]?([^\+]+)(.*)</param> -<param name="revision">v2.0.30</param> -<param name="changesgenerate">enable</param> +<param name="revision">v2.1.0</param> +<param name="changesgenerate">disable</param> </service> <service name="recompress" mode="disabled"> <param name="file">conmon-*.tar</param> ++++++ conmon-2.0.30.tar.xz -> conmon-2.1.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/.github/workflows/integration.yml new/conmon-2.1.0/.github/workflows/integration.yml --- old/conmon-2.0.30/.github/workflows/integration.yml 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/.github/workflows/integration.yml 2022-01-24 21:00:50.000000000 +0100 @@ -12,7 +12,7 @@ steps: - uses: actions/setup-go@v2 with: - go-version: '1.16' + go-version: '1.17' - uses: actions/checkout@v2 - uses: actions/cache@v2 with: @@ -29,7 +29,7 @@ steps: - uses: actions/setup-go@v2 with: - go-version: '1.16' + go-version: '1.17' - uses: actions/checkout@v2 - uses: actions/cache@v2 with: @@ -41,15 +41,16 @@ - run: hack/github-actions-setup - name: Run conmon integration tests run: | - make vendor - sudo make test + sudo make vendor + sudo mkdir -p /var/run/crio + sudo make test-binary cri-o: runs-on: ubuntu-latest steps: - uses: actions/setup-go@v2 with: - go-version: '1.16' + go-version: '1.17' - uses: actions/checkout@v2 - uses: actions/cache@v2 with: @@ -63,7 +64,8 @@ run: | cd cri-o make all test-binaries - sudo -E test/test_runner.sh + # skip seccomp tests because they have permission denied issues in a container + sudo -E test/test_runner.sh $(ls test/ | grep bats | grep -v seccomp) env: JOBS: '2' @@ -72,7 +74,7 @@ steps: - uses: actions/setup-go@v2 with: - go-version: '1.16' + go-version: '1.17' - uses: actions/checkout@v2 - uses: actions/cache@v2 with: @@ -81,16 +83,16 @@ ~/.cache/go-build key: go-integration-podman-${{ hashFiles('**/go.mod') }} restore-keys: go-integration-podman- - # https://github.com/actions/setup-go/issues/107 - - run: | - export PATH=${GOROOT}/bin:$PATH - go version - run: hack/github-actions-setup + - run: | + # https://github.com/actions/setup-go/issues/107 + cp -f `which go` /usr/bin/go + - name: Run Podman integration tests run: | git clone https://github.com/containers/podman cd podman - make bin/podman + make sudo -E ginkgo \ -skip 'run.apparmor.disabled|image.trust.show.--json|run.network.bind.to.HostIP' \ -noColor \ @@ -101,23 +103,22 @@ steps: - uses: actions/setup-go@v2 with: - go-version: '1.16' + go-version: '1.17' - uses: actions/checkout@v2 - uses: actions/cache@v2 with: path: | ~/go/pkg/mod ~/.cache/go-build - key: go-integration-podman-${{ hashFiles('**/go.mod') }} - restore-keys: go-integration-podman- - # https://github.com/actions/setup-go/issues/107 - - run: | - export PATH=${GOROOT}/bin:$PATH - go version + key: go-integration-podman-system-${{ hashFiles('**/go.mod') }} + restore-keys: go-integration-podman-system- - run: hack/github-actions-setup - name: Run Podman system tests run: | + # https://github.com/actions/setup-go/issues/107 + export PATH=${GOROOT}/bin:$PATH git clone https://github.com/containers/podman cd podman - make bin/podman + make bin/podman bin/rootlessport + sudo mkdir -p /usr/local/libexec/podman && sudo cp bin/rootlessport /usr/local/libexec/podman sudo -E make localsystem diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/VERSION new/conmon-2.1.0/VERSION --- old/conmon-2.0.30/VERSION 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/VERSION 2022-01-24 21:00:50.000000000 +0100 @@ -1 +1 @@ -2.0.30 +2.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/contrib/cirrus/cri-o_test.sh new/conmon-2.1.0/contrib/cirrus/cri-o_test.sh --- old/conmon-2.0.30/contrib/cirrus/cri-o_test.sh 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/contrib/cirrus/cri-o_test.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,35 +0,0 @@ -#!/bin/bash - -set -e -source $(dirname $0)/lib.sh - -req_env_var SRC SCRIPT_BASE CRIO_SRC OS_RELEASE_ID OS_RELEASE_VER - -cd "$CRIO_SRC" - -if [[ ! "$OS_RELEASE_ID" =~ fedora ]]; then - bad_os_id_ver -fi - -msg "Building binaries required for testing" -ooe.sh make test-binaries - -# TODO: Around the CRI-O 1.16 timeframe, the network tests -# would fail without this patch. The same problem did not -# occur on RHEL/CentOS. Countless hours were spent debugging -# but the root-cause was never found. This is a workaround. -PATCH="$SRC/$SCRIPT_BASE/network_bats.patch" -cd "$CRIO_SRC" -warn "WARNING: Applying $PATCH" -git apply --index --apply --ignore-space-change --recount "$PATCH" - -# Assume cri-o and all dependencies are installed from packages -# and conmon installed using build_and_replace_conmon() -export CRIO_BINARY=/usr/bin/crio -export CONMON_BINARY=/usr/libexec/crio/conmon -export PAUSE_BINARY=/usr/libexec/crio/pause -export CRIO_CNI_PLUGIN=/usr/libexec/cni - -msg "Executing cri-o integration tests (typical 10 - 20 min)" -cd "$CRIO_SRC" -timeout --foreground --kill-after=5m 60m ./test/test_runner.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/contrib/cirrus/lib.sh new/conmon-2.1.0/contrib/cirrus/lib.sh --- old/conmon-2.0.30/contrib/cirrus/lib.sh 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/contrib/cirrus/lib.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,155 +0,0 @@ - - -# Library of common, shared utility functions. This file is intended -# to be sourced by other scripts, not called directly. - -# BEGIN Global export of all variables -set -a - -# Due to differences across platforms and runtime execution environments, -# handling of the (otherwise) default shell setup is non-uniform. Rather -# than attempt to workaround differences, simply force-load/set required -# items every time this library is utilized. -USER="$(whoami)" -HOME="$(getent passwd $USER | cut -d : -f 6)" -# Some platforms set and make this read-only -[[ -n "$UID" ]] || \ - UID=$(getent passwd $USER | cut -d : -f 3) - -# Automation library installed at image-build time, -# defining $AUTOMATION_LIB_PATH in this file. -if [[ -r "/etc/automation_environment" ]]; then - source /etc/automation_environment -fi -# shellcheck disable=SC2154 -if [[ -n "$AUTOMATION_LIB_PATH" ]]; then - # shellcheck source=/usr/share/automation/lib/common_lib.sh - source $AUTOMATION_LIB_PATH/common_lib.sh -else - ( - echo "WARNING: It does not appear that containers/automation was installed." - echo " Functionality of most of this library will be negatively impacted" - echo " This ${BASH_SOURCE[0]} was loaded by ${BASH_SOURCE[1]}" - ) > /dev/stderr -fi - -# Filepath containing CI-Automation wide shell env. vars. -ENVLIB=${ENVLIB:-/etc/ci_environment} -if [[ -r "$ENVLIB" ]]; then source "$ENVLIB"; fi - -OS_RELEASE_ID="$(source /etc/os-release; echo $ID)" -# GCE image-name compatible string representation of distribution _major_ version -OS_RELEASE_VER="$(source /etc/os-release; echo $VERSION_ID | tr -d '.')" -# Combined to ease some usage -OS_REL_VER="${OS_RELEASE_ID}-${OS_RELEASE_VER}" - -GOPATH=/var/tmp/go -CIRRUS_WORKING_DIR="${CIRRUS_WORKING_DIR:-$(realpath $(dirname ${BASH_SOURCE[0]})/../../)}" -SCRIPT_BASE=${SCRIPT_BASE:-./contrib/cirrus} -CIRRUS_REPO_NAME=${CIRRUS_REPO_NAME-$(dirname $0)} - -# Cirrus only sets $CIRRUS_BASE_SHA properly for PRs, but $EPOCH_TEST_COMMIT -# needs to be set from this value in order for `make validate` to run properly. -# When running get_ci_vm.sh, most $CIRRUS_xyz variables are empty. Attempt -# to accomidate both branch and get_ci_vm.sh testing by discovering the base -# branch SHA value. -# shellcheck disable=SC2154 -if [[ -z "$CIRRUS_BASE_SHA" ]] && [[ -z "$CIRRUS_TAG" ]] -then # Operating on a branch, or under `get_ci_vm.sh` - CIRRUS_BASE_SHA=$(git rev-parse ${UPSTREAM_REMOTE:-origin}/main) -elif [[ -z "$CIRRUS_BASE_SHA" ]] -then # Operating on a tag - CIRRUS_BASE_SHA=$(git rev-parse HEAD) -fi -# The starting place for linting and code validation -EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA" - -CONMON_SLUG="${CONMON_SLUG:-github.com/containers/conmon}" -CRIO_REPO="${CRIO_REPO:-https://github.com/cri-o/cri-o.git}" -CRIO_SLUG="${CRIO_SLUG:-github.com/cri-o/cri-o}" - -# END Global export of all variables -set +a - -bad_os_id_ver() { - die "Unknown/Unsupported distro. $OS_RELEASE_ID and/or version $OS_RELEASE_VER" -} - -install_crio_repo() { - req_env_vars GOPATH CRIO_SRC CRIO_REPO - msg "Cloning current CRI-O Source" - rm -rf "$CRIO_SRC" # just in case - ooe.sh git clone "$CRIO_REPO" "$CRIO_SRC" - - # Install CRI-O - cd $CRIO_SRC - ooe.sh make PREFIX=/usr - ooe.sh make install PREFIX=/usr -} - -install_testing_deps() { - req_env_vars GOPATH CRIO_SRC - - msg "Installing required go packages into \$GOPATH" - for toolpath in \ - tools/godep \ - onsi/ginkgo \ - onsi/gomega \ - cloudflare/cfssl/cmd/... \ - jteeuwen/go-bindata/go-bindata \ - cpuguy83/go-md2man \ - urfave/cli \ - containers/image/storage - do - go get -d "github.com/$toolpath" - done - - msg "Installing latest upstream version of BATS" - ooe.sh git clone https://github.com/bats-core/bats-core.git /tmp/bats - cd /tmp/bats - ooe.sh ./install.sh /usr - rm -rf /tmp/bats - - msg "Installing helper script for CNI plugin test" - cd "$CRIO_SRC" - mkdir -p /opt/cni/bin/ - # Search path for helper is difficult to control - ooe.sh install -D -m 0755 test/cni_plugin_helper.bash /usr/libexec/cni/ - # Helper hard-codes cni binary path :( - ooe.sh ln -fv /usr/libexec/cni/* /opt/cni/bin/ - - msg "Installing registry configuration" - mkdir -p /etc/containers/registries.d/ - ooe.sh install -D -m 0644 test/redhat_sigstore.yaml \ - /etc/containers/registries.d/registry.access.redhat.com.yaml -} - -# Needed for e2e tests -selinux_permissive(){ - warn "Entering SELinux Permissive mode, will switch to enforcing upon shell exit" - trap "setenforce 1" EXIT - setenforce 0 -} - -build_and_replace_conmon() { - req_env_vars SRC - - NEWNAME=.original_packaged_conmon - msg "Renaming conmon binaries from RPMs" - find /usr -type f -name conmon | - while read CONMON_FILEPATH - do - NEWPATH="$(dirname $CONMON_FILEPATH)/$NEWNAME" - [[ -r "$NEWPATH" ]] || mv -v "$CONMON_FILEPATH" "$NEWPATH" - done - - msg "Building conmon" - cd $SRC - - ooe.sh make - msg "Installing conmon" - ooe.sh make crio PREFIX=/usr - # Use same version for podman in case ever needed - ooe.sh ln -fv /usr/libexec/crio/conmon /usr/libexec/podman/conmon - ooe.sh restorecon -R /usr/bin -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/contrib/cirrus/network_bats.patch new/conmon-2.1.0/contrib/cirrus/network_bats.patch --- old/conmon-2.0.30/contrib/cirrus/network_bats.patch 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/contrib/cirrus/network_bats.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -diff --git a/test/network.bats b/test/network.bats -index d4fd2ee21..d3808aaad 100644 ---- a/test/network.bats -+++ b/test/network.bats -@@ -185,17 +185,3 @@ function teardown() { - num_allocated=$(ls /var/lib/cni/networks/crionet_test_args | wc -l) - [[ "${num_allocated}" == "0" ]] - } -- --@test "Clean up network if pod sandbox fails after plugin success" { -- start_crio "" "" "" "" "prepare_plugin_test_args_network_conf_malformed_result" -- -- run crictl runp "$TESTDATA"/sandbox_config.json -- echo "$output" -- [ "$status" -ne 0 ] -- -- # ensure that the server cleaned up sandbox networking if the sandbox -- # failed during network setup after the CNI plugin itself succeeded -- rm -f /var/lib/cni/networks/crionet_test_args/last_reserved_ip -- num_allocated=$(ls /var/lib/cni/networks/crionet_test_args | wc -l) -- [[ "${num_allocated}" == "0" ]] --} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/contrib/cirrus/setup_environment.sh new/conmon-2.1.0/contrib/cirrus/setup_environment.sh --- old/conmon-2.0.30/contrib/cirrus/setup_environment.sh 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/contrib/cirrus/setup_environment.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,46 +0,0 @@ -#!/bin/bash - -set -e -source $(dirname $0)/lib.sh - -req_env_vars USER HOME ENVLIB SCRIPT_BASE CIRRUS_REPO_NAME CIRRUS_WORKING_DIR -req_env_vars GOPATH CRIO_SLUG - -cd "$CIRRUS_WORKING_DIR" # for clarity of initial conditions - -# Setup env. vars common to all tasks/scripts/platforms and -# ensure they return for every following script execution. -MARK="# Added by $0, manual changes will be lost." -touch "$ENVLIB" -if ! grep -q "$MARK" "$ENVLIB" -then - cat > "$ENVLIB" <<EOF -$MARK -SRC="$CIRRUS_WORKING_DIR" -CRIO_SRC="$GOPATH/src/$CRIO_SLUG" -$(go env) -PATH="$PATH:$GOPATH/bin:/usr/local/bin" -EOF - source "$ENVLIB" - - show_env_vars - - if [[ ! "$OS_RELEASE_ID" =~ fedora ]]; then - bad_os_id_ver - fi - install_crio_repo - install_testing_deps - build_and_replace_conmon - - msg "Setting read_only flag to false" - sed -i 's/read_only = true/read_only = false/g' /etc/crio/crio.conf - - msg "Removing nodev flag" - sed -i 's/nodev//g' /etc/containers/storage.conf - - msg "Configuring firewall/networking for integration tests" - ooe.sh iptables -F - ooe.sh iptables -t nat -I POSTROUTING -s 127.0.0.1 ! -d 127.0.0.1 -j MASQUERADE - msg "Current IPTables:" - msg "$(iptables -L -n -v)" -fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/hack/github-actions-setup new/conmon-2.1.0/hack/github-actions-setup --- old/conmon-2.0.30/hack/github-actions-setup 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/hack/github-actions-setup 2022-01-24 21:00:50.000000000 +0100 @@ -18,6 +18,7 @@ install_runc install_cni_plugins install_testdeps + setup_etc_subid } prepare_system() { @@ -132,4 +133,10 @@ popd } +setup_etc_subid() { + echo "containers:200000:65536" | sudo tee -a /etc/subuid + echo "containers:200000:65536" | sudo tee -a /etc/subgid + +} + main "$@" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/hack/kubernetes-e2e new/conmon-2.1.0/hack/kubernetes-e2e --- old/conmon-2.0.30/hack/kubernetes-e2e 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/hack/kubernetes-e2e 2022-01-24 21:00:50.000000000 +0100 @@ -28,7 +28,7 @@ journalctl --no-pager -u crio # Start Kubernetes -GOROOT="$GOROOT_1_16_X64" +GOROOT="$GOROOT_1_17_X64" GOPATH="$HOME/go" PATH="$GOROOT/bin:$PATH" K8SPATH="$GOPATH/src/k8s.io" @@ -89,6 +89,7 @@ export KUBE_MASTER_URL=$IP export KUBE_MASTER_IP=$IP export KUBE_MASTER=$IP +export HOSTNAME_OVERRIDE=$IP export GINKGO_PARALLEL_NODES=4 export GINKGO_PARALLEL=y diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/meson.build new/conmon-2.1.0/meson.build --- old/conmon-2.0.30/meson.build 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/meson.build 2022-01-24 21:00:50.000000000 +0100 @@ -34,7 +34,14 @@ language : 'c') glib = dependency('glib-2.0') -libdl = cc.find_library('dl') + +cc = meson.get_compiler('c') +null_dep = dependency('', required : false) +if cc.has_function('dlopen') + libdl = null_dep +else + libdl = cc.find_library('dl') +endif executable('conmon', ['src/conmon.c', @@ -75,4 +82,3 @@ install : true, install_dir : join_paths(get_option('libexecdir'), 'podman'), ) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/runner/conmon/conmon.go new/conmon-2.1.0/runner/conmon/conmon.go --- old/conmon-2.0.30/runner/conmon/conmon.go 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/runner/conmon/conmon.go 2022-01-24 21:00:50.000000000 +0100 @@ -22,6 +22,7 @@ pidFile string stdout io.Writer stderr io.Writer + stdin io.Reader parentStartPipe *os.File parentAttachPipe *os.File @@ -61,6 +62,7 @@ ci.cmd.Stdout = ci.stdout ci.cmd.Stderr = ci.stderr + ci.cmd.Stdin = ci.stdin return ci, nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/runner/conmon/options.go new/conmon-2.1.0/runner/conmon/options.go --- old/conmon-2.0.30/runner/conmon/options.go 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/runner/conmon/options.go 2022-01-24 21:00:50.000000000 +0100 @@ -30,6 +30,13 @@ } } +func WithStdin(stdin io.Reader) ConmonOption { + return func(ci *ConmonInstance) error { + ci.stdin = stdin + return nil + } +} + func WithPath(path string) ConmonOption { return func(ci *ConmonInstance) error { ci.path = path diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/runner/conmon_test/conmon_test.go new/conmon-2.1.0/runner/conmon_test/conmon_test.go --- old/conmon-2.0.30/runner/conmon_test/conmon_test.go 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/runner/conmon_test/conmon_test.go 2022-01-24 21:00:50.000000000 +0100 @@ -9,6 +9,8 @@ "github.com/containers/conmon/runner/conmon" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/pkg/errors" + "golang.org/x/sys/unix" ) var _ = Describe("conmon", func() { @@ -71,6 +73,18 @@ Expect(err).To(BeNil()) }) AfterEach(func() { + for { + // There is a race condition on the directory deletion + // as conmon could still be running and creating files + // under tmpDir. Attempt rmdir again if it fails with + // ENOTEMPTY. + err := os.RemoveAll(tmpDir) + if err != nil && errors.Is(err, unix.ENOTEMPTY) { + continue + } + Expect(err).To(BeNil()) + break + } Expect(os.RemoveAll(tmpDir)).To(BeNil()) err := os.Chdir(origCwd) Expect(err).To(BeNil()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/runner/conmon_test/ctr_logs_test.go new/conmon-2.1.0/runner/conmon_test/ctr_logs_test.go --- old/conmon-2.0.30/runner/conmon_test/ctr_logs_test.go 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/runner/conmon_test/ctr_logs_test.go 2022-01-24 21:00:50.000000000 +0100 @@ -55,6 +55,11 @@ _, err := os.Stat(tmpLogPath) Expect(err).To(BeNil()) }) + It("log driver as passthrough should pass", func() { + stdout, stderr := getConmonOutputGivenLogOpts(conmon.WithLogDriver("passthrough", "")) + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(BeEmpty()) + }) It("log driver as k8s-file with invalid path should fail", func() { _, stderr := getConmonOutputGivenLogOpts(conmon.WithLogDriver("k8s-file", invalidPath)) Expect(stderr).To(ContainSubstring("Failed to open log file")) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/runner/conmon_test/suite_test.go new/conmon-2.1.0/runner/conmon_test/suite_test.go --- old/conmon-2.0.30/runner/conmon_test/suite_test.go 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/runner/conmon_test/suite_test.go 2022-01-24 21:00:50.000000000 +0100 @@ -37,8 +37,9 @@ func getConmonOutputGivenOptions(options ...conmon.ConmonOption) (string, string) { var stdout bytes.Buffer var stderr bytes.Buffer + var stdin bytes.Buffer - options = append(options, conmon.WithStdout(&stdout), conmon.WithStderr(&stderr)) + options = append(options, conmon.WithStdout(&stdout), conmon.WithStderr(&stderr), conmon.WithStdin(&stdin)) ci, err := conmon.CreateAndExecConmon(options...) Expect(err).To(BeNil()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/cgroup.c new/conmon-2.1.0/src/cgroup.c --- old/conmon-2.0.30/src/cgroup.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/cgroup.c 2022-01-24 21:00:50.000000000 +0100 @@ -143,6 +143,7 @@ _cleanup_close_ int cfd = open(memory_cgroup_file_path, O_WRONLY | O_CLOEXEC); if (cfd == -1) { nwarnf("Failed to open %s", memory_cgroup_file_path); + g_free(memory_cgroup_file_path); return; } @@ -197,7 +198,7 @@ /* End of input */ close(fd); oom_event_fd = -1; - free(cgroup_event_control_path); + g_free(cgroup_event_control_path); return G_SOURCE_REMOVE; } @@ -226,7 +227,7 @@ if (num_read == 0) { close(fd); oom_event_fd = -1; - free(cgroup_event_control_path); + g_free(cgroup_event_control_path); return G_SOURCE_REMOVE; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/close_fds.c new/conmon-2.1.0/src/close_fds.c --- old/conmon-2.0.30/src/close_fds.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/close_fds.c 2022-01-24 21:00:50.000000000 +0100 @@ -80,3 +80,27 @@ close(fd); } } + +void close_all_fds_ge_than(int firstfd) +{ + struct dirent *ent; + DIR *d; + + d = opendir("/proc/self/fd"); + if (!d) + return; + + for (ent = readdir(d); ent; ent = readdir(d)) { + int fd; + + if (ent->d_name[0] == '.') + continue; + + fd = atoi(ent->d_name); + if (fd == dirfd(d)) + continue; + if (fd >= firstfd) + close(fd); + } + closedir(d); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/close_fds.h new/conmon-2.1.0/src/close_fds.h --- old/conmon-2.0.30/src/close_fds.h 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/close_fds.h 2022-01-24 21:00:50.000000000 +0100 @@ -1 +1,2 @@ void close_other_fds(); +void close_all_fds_ge_than(int firstfd); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/conmon.c new/conmon-2.1.0/src/conmon.c --- old/conmon-2.0.30/src/conmon.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/conmon.c 2022-01-24 21:00:50.000000000 +0100 @@ -25,6 +25,16 @@ #include <sys/stat.h> #include <locale.h> +static void disconnect_std_streams(int dev_null_r, int dev_null_w) +{ + if (dup2(dev_null_r, STDIN_FILENO) < 0) + pexit("Failed to dup over stdin"); + if (dup2(dev_null_w, STDOUT_FILENO) < 0) + pexit("Failed to dup over stdout"); + if (dup2(dev_null_w, STDERR_FILENO) < 0) + pexit("Failed to dup over stderr"); +} + int main(int argc, char *argv[]) { setlocale(LC_ALL, ""); @@ -114,13 +124,8 @@ /* Disconnect stdio from parent. We need to do this, because the parent is waiting for the stdout to end when the intermediate child dies */ - if (dup2(dev_null_r, STDIN_FILENO) < 0) - pexit("Failed to dup over stdin"); - if (dup2(dev_null_w, STDOUT_FILENO) < 0) - pexit("Failed to dup over stdout"); - if (dup2(dev_null_w, STDERR_FILENO) < 0) - pexit("Failed to dup over stderr"); - + if (!logging_is_passthrough()) + disconnect_std_streams(dev_null_r, dev_null_w); /* Create a new session group */ setsid(); @@ -193,7 +198,7 @@ /* Setup endpoint for attach */ _cleanup_free_ char *attach_symlink_dir_path = NULL; - if (opt_bundle_path != NULL) { + if (opt_bundle_path != NULL && !logging_is_passthrough()) { attach_symlink_dir_path = setup_attach_socket(); dummyfd = setup_terminal_control_fifo(); setup_console_fifo(); @@ -227,27 +232,28 @@ if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) _pexit("Failed to unblock signals"); - if (workerfd_stdin < 0) - workerfd_stdin = dev_null_r; - if (dup2(workerfd_stdin, STDIN_FILENO) < 0) - _pexit("Failed to dup over stdin"); - if (workerfd_stdin != dev_null_r && fchmod(STDIN_FILENO, 0777) < 0) - nwarn("Failed to chown stdin"); - - if (workerfd_stdout < 0) - workerfd_stdout = dev_null_w; - if (dup2(workerfd_stdout, STDOUT_FILENO) < 0) - _pexit("Failed to dup over stdout"); - if (workerfd_stdout != dev_null_w && fchmod(STDOUT_FILENO, 0777) < 0) - nwarn("Failed to chown stdout"); - - if (workerfd_stderr < 0) - workerfd_stderr = workerfd_stdout; - if (dup2(workerfd_stderr, STDERR_FILENO) < 0) - _pexit("Failed to dup over stderr"); - if (workerfd_stderr != dev_null_w && fchmod(STDERR_FILENO, 0777) < 0) - nwarn("Failed to chown stderr"); - + if (!logging_is_passthrough()) { + if (workerfd_stdin < 0) + workerfd_stdin = dev_null_r; + if (dup2(workerfd_stdin, STDIN_FILENO) < 0) + _pexit("Failed to dup over stdin"); + if (workerfd_stdin != dev_null_r && fchmod(STDIN_FILENO, 0777) < 0) + nwarn("Failed to chmod stdin"); + + if (workerfd_stdout < 0) + workerfd_stdout = dev_null_w; + if (dup2(workerfd_stdout, STDOUT_FILENO) < 0) + _pexit("Failed to dup over stdout"); + if (workerfd_stdout != dev_null_w && fchmod(STDOUT_FILENO, 0777) < 0) + nwarn("Failed to chmod stdout"); + + if (workerfd_stderr < 0) + workerfd_stderr = workerfd_stdout; + if (dup2(workerfd_stderr, STDERR_FILENO) < 0) + _pexit("Failed to dup over stderr"); + if (workerfd_stderr != dev_null_w && fchmod(STDERR_FILENO, 0777) < 0) + nwarn("Failed to chmod stderr"); + } /* If LISTEN_PID env is set, we need to set the LISTEN_PID it to the new child process */ char *listenpid = getenv("LISTEN_PID"); @@ -287,6 +293,9 @@ exit(127); } + if (logging_is_passthrough()) + disconnect_std_streams(dev_null_r, dev_null_w); + if ((signal(SIGTERM, on_sig_exit) == SIG_ERR) || (signal(SIGQUIT, on_sig_exit) == SIG_ERR) || (signal(SIGINT, on_sig_exit) == SIG_ERR)) pexit("Failed to register the signal handler"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/conn_sock.c new/conmon-2.1.0/src/conn_sock.c --- old/conmon-2.0.30/src/conn_sock.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/conn_sock.c 2022-01-24 21:00:50.000000000 +0100 @@ -524,4 +524,8 @@ if (local_mainfd_stdin.readers == NULL) return; g_ptr_array_foreach(local_mainfd_stdin.readers, close_sock, NULL); + + if (remote_attach_sock.fd >= 0) + close(remote_attach_sock.fd); + remote_attach_sock.fd = -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/ctr_exit.c new/conmon-2.1.0/src/ctr_exit.c --- old/conmon-2.0.30/src/ctr_exit.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/ctr_exit.c 2022-01-24 21:00:50.000000000 +0100 @@ -5,12 +5,15 @@ #include "utils.h" #include "parent_pipe_fd.h" #include "globals.h" +#include "ctr_logging.h" +#include "close_fds.h" #include <errno.h> #include <glib.h> #include <glib-unix.h> #include <signal.h> #include <stdlib.h> +#include <sys/prctl.h> #include <unistd.h> volatile pid_t container_pid = -1; @@ -133,15 +136,25 @@ void do_exit_command() { - if (sync_pipe_fd > 0) { - close(sync_pipe_fd); - sync_pipe_fd = -1; - } - if (signal(SIGCHLD, SIG_DFL) == SIG_ERR) { _pexit("Failed to reset signal for SIGCHLD"); } + /* + * Close everything except stdin, stdout and stderr. + */ + close_all_fds_ge_than(3); + + /* + * We don't want the exit command to be reaped by the parent conmon + * as that would prevent double-fork from doing its job. + * Unfortunately, that also means that any new subchildren from + * still running processes could also get lost + */ + if (prctl(PR_SET_CHILD_SUBREAPER, 0) != 0) { + nwarn("Failed to disable self subreaper attribute - might wait for indirect children a long time"); + } + pid_t exit_pid = fork(); if (exit_pid < 0) { _pexit("Failed to fork"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/ctr_logging.c new/conmon-2.1.0/src/ctr_logging.c --- old/conmon-2.0.30/src/ctr_logging.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/ctr_logging.c 2022-01-24 21:00:50.000000000 +0100 @@ -1,6 +1,7 @@ #define _GNU_SOURCE #include "ctr_logging.h" #include "cli.h" +#include "config.h" #include <string.h> // if the systemd development files were found, we can log to systemd @@ -24,6 +25,7 @@ /* Different types of container logging */ static gboolean use_journald_logging = FALSE; static gboolean use_k8s_logging = FALSE; +static gboolean use_logging_passthrough = FALSE; /* Value the user must input for each log driver */ static const char *const K8S_FILE_STRING = "k8s-file"; @@ -37,13 +39,22 @@ static char *k8s_log_path = NULL; /* journald log file parameters */ +// short ID length #define TRUNC_ID_LEN 12 +// MESSAGE= #define MESSAGE_EQ_LEN 8 +// PRIORITY=x #define PRIORITY_EQ_LEN 10 +// CONTAINER_ID_FULL= #define CID_FULL_EQ_LEN 18 +// CONTAINER_ID= #define CID_EQ_LEN 13 +// CONTAINER_NAME= #define NAME_EQ_LEN 15 +// CONTAINER_PARTIAL_MESSAGE=true #define PARTIAL_MESSAGE_EQ_LEN 30 +// SYSLOG_IDENTIFIER= +#define SYSLOG_IDENTIFIER_EQ_LEN 18 static char short_cuuid[TRUNC_ID_LEN + 1]; static char *cuuid = NULL; static char *name = NULL; @@ -54,6 +65,8 @@ static char *container_name = NULL; static char *container_tag = NULL; static size_t container_tag_len; +static char *syslog_identifier = NULL; +static size_t syslog_identifier_len; typedef struct { int iovcnt; @@ -71,6 +84,11 @@ static void reopen_k8s_file(void); +gboolean logging_is_passthrough(void) +{ + return use_logging_passthrough; +} + /* * configures container log specific information, such as the drivers the user * called with and the max log size for log file types. For the log file types @@ -117,15 +135,19 @@ if (tag) { container_tag = g_strdup_printf("CONTAINER_TAG=%s", tag); container_tag_len = strlen(container_tag); - } - /* To maintain backwards compatibility with older versions of conmon, we need to skip setting - * the name value if it isn't present - */ - if (name) { + syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", tag); + syslog_identifier_len = strlen(syslog_identifier); + } else if (name) { /* save the length so we don't have to compute every sd_journal_* call */ name_len = strlen(name); container_name = g_strdup_printf("CONTAINER_NAME=%s", name); + + syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", name); + syslog_identifier_len = name_len + SYSLOG_IDENTIFIER_EQ_LEN; + } else { + syslog_identifier = g_strdup_printf("SYSLOG_IDENTIFIER=%s", short_cuuid); + syslog_identifier_len = TRUNC_ID_LEN + SYSLOG_IDENTIFIER_EQ_LEN; } } } @@ -160,6 +182,14 @@ return; } + if (!strcmp(driver, "passthrough")) { + if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO)) + nexitf("cannot use a tty with passthrough logging mode to prevent attacks via TIOCSTI"); + + use_logging_passthrough = TRUE; + return; + } + if (!strcmp(driver, JOURNALD_FILE_STRING)) { use_journald_logging = TRUE; return; @@ -201,10 +231,19 @@ /* write to systemd journal. If the pipe is stdout, write with notice priority, - * otherwise, write with error priority + * otherwise, write with error priority. Partial lines (that don't end in a newline) are buffered + * between invocations. A 0 buflen argument forces a buffered partial line to be flushed. */ int write_journald(int pipe, char *buf, ssize_t buflen) { + static char stdout_partial_buf[STDIO_BUF_SIZE]; + static size_t stdout_partial_buf_len = 0; + static char stderr_partial_buf[STDIO_BUF_SIZE]; + static size_t stderr_partial_buf_len = 0; + + char *partial_buf; + size_t *partial_buf_len; + /* When using writev_buffer_append_segment, we should never approach the number of * entries necessary to flush the buffer. Therefore, the fd passed in is for /dev/null */ @@ -217,15 +256,31 @@ * to be changed if this convention is changed. */ const char *message_priority = "PRIORITY=6"; - if (pipe == STDERR_PIPE) + if (pipe == STDERR_PIPE) { message_priority = "PRIORITY=3"; + partial_buf = stderr_partial_buf; + partial_buf_len = &stderr_partial_buf_len; + } else { + partial_buf = stdout_partial_buf; + partial_buf_len = &stdout_partial_buf_len; + } ptrdiff_t line_len = 0; - while (buflen > 0) { + while (buflen > 0 || *partial_buf_len > 0) { writev_buffer_t bufv = {0}; - bool partial = get_line_len(&line_len, buf, buflen); + bool partial = buflen == 0 || get_line_len(&line_len, buf, buflen); + + /* If this is a partial line, and we have capacity to buffer it, buffer it and return. + * The capacity of the partial_buf is one less than its size so that we can always add + * a null terminating char later */ + if (buflen && partial && ((unsigned long)line_len < (STDIO_BUF_SIZE - *partial_buf_len))) { + memcpy(partial_buf + *partial_buf_len, buf, line_len); + *partial_buf_len += line_len; + return 0; + } + /* sd_journal_* doesn't have an option to specify the number of bytes to write in the message, and instead writes the * entire string. Copying every line doesn't make very much sense, so instead we do this tmp_line_end * hack to emulate separate strings. @@ -233,14 +288,15 @@ char tmp_line_end = buf[line_len]; buf[line_len] = '\0'; - _cleanup_free_ char *message = g_strdup_printf("MESSAGE=%s", buf); - if (writev_buffer_append_segment(dev_null, &bufv, message, line_len + MESSAGE_EQ_LEN) < 0) + ssize_t msg_len = line_len + MESSAGE_EQ_LEN + *partial_buf_len; + partial_buf[*partial_buf_len] = '\0'; + _cleanup_free_ char *message = g_strdup_printf("MESSAGE=%s%s", partial_buf, buf); + if (writev_buffer_append_segment(dev_null, &bufv, message, msg_len) < 0) return -1; /* Restore state of the buffer */ buf[line_len] = tmp_line_end; - if (writev_buffer_append_segment(dev_null, &bufv, container_id_full, cuuid_len + CID_FULL_EQ_LEN) < 0) return -1; @@ -257,6 +313,9 @@ if (name && writev_buffer_append_segment(dev_null, &bufv, container_name, name_len + NAME_EQ_LEN) < 0) return -1; + if (writev_buffer_append_segment(dev_null, &bufv, syslog_identifier, syslog_identifier_len) < 0) + return -1; + /* per docker journald logging format, CONTAINER_PARTIAL_MESSAGE is set to true if it's partial, but otherwise not set. */ if (partial && writev_buffer_append_segment(dev_null, &bufv, "CONTAINER_PARTIAL_MESSAGE=true", PARTIAL_MESSAGE_EQ_LEN) < 0) return -1; @@ -269,6 +328,7 @@ buf += line_len; buflen -= line_len; + *partial_buf_len = 0; } return 0; } @@ -499,6 +559,14 @@ return err; } +/* Force closing any open FD. */ +void close_logging_fds(void) +{ + if (k8s_log_fd >= 0) + close(k8s_log_fd); + k8s_log_fd = -1; +} + /* reopen all log files */ void reopen_log_files(void) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/ctr_logging.h new/conmon-2.1.0/src/ctr_logging.h --- old/conmon-2.0.30/src/ctr_logging.h 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/ctr_logging.h 2022-01-24 21:00:50.000000000 +0100 @@ -9,5 +9,7 @@ bool write_to_logs(stdpipe_t pipe, char *buf, ssize_t num_read); void configure_log_drivers(gchar **log_drivers, int64_t log_size_max_, char *cuuid_, char *name_, char *tag); void sync_logs(void); +gboolean logging_is_passthrough(void); +void close_logging_fds(void); #endif /* !defined(CTR_LOGGING_H) */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/ctr_stdio.c new/conmon-2.1.0/src/ctr_stdio.c --- old/conmon-2.0.30/src/ctr_stdio.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/ctr_stdio.c 2022-01-24 21:00:50.000000000 +0100 @@ -11,6 +11,7 @@ static gboolean tty_hup_timeout_scheduled = false; static bool read_stdio(int fd, stdpipe_t pipe, gboolean *eof); +static void drain_log_buffers(stdpipe_t pipe); static gboolean tty_hup_timeout_cb(G_GNUC_UNUSED gpointer user_data); @@ -90,12 +91,23 @@ while (read_stdio(mainfd_stdout, STDOUT_PIPE, NULL)) ; } + drain_log_buffers(STDOUT_PIPE); if (mainfd_stderr != -1) { g_unix_set_fd_nonblocking(mainfd_stderr, TRUE, NULL); while (read_stdio(mainfd_stderr, STDERR_PIPE, NULL)) ; } - return; + drain_log_buffers(STDERR_PIPE); +} + +/* the journald log writer is buffering partial lines so that whole log lines are emitted + * to the journal as a unit. this flushes those buffers */ +static void drain_log_buffers(stdpipe_t pipe) +{ + /* We pass a single byte buffer because write_to_logs expects that there is one + byte of capacity beyond the buflen that we specify */ + char buf; + write_to_logs(pipe, &buf, 0); } static bool read_stdio(int fd, stdpipe_t pipe, gboolean *eof) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/conmon-2.0.30/src/ctrl.c new/conmon-2.1.0/src/ctrl.c --- old/conmon-2.0.30/src/ctrl.c 2021-09-21 22:13:00.000000000 +0200 +++ new/conmon-2.1.0/src/ctrl.c 2022-01-24 21:00:50.000000000 +0100 @@ -14,6 +14,7 @@ #include <sys/socket.h> #include <sys/stat.h> #include <termios.h> +#include <unistd.h> static void resize_winsz(int height, int width); static gboolean read_from_ctrl_buffer(int fd, gboolean (*line_process_func)(char *)); @@ -61,7 +62,9 @@ /* We only have a single fd for both pipes, so we just treat it as * stdout. stderr is ignored. */ mainfd_stdin = console.fd; - mainfd_stdout = console.fd; + mainfd_stdout = dup(console.fd); + if (mainfd_stdout < 0) + pexit("Failed to dup console file descriptor"); /* Now that we have a fd to the tty, make sure we handle any pending data * that was already buffered. */ @@ -252,8 +255,13 @@ if (!fifo_r || !fifo_w) pexitf("setup fifo was passed a NULL pointer"); - if (mkfifo(fifo_path, 0666) == -1) - pexitf("Failed to mkfifo at %s", fifo_path); + if (mkfifo(fifo_path, 0666) == -1) { + if (errno == EEXIST) { + unlink(fifo_path); + if (mkfifo(fifo_path, 0666) == -1) + pexitf("Failed to mkfifo at %s", fifo_path); + } + } if ((*fifo_r = open(fifo_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC)) == -1) pexitf("Failed to open %s read half", error_var_name);