diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index f3f39b875a4..d9c9cbf5799 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -55,6 +55,43 @@ jobs: go-version: "1.26" runner: ubuntu-26.04 + # Runs the gomodjail static analysis gate, that verifies that the Go modules annotated + # `gomodjail:confined` in go.mod cannot reach a denied capability (filesystem, network, + # exec, raw syscalls, ...). + # https://github.com/AkihiroSuda/gomodjail + # To run locally, use `make lint-gomodjail-all`. + lint-gomodjail: + name: "gomodjail" + timeout-minutes: 10 + runs-on: ubuntu-26.04 + env: + GOTOOLCHAIN: local + steps: + - name: "Init: checkout" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 1 + persist-credentials: false + + - name: "Init: install go" + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: "1.26" + check-latest: true + # This workflow also runs on push, so the setup-go cache is disabled + # for zizmor's cache-poisoning audit + cache: false + + - name: "Init: install dev-tools" + run: | + echo "::group:: make install-dev-tools" + make install-dev-tools + echo "::endgroup::" + + - name: "Run" + run: | + NO_COLOR=true make lint-gomodjail-all + # Lint for shell and yaml files lint-other: name: "other" diff --git a/Dockerfile b/Dockerfile index 141c1569b0e..79b05a2ba98 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ ARG TINI_VERSION=v0.19.0@BINARY # Extra deps: Debug ARG BUILDG_VERSION=v0.5.3@BINARY # Extra deps: gomodjail -ARG GOMODJAIL_VERSION=v0.3.2@c145bb1e36fe0939c5fa0467f2477878dea8e3d9 +ARG GOMODJAIL_VERSION=v2.0.1@5924a4079d0f70459a10973f715238dc336478ea # Test deps # Currently, the Docker Official Images and the test deps are not pinned by the hash diff --git a/Makefile b/Makefile index 1deca854a00..b738a73adb4 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ DOCKER ?= docker GO ?= go GOOS ?= $(shell $(GO) env GOOS) GOARCH ?= $(shell $(GO) env GOARCH) +GOHOSTOS ?= $(shell $(GO) env GOHOSTOS) ifeq ($(GOOS),windows) BIN_EXT := .exe endif @@ -83,9 +84,9 @@ endef ########################## all: binaries -lint: lint-go-all lint-yaml lint-shell lint-commits lint-mod lint-licenses-all +lint: lint-go-all lint-yaml lint-shell lint-commits lint-mod lint-gomodjail-all lint-licenses-all -fix: fix-mod fix-go-all +fix: fix-mod fix-gomodjail fix-go-all # TODO: fix race task and add it test: test-unit # test-unit-race test-unit-bench @@ -175,6 +176,30 @@ lint-mod: && go mod tidy --diff $(call footer, $@) +# gomodjail statically verifies that the modules annotated `gomodjail:confined` in go.mod +# cannot reach a denied capability (filesystem, network, exec, raw syscalls, ...). +# https://github.com/AkihiroSuda/gomodjail +lint-gomodjail: + $(call title, $@: $(GOOS)/$(GOARCH)) +ifeq ($(GOHOSTOS),windows) + @echo "Skipped: gomodjail does not support Windows hosts" +else + @cd $(MAKEFILE_DIR) \ + && gomodjail analyze --goos=$(GOOS) --goarch=$(GOARCH) ./... +endif + $(call footer, $@) + +# The confinement is only enforced for linux/amd64 and linux/arm64, as these are the only +# platforms for which the gomodjail-packed binary is built (see Dockerfile), and the only +# ones supported by the gomodjail dynamic mode. The verdicts are platform-dependent, hence +# both architectures have to be analyzed. +lint-gomodjail-all: + $(call title, $@) + @cd $(MAKEFILE_DIR) \ + && GOOS=linux GOARCH=amd64 make lint-gomodjail \ + && GOOS=linux GOARCH=arm64 make lint-gomodjail + $(call footer, $@) + # FIXME: go-licenses cannot find LICENSE from root of repo when submodule is imported: # https://github.com/google/go-licenses/issues/186 # This is impacting gotest.tools @@ -221,6 +246,19 @@ fix-mod: && go mod tidy $(call footer, $@) +# Downgrades the `gomodjail:confined` annotation of the modules that fail `make lint-gomodjail-all` +# to `gomodjail:unconfined`, so that the annotations in go.mod stay reviewable. +fix-gomodjail: + $(call title, $@) +ifeq ($(GOHOSTOS),windows) + @echo "Skipped: gomodjail does not support Windows hosts" +else + @cd $(MAKEFILE_DIR) \ + && gomodjail fix --goos=linux --goarch=amd64 ./... \ + && gomodjail fix --goos=linux --goarch=arm64 ./... +endif + $(call footer, $@) + ########################## # Development tools installation ########################## @@ -238,6 +276,13 @@ install-dev-tools: && go install github.com/vbatts/git-validation@7b60e35b055dd2eab5844202ffffad51d9c93922 \ && go install github.com/containerd/ltag@66e6a514664ee2d11a470735519fa22b1a9eaabd \ && go install gotest.tools/gotestsum@0d9599e513d70e5792bb9334869f82f6e8b53d4d + # gomodjail: v2.0.1 (2026-09-09) + # Not installed on Windows hosts: gomodjail does not build there, as its dynamic mode + # is compiled in unconditionally (https://github.com/AkihiroSuda/gomodjail) +ifneq ($(GOHOSTOS),windows) + @cd $(MAKEFILE_DIR) \ + && go install github.com/AkihiroSuda/gomodjail/v2/cmd/gomodjail@5924a4079d0f70459a10973f715238dc336478ea +endif @echo "Remember to add \$$HOME/go/bin to your path" $(call footer, $@) @@ -319,8 +364,8 @@ artifacts: clean install \ uninstall \ clean \ - lint-go lint-go-all lint-yaml lint-shell lint-commits lint-mod lint-licenses lint-licenses-all \ - fix-go fix-go-all fix-mod \ + lint-go lint-go-all lint-yaml lint-shell lint-commits lint-mod lint-gomodjail lint-gomodjail-all lint-licenses lint-licenses-all \ + fix-go fix-go-all fix-mod fix-gomodjail \ install-dev-tools \ test-unit test-unit-race test-unit-bench \ artifacts diff --git a/docs/testing/README.md b/docs/testing/README.md index cbdc151ec4f..efea60cf4b5 100644 --- a/docs/testing/README.md +++ b/docs/testing/README.md @@ -31,6 +31,13 @@ eg: or `LINT_COMMIT_RANGE=target_branch..HEAD make lint` +`make lint` also runs [gomodjail](https://github.com/AkihiroSuda/gomodjail) in its static analysis +mode (`make lint-gomodjail-all`), to verify that the modules annotated `gomodjail:confined` in +`go.mod` cannot reach a denied capability (filesystem, network, process execution, raw syscalls, +OS state modification, or cgo). If a dependency bump makes a confined module reach one of those, +`make fix` (or `make fix-gomodjail`) downgrades its annotation to `gomodjail:unconfined`, so that +the decision stays visible in `go.mod`. + ## Unit testing ``` diff --git a/go.mod b/go.mod index 8024b60afc3..c073bcacb48 100644 --- a/go.mod +++ b/go.mod @@ -8,18 +8,18 @@ require ( github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 github.com/Microsoft/hcsshim v0.15.0-rc.4 github.com/compose-spec/compose-go/v2 v2.15.0 //gomodjail:unconfined - github.com/containerd/accelerated-container-image v1.4.4 + github.com/containerd/accelerated-container-image v1.4.4 //gomodjail:unconfined github.com/containerd/cgroups/v3 v3.1.3 //gomodjail:unconfined github.com/containerd/console v1.0.5 //gomodjail:unconfined - github.com/containerd/containerd/api v1.12.0-rc.0 + github.com/containerd/containerd/api v1.12.0-rc.0 //gomodjail:unconfined github.com/containerd/containerd/v2 v2.4.0-beta.0 //gomodjail:unconfined github.com/containerd/continuity v0.5.0 //gomodjail:unconfined github.com/containerd/errdefs v1.0.0 github.com/containerd/fifo v1.1.0 //gomodjail:unconfined github.com/containerd/go-cni v1.1.14 //gomodjail:unconfined github.com/containerd/imgcrypt/v2 v2.0.3 //gomodjail:unconfined - github.com/containerd/log v0.2.0 - github.com/containerd/nerdctl/mod/tigron v0.0.0 + github.com/containerd/log v0.2.0 //gomodjail:unconfined + github.com/containerd/nerdctl/mod/tigron v0.0.0 //gomodjail:unconfined github.com/containerd/nydus-snapshotter v0.15.15 //gomodjail:unconfined github.com/containerd/platforms v1.0.0-rc.5 //gomodjail:unconfined github.com/containerd/stargz-snapshotter v0.18.2 //gomodjail:unconfined @@ -29,24 +29,24 @@ require ( github.com/containernetworking/cni v1.3.1 //gomodjail:unconfined github.com/containernetworking/plugins v1.9.1 //gomodjail:unconfined github.com/coreos/go-iptables v0.8.0 //gomodjail:unconfined - github.com/coreos/go-systemd/v22 v22.7.0 + github.com/coreos/go-systemd/v22 v22.7.0 //gomodjail:unconfined github.com/cyphar/filepath-securejoin v0.7.0 //gomodjail:unconfined github.com/distribution/reference v0.6.0 github.com/docker/cli v29.8.0+incompatible //gomodjail:unconfined - github.com/docker/go-connections v0.8.1 + github.com/docker/go-connections v0.8.1 //gomodjail:unconfined github.com/docker/go-units v0.5.0 github.com/fahedouch/go-logrotate v0.3.0 //gomodjail:unconfined github.com/fatih/color v1.19.0 //gomodjail:unconfined - github.com/fluent/fluent-logger-golang v1.10.1 + github.com/fluent/fluent-logger-golang v1.10.1 //gomodjail:unconfined github.com/fsnotify/fsnotify v1.10.1 //gomodjail:unconfined github.com/go-viper/mapstructure/v2 v2.5.0 - github.com/ipfs/go-cid v0.6.2 + github.com/ipfs/go-cid v0.6.2 //gomodjail:unconfined github.com/klauspost/compress v1.20.0 github.com/mattn/go-isatty v0.0.24 //gomodjail:unconfined - github.com/moby/moby/client v0.6.0 - github.com/moby/moby/v2 v2.0.0-beta.23 - github.com/moby/sys/mount v0.3.5 - github.com/moby/sys/signal v0.7.1 + github.com/moby/moby/client v0.6.0 //gomodjail:unconfined + github.com/moby/moby/v2 v2.0.0-beta.23 //gomodjail:unconfined + github.com/moby/sys/mount v0.3.5 //gomodjail:unconfined + github.com/moby/sys/signal v0.7.1 //gomodjail:unconfined github.com/moby/sys/user v0.4.1 //gomodjail:unconfined github.com/moby/sys/userns v0.2.0 //gomodjail:unconfined github.com/moby/term v0.5.2 //gomodjail:unconfined @@ -54,7 +54,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.1 github.com/opencontainers/runtime-spec v1.3.0 - github.com/opencontainers/selinux v1.15.1 + github.com/opencontainers/selinux v1.15.1 //gomodjail:unconfined github.com/pelletier/go-toml/v2 v2.4.3 github.com/rootless-containers/bypass4netns v0.4.2 //gomodjail:unconfined github.com/rootless-containers/rootlesskit/v3 v3.2.0-beta.0 //gomodjail:unconfined @@ -62,68 +62,89 @@ require ( github.com/spf13/pflag v1.0.10 //gomodjail:unconfined github.com/vishvananda/netlink v1.3.1 //gomodjail:unconfined github.com/vishvananda/netns v0.0.5 //gomodjail:unconfined - github.com/yuchanns/srslog v1.1.0 + github.com/yuchanns/srslog v1.1.0 //gomodjail:unconfined go.yaml.in/yaml/v3 v3.0.5 golang.org/x/crypto v0.57.0 - golang.org/x/net v0.58.0 + golang.org/x/net v0.58.0 //gomodjail:unconfined golang.org/x/sync v0.23.0 //gomodjail:unconfined golang.org/x/sys v0.48.0 //gomodjail:unconfined golang.org/x/term v0.46.0 //gomodjail:unconfined golang.org/x/text v0.42.0 - gotest.tools/v3 v3.5.2 + gotest.tools/v3 v3.5.2 //gomodjail:unconfined tags.cncf.io/container-device-interface v1.1.1 //gomodjail:unconfined ) require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + //gomodjail:unconfined github.com/cilium/ebpf v0.22.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect + //gomodjail:unconfined github.com/containerd/go-runc v1.2.1 // indirect github.com/containerd/plugin v1.1.0 // indirect + //gomodjail:unconfined github.com/containerd/ttrpc v1.2.9 // indirect + //gomodjail:unconfined github.com/containers/ocicrypt v1.3.2 // indirect + //gomodjail:unconfined github.com/creack/pty v1.1.24 // indirect + //gomodjail:unconfined github.com/djherbis/times v1.6.0 // indirect + //gomodjail:unconfined github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/felixge/httpsnoop v1.1.0 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + //gomodjail:unconfined github.com/godbus/dbus/v5 v5.2.2 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + //gomodjail:unconfined github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/mattn/go-colorable v0.1.14 // indirect + //gomodjail:unconfined github.com/mattn/go-shellwords v1.0.13 // indirect + //gomodjail:unconfined github.com/miekg/pkcs11 v1.1.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + //gomodjail:unconfined github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/locker v1.0.1 // indirect + //gomodjail:unconfined github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/symlink v0.3.0 // indirect github.com/mr-tron/base58 v1.3.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect + //gomodjail:unconfined github.com/multiformats/go-multiaddr v0.16.1 // indirect github.com/multiformats/go-multibase v0.3.0 // indirect + //gomodjail:unconfined github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-varint v0.1.0 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect + //gomodjail:unconfined github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect github.com/sasha-s/go-deadlock v0.3.5 // indirect //gomodjail:unconfined github.com/sirupsen/logrus v1.10.2 // indirect github.com/smallstep/pkcs7 v0.2.1 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect + //gomodjail:unconfined github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect + //gomodjail:unconfined github.com/tinylib/msgp v1.3.0 // indirect + //gomodjail:unconfined github.com/vbatts/tar-split v0.12.3 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect + //gomodjail:unconfined go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.71.0 // indirect + //gomodjail:unconfined go.opentelemetry.io/otel v1.46.0 // indirect go.opentelemetry.io/otel/metric v1.46.0 // indirect go.opentelemetry.io/otel/trace v1.46.0 // indirect @@ -133,6 +154,7 @@ require ( google.golang.org/grpc v1.83.2 // indirect //gomodjail:unconfined google.golang.org/protobuf v1.36.12 // indirect + //gomodjail:unconfined lukechampine.com/blake3 v1.3.0 // indirect tags.cncf.io/container-device-interface/specs-go v1.1.1 // indirect ) @@ -144,10 +166,12 @@ require ( github.com/ProtonMail/go-crypto v1.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect + //gomodjail:unconfined github.com/google/uuid v1.6.0 // indirect github.com/moby/moby/api v1.56.0 // indirect go.opentelemetry.io/otel/sdk v1.46.0 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect + //gomodjail:unconfined sigs.k8s.io/knftables v0.0.18 // indirect )