Container Runtime Security Hardening in 2026: containerd 2.3, CRI-O and Podman 6 CVE Response

Container Runtime Security Hardening in 2026: containerd 2.3, CRI-O and Podman 6 CVE Response

Container Runtime Security Hardening in 2026: containerd 2.3, CRI-O and Podman 6 CVE Response

The most important process on a Kubernetes node is not your application, and it is not the kubelet. It is the container runtime, a long-lived, privileged daemon that parses untrusted image layers, executes probes on your behalf and mediates every boundary between a workload and the host kernel. Container runtime security is therefore the discipline of treating that daemon as the most attractive target on the node, not as plumbing.

The first two weeks of September 2026 made the point twice. containerd shipped coordinated patch releases (v2.3.5, v2.2.8, v2.0.12 and v1.7.35) for denial-of-service flaws in the CRI exec path and the layer unpack handler. Podman 6.1.1 fixed CVE-2026-17106, a tar extraction flaw that lets crafted archives write outside the extraction directory. CRI-O also shipped patches that week, but, as we will see, they were not security fixes. Separating those facts matters.

You will leave with a verified account of what each advisory actually says, a layered hardening model that survives the next CVE, and a rollout runbook you can run this week.

What this covers: the September 2026 advisories, a layered model for runtime hardening, a worked configuration walk-through for containerd, CRI-O and Podman, failure modes of each control, and a patch-and-verify checklist.

Context and Background

Three runtimes dominate the places where containers run in 2026. containerd is the default runtime under most managed Kubernetes services and under Docker Engine itself. CRI-O is the Kubernetes-only runtime used by Red Hat OpenShift and a number of self-managed distributions. Podman is the daemonless, rootless-first engine used on developer workstations, edge boxes and CI runners. If you want a side-by-side of the first two, our comparison of containerd versus CRI-O as Kubernetes runtimes covers architecture and operational differences.

All three share a layered design. A high-level runtime (containerd, CRI-O, Podman’s libpod) pulls images, unpacks layers into snapshots and prepares an OCI bundle. A low-level runtime (runc or crun, or a sandboxed runtime such as gVisor or Kata Containers) calls into the kernel to create namespaces, cgroups and seccomp filters. Between them sits a shim process that outlives the daemon so containers survive a daemon restart. Each hop is a place where untrusted input crosses a privilege boundary.

That is why the same classes of bug keep recurring. Image layers are attacker-controlled archives, so tar and whiteout handling is a perennial source of path-traversal and resource-exhaustion bugs. Image configuration is attacker-influenced metadata, so labels and annotations that flow into runtime behaviour are a second source. Finally, the CRI is an API on a privileged socket, so anything that lets an unprivileged workload make the daemon do unbounded work becomes a node-level denial of service.

The CVE record for containerd earlier in 2026 shows the pattern. AWS Security Bulletin 2026-046-AWS, published 18 June 2026, listed five issues in the containerd CRI plugin across the 1.7 to 2.3 lines: cache poisoning through unvalidated checkpoint image references (CVE-2026-50195, CVSS 8.8), image-config LABEL propagation leading to command execution (CVE-2026-53488, 8.3), CDI annotation smuggling from checkpoint metadata (CVE-2026-53492, 6.8), symlink handling during checkpoint restore (CVE-2026-53489, 6.5) and an uncontrolled-memory image parsing issue (CVE-2026-47262, 6.5). Two of those required optional features, checkpoint/restore or CDI, to be enabled. The September advisories we examine below are smaller in blast radius but arrive on the same attack surface.

One honest framing point before the detail. Advisories describe what was fixed, not what attackers do. Throughout this article we stay on the defensive side: what the maintainers disclosed, what configuration reduces exposure, and how to roll out fixes safely. We do not reconstruct exploits, and where a source did not publish a detail, such as a CVSS score, we say so rather than guess. For the Kubernetes-side picture of rootless components, see our write-up on Kubernetes 1.37 and the rootless kubelet.

Container Runtime Security: A Layered Reference Model

Effective container runtime security rests on four layers that fail independently: a patched daemon, a minimal and non-root execution identity, a restricted kernel attack surface, and trust controls on what the runtime is allowed to pull and run. Patching closes known bugs; the other three layers limit the damage of the next unknown one.

Container runtime security layers and trust boundaries across containerd, CRI-O and Podman

Figure 1: Where untrusted input crosses a privilege boundary in a typical container runtime stack, from registry to kernel.

Figure 1 shows the stack from the registry to the kernel. Untrusted bytes enter at the registry boundary, where they are authenticated, fetched and unpacked by the high-level runtime. They cross a second boundary when the runtime turns image metadata and pod spec into an OCI runtime bundle. The third boundary is the kernel itself, enforced by user namespaces, capabilities, seccomp and Linux Security Modules. Each September advisory sits at a different boundary, which is why a single control never covers them all.

What the September 2026 advisories actually say

The containerd release notes for v2.3.5 list two security items: CVE-2026-53495 and GHSA-rp3h-jf77-q9p4. The same fixes landed in v2.2.8, v2.0.12 and v1.7.35. The release also bundles hardening that strips sensitive authentication headers when fetching descriptor URLs during image distribution, plus unrelated fixes such as a data race in CRI I/O streaming, a startup hang while loading shims and a user lookup failure when the rootfs contains symlinked passwd or group files. It updates the bundled runc to v1.5.1.

The first item, published as GHSA-7jxh-36q5-gcqv and carrying CVE-2026-53495, is rated moderate. The advisory describes unbounded I/O draining in the CRI ExecSync implementation on Linux. Exec probes and lifecycle hooks that leave a background child process running can block containerd’s I/O drain goroutines indefinitely, because the drain phase has no timeout or context cancellation. Repeated ExecSync calls, particularly from probes that fire every few seconds, leak goroutines and memory until the OOM killer terminates containerd. Affected ranges are containerd before 1.7.35, 2.0 before 2.0.12, 2.2 before 2.2.8 and 2.3 before 2.3.5. The published workaround is to ensure probes and hooks do not launch long-lived background child processes. No CVSS score appeared on the advisory page we read.

The second item, GHSA-rp3h-jf77-q9p4, is also rated moderate and is titled “Unpack DoS via repeated opaque whiteouts”. The advisory states that processing certain image layers causes superlinear time complexity through repeated directory traversals. Consequences are slow container starts, high CPU during pulls and reduced concurrent pull capacity, which in an orchestrator can delay unrelated deployments. It affects the same version ranges and the advisory states there are no known workarounds; interim guidance is to restrict pulls to trusted registries. We did not find a CVE identifier mapped to this GHSA in the sources we could read, so we cite the GHSA identifier.

Podman 6.1.1’s release notes state it addresses CVE-2026-17106, where “a crafted tar archive could write outside the extraction directory through the use of malicious links”, and attribute the issue to the go-archive library. The upstream CVE record describes the flaw in moby/go-archive: the extractor makes decisions with lexical string checks, then performs filesystem operations on paths the operating system resolves, so links introduced by the archive can be followed out of the destination directory. It is scored 7.1 (High) under CVSS 4.0 with a local attack vector and active user interaction, and lists fixed versions including go-archive 0.3.0 and Docker Engine 29.7.0. The same release fixes a rootlessport bug affecting simultaneous IPv4 and IPv6 bindings, notably on Podman Machine with WSL.

The CRI-O 1.36.5 release, dated 2 September 2026 on its release page, is a different story. Its notes list two bug fixes: serialization in concurrent image volume mounts and a cpuset bug in the high-performance hooks for init containers. The newsletter we used as a roundup grouped it with the security releases, but the release notes themselves contain no CVE. Patch it as part of routine maintenance, not as an incident. Equally, 1.35.8 and 1.34.13 appeared the same week and we found no security statement for them in the roundup.

Why denial of service belongs in a security plan

Engineers sometimes triage “moderate DoS” below the line. On a node, that is a mistake, because the container runtime is a shared fate component. When containerd is killed by the OOM killer, running containers usually keep running thanks to the shim, but the kubelet loses its CRI endpoint, new pods cannot start, probes stop being evaluated through CRI and the node flaps to NotReady until restart. A multi-tenant cluster where one tenant can influence probe behaviour or layer content has handed that tenant a lever over the whole node.

The exec-probe bug is particularly instructive because the trigger is ordinary: a shell-script probe that backgrounds a helper. No attacker is needed for an outage, only a team that wrote sleep 3600 & in a probe script. A defence that depends on trusted authors alone is not a defence, so the right response is both the patch and a policy gate on probe definitions.

Four independent layers

The first layer is patch hygiene: knowing which runtime build every node runs and being able to replace it within days. The second is identity: running workloads, and where possible the runtime itself, without host root, using user namespaces and rootless modes. The third is kernel attack surface: dropping capabilities, applying seccomp and enforcing an LSM profile so a runtime or workload bug has fewer syscalls to abuse. The fourth is supply-chain trust: restricting registries, verifying signatures and refusing images that fail policy before they ever reach the unpack handler.

Notice what each layer would have done in September. Patch hygiene fixes both containerd items. Identity and kernel layers do not stop a goroutine leak but do bound what a compromised workload could do next to it. Supply-chain trust limits who can supply the pathological layer behind the whiteout issue and the crafted archive behind CVE-2026-17106. No single layer is sufficient, and that is the entire argument for layering.

Deeper Analysis: Mechanisms, Configuration and Blast Radius

The mechanism behind each fix explains which hardening step helps. We take the three bug classes in turn, then translate them into configuration for each runtime. Everything here is defensive: the goal is to bound exposure and shorten the patch window, not to reproduce an attack.

The ExecSync path and why probes matter

Kubernetes exec probes and preStop or postStart lifecycle hooks do not run inside the kubelet. The kubelet asks the runtime, over the CRI, to run a command synchronously inside the container and return its exit code and output. In containerd that call lands in the CRI plugin’s ExecSync handler, which starts the process through the shim and collects stdout and stderr.

Sequence of a CRI exec probe showing where the I/O drain phase can block without a timeout in containerd

Figure 2: The ExecSync call path. The unpatched drain phase waits for the output pipes to close, so a background child that inherits them keeps it waiting.

As Figure 2 shows, the command’s own exit is not the end of the call. The handler must also drain the output pipes until they report end-of-file. A background child that inherited those pipes keeps them open after its parent exits, so the drain waits for a descriptor that will not close. The advisory identifies the missing timeout or context cancellation in that phase as the defect. Each stuck call pins a goroutine and its buffers, and probes repeat on a fixed period, so a leak that costs a few kilobytes per call accumulates quickly across hundreds of pods per node.

Worked numbers make the risk concrete, and these are illustrative arithmetic, not measurements. Suppose a node runs 100 pods, each with an exec liveness probe at a 10-second period, and 10 of those probes leave a background child behind. That is one leaked drain per probe per 10 seconds, so 60 leaked drains per minute across the node, or 86,400 per day. If each pins roughly 64 KiB of buffers and stack, a figure we assume for the sake of the calculation, that is about 5.3 GiB per day of retained memory, enough to trigger the OOM killer on a small node in hours. The actual cost per leak is undisclosed, but the shape of the curve, linear growth until an out-of-memory kill, follows directly from the advisory text.

Two defensive conclusions follow. First, prefer probe types that do not use ExecSync at all: httpGet, tcpSocket and grpc probes are executed by the kubelet against the pod network, so they never enter the runtime’s exec path. Second, where exec probes are unavoidable, write them as short foreground commands that do not fork background processes, and enforce that with an admission policy rather than a wiki page.

Opaque whiteouts and the unpack handler

An OCI image layer is a tar archive of filesystem changes. Deletions are encoded as special “whiteout” entries: a file named .wh.<name> hides <name> from lower layers, and an opaque whiteout, .wh..wh..opq, hides the entire contents of a directory from lower layers. The unpack handler must apply these entries to the snapshot as it extracts, which involves walking the target directory.

The advisory title, “Unpack DoS via repeated opaque whiteouts”, and its description of superlinear time through repeated directory traversals indicate that a layer constructed with many such entries makes the work grow faster than the layer’s size. The maintainers did not publish a complexity figure, so we will not guess one. What matters operationally is the effect: CPU pinned on the pulling node and fewer concurrent pulls available to the scheduler.

Because there is no workaround, the control is upstream of the runtime: only pull from registries you control or mirror, and set a pull-through cache so a hostile layer is fetched once into a quarantine path rather than by every node. This is where the supply-chain layer earns its place. A registry allowlist is not a patch, but it converts “anyone can ship a pathological layer to my nodes” into “only a compromised internal registry can”.

CVE-2026-17106 is a textbook confinement failure. A path check done on strings, such as “does this cleaned path start with the destination directory”, can be defeated when the archive itself first creates a symbolic link, and a later entry is then written through that link. The extractor believes the path is inside the destination while the kernel resolves it somewhere else. The fix in go-archive 0.3.0 and the dependent releases addresses confinement; we do not describe the exploit construction.

The defensive takeaways are about blast radius. The CVSS vector for this issue has a local attack vector and requires user interaction, so the realistic exposure is a user or automation that extracts an untrusted archive. Which Podman code paths reach the vulnerable extractor is not spelled out in the release notes, so we do not enumerate commands. Rootless Podman limits what such a write can reach to the invoking user’s files, which is the strongest argument for running rootless in CI: an out-of-directory write lands in a throwaway user’s home, not in root-owned paths. Treat this as a reason to run build and CI hosts as unprivileged users even before you patch.

Hardening the daemon, runtime by runtime

For containerd, the CRI configuration exposes several security-relevant settings. The option unset_seccomp_profile defines the profile used when a CRI request does not specify one and, per the containerd CRI documentation, defaults to unconfined if unset. That default is the single most important one to review. Kubernetes’ RuntimeDefault seccomp profile is applied only if the pod asks for it, either per pod or through the kubelet’s --seccomp-default setting, so a cluster without either leaves workloads unfiltered. Options such as enable_unprivileged_ports and enable_unprivileged_icmp widen sysctls for non-host-network containers and should be enabled only where needed. The privileged_without_host_devices option stops privileged containers from automatically inheriting host devices, and runtime classes let you route untrusted workloads to a sandboxed handler such as gVisor or Kata.

# /etc/containerd/config.toml (config version 3 shown; section names differ in version 2)
version = 3

[plugins.'io.containerd.cri.v1.runtime']
  # Confirm exact key placement against the CRI config doc for your containerd version.
  unset_seccomp_profile = "runtime/default"
  enable_unprivileged_ports = false
  enable_unprivileged_icmp = false

  [plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runc]
    privileged_without_host_devices = true

For CRI-O, the equivalents live in crio.conf or drop-ins under /etc/crio/crio.conf.d/. Typical hardening keys are selinux = true where SELinux is available, a restricted default_capabilities list, pids_limit to cap fork bombs and a seccomp_profile path if you ship a custom profile. Key names and defaults vary by release, so validate against the documentation for your installed version; we did not verify each default for 1.36 and do not assert any here.

# /etc/crio/crio.conf.d/10-hardening.conf  (verify keys against your CRI-O version)
[crio.runtime]
selinux = true
pids_limit = 2048
default_capabilities = ["CHOWN", "DAC_OVERRIDE", "FSETID", "FOWNER", "SETGID", "SETUID", "SETPCAP", "NET_BIND_SERVICE", "KILL"]

For Podman, hardening is mostly a matter of flags and defaults. Rootless containers run without --privileged and, per the Podman documentation, cannot have more privileges than the user who launched them. Add --cap-drop=all and re-add only what is needed, --security-opt=no-new-privileges to block setuid escalation, and --read-only with --read-only-tmpfs for a writable /tmp and /run. The --userns=auto mode allocates a separate user namespace mapping, which limits cross-container UID overlap, while --userns=keep-id is convenient for bind-mounting your own files but maps you to yourself, so use it deliberately.

podman run --rm \
  --cap-drop=all --security-opt=no-new-privileges \
  --read-only --read-only-tmpfs=true \
  --userns=auto \
  registry.example.com/team/app:1.4.2

Pod-level identity: user namespaces and seccomp

The most valuable pod-level control available in 2026 is user namespaces. Kubernetes documents the feature as stable since v1.36 (first available in v1.28), and the 1.36 announcement describes it as no longer something you can disable. Setting hostUsers: false in the pod spec gives the pod its own UID and GID mapping, so root inside the container maps to an unprivileged ID on the host, and capabilities such as CAP_NET_ADMIN apply only to namespaced resources. The mechanism relies on ID-mapped mounts, so it needs a recent kernel and a runtime and low-level runtime that support it. The announcement we read did not enumerate exact minimum versions, so check your distribution and runtime documentation rather than trusting a number here.

apiVersion: v1
kind: Pod
metadata:
  name: hardened-app
spec:
  hostUsers: false
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/team/app:1.4.2
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      readinessProbe:
        httpGet: { path: /ready, port: 8080 }
        periodSeconds: 10

Notice the probe: an httpGet readiness check avoids ExecSync entirely. A user-namespaced, non-root, seccomp-filtered pod that never calls the exec path would have been immune to the exec-probe leak even before patching, and its container escape surface is smaller if a future kernel or runc bug appears.

Defense in depth for container runtime security from admission policy to kernel enforcement

Figure 3: Controls ordered by where they act. Admission and supply-chain gates run before the runtime sees a workload, and kernel controls bound what survives a runtime bug.

Figure 3 puts the controls in order. Admission policy and registry gating act before the runtime is involved and are cheapest to enforce centrally. Pod security settings shape the OCI bundle the runtime builds. Kernel-level enforcement, which includes user namespaces, seccomp, capabilities and LSMs, applies at execution and is the last line when a runtime bug is exploited. A mature program has a control at every tier and a measurable owner for each.

Patch Rollout: A Runbook for Runtime Updates

Replacing a container runtime on a live node is riskier than patching an application, because the daemon is on the critical path for every pod. The runbook below treats the runtime like a database engine upgrade: inventory first, canary second, fleet third, verification always.

Rolling container runtime patch runbook from inventory and canary to fleet rollout and verification

Figure 4: A staged rollout with explicit gates. A failed canary stops the pipeline and triggers rollback to the previous runtime build.

Step 1: inventory and exposure

You cannot patch what you cannot enumerate. Query every node for its runtime and version; for Kubernetes, kubectl get nodes -o wide shows the CONTAINER-RUNTIME column, which reports values such as containerd://2.3.4. Map each version to its patched line: anything below 1.7.35, 2.0.12, 2.2.8 or 2.3.5 is in scope for the September containerd advisories. Note the lines without a patch: containerd 2.1 does not appear in the patched set we read, so a node on 2.1 should plan a move to a supported line rather than wait for a backport that may not come. That is an inference from the advisory’s list of affected and fixed ranges, so confirm against the project’s support policy.

Managed services complicate this. The AWS bulletin from June said the provider was deploying corrected runtimes across managed fleets and that self-managed containerd on EC2 or on-premises needed manual upgrades. Check your provider’s bulletin for September fixes and confirm which node image version carries them. If you run Podman on CI hosts, include those hosts: they are easy to forget because no cluster tracks them.

Step 2: reduce exposure while you plan

Where patching will take days, shrink the window. For the exec-probe issue, scan manifests for exec probes and lifecycle hooks and rewrite them to httpGet, tcpSocket or grpc checks where possible. Kubernetes policy engines can reject new exec probes in namespaces that do not need them. For the unpack issue, restrict pulls to trusted registries and mirrors, which is the only mitigation the advisory offers. For the Podman archive issue, stop extracting untrusted archives on privileged hosts and run such steps as unprivileged users.

Step 3: canary, then drain-and-replace

Pick a canary pool that covers your kernel and OS variants. Cordon and drain one node, replace the runtime package or, better, replace the node from an updated machine image, and uncordon. Immutable node images are safer than in-place package upgrades because rollback is replacing the image, not reversing a package state. In-place upgrades are acceptable for edge and CI hosts but should keep the previous package available.

Remember that restarting containerd does not by itself kill running containers, since shims keep them alive, but a drain is still the safer path for security fixes because it also refreshes shim and runc binaries for new pods. The containerd 2.3.5 release also bumps runc to v1.5.1, so treat the update as a low-level runtime change as well and test workloads that depend on specific runc behaviour.

Step 4: verify, do not assume

After each batch, verify three things. The reported runtime version on the node object matches the target. The kubelet reports Ready and probe success rates have not dropped. And for the exec-probe fix, the containerd process memory and goroutine trend is flat under load. If you scrape containerd metrics, alert on process resident memory growth, which is the early symptom the advisory describes; an unpatched node leaking drains shows a steady upward slope, not a spike.

Record the rollout in your asset inventory with the date and version. Auditors and incident responders both ask the same question after the next CVE: how long was each node exposed? A timestamped inventory answers it in minutes.

Trade-offs, Gotchas, and What Goes Wrong

Every control above has a cost, and most outages caused by hardening come from skipping the testing. Seccomp RuntimeDefault is broadly compatible but can break workloads that use less common syscalls, such as some profilers, debuggers or io_uring-based applications, and failures appear as EPERM or Operation not permitted far from the cause. Roll it out namespace by namespace in audit-first mode where your tooling allows, and keep a documented exception path rather than disabling filtering globally.

User namespaces have their own friction. ID-mapped mounts require filesystem and kernel support, and volume types that do not support idmapping can make a hostUsers: false pod fail to start. Workloads that expect to share files by UID across pods need a deliberate ownership plan. Because the feature relies on recent kernels and a matching runtime, mixed-age node pools can produce pods that schedule fine on one node and fail on another, so label node pools by capability and use node selectors until the fleet is uniform.

Rootless operation trades capability for safety. Rootless Podman cannot bind privileged ports without a sysctl change, has different networking performance characteristics and restricts some storage drivers and device access. These are acceptable on CI and developer machines, but a team that relaxes them by running --privileged to get a job done has erased the benefit. Audit for --privileged, hostPID, hostNetwork and writable hostPath mounts as strongly as you audit CVE versions.

Patching has failure modes too. A containerd upgrade that changes config schema can fail at startup; the 2.3.5 notes mention a fix for loading newer drop-in config versions, a reminder that configuration format is a moving part. Keep configuration under version control, validate with containerd config dump in a canary before the fleet, and never roll runtime and kubelet changes in the same maintenance window, or a failure becomes impossible to attribute.

A subtler anti-pattern is vulnerability-scanner theatre. Image scanners report vulnerabilities in packages inside images, not in the node’s container runtime, and the runtime sits outside the image. A green image dashboard says nothing about whether containerd on the node is vulnerable to the exec-probe leak. Node-level inventory is a separate control with a separate owner.

Finally, do not over-read severity labels. Both containerd September advisories are moderate, and CVE-2026-17106 is scored 7.1 under CVSS 4.0 with a local vector and user interaction. Those ratings describe the generic case. In a multi-tenant cluster, a “moderate” denial of service that any tenant can trigger may deserve the urgency of a high, while the same bug on a single-team, single-tenant cluster can wait for the next window. Rate by your exposure, not the headline.

Practical Recommendations

Start with visibility, then fix the fast things, then invest in the structural controls. In the first week, inventory runtime versions on every node and CI host and schedule upgrades to containerd 1.7.35, 2.0.12, 2.2.8 or 2.3.5 and Podman 6.1.1. Treat the CRI-O 1.36.5 and sibling patch releases as routine maintenance, since their release notes list bug fixes rather than security items, but stay current within your supported minor.

In the first month, convert exec probes to httpGet, tcpSocket or grpc where the application allows, and enforce the rule with admission policy. Set a cluster-wide seccomp default so RuntimeDefault applies without every team opting in, and restrict image pulls to approved registries through a mirror or pull-through cache. In the first quarter, adopt hostUsers: false for new workloads and migrate existing ones in waves, and move CI runners to rootless Podman or an equivalent unprivileged builder.

For longer-term resilience, consider sandboxed runtime classes for untrusted or multi-tenant workloads and subscribe to the security advisory feeds for every runtime you operate. The containerd project’s advisory page, the CRI-O release notes and the Podman release announcements are the primary sources, and a webhook into your ticketing system beats checking weekly newsletters.

  • Inventory runtime versions on all nodes, CI hosts and edge devices; record dates.
  • Patch containerd to 1.7.35, 2.0.12, 2.2.8 or 2.3.5, and Podman to 6.1.1.
  • Replace exec probes with httpGet, tcpSocket or grpc probes; block new exec probes by policy.
  • Enable a default seccomp profile and drop all capabilities by default.
  • Pull only from approved registries via a mirror; sign and verify images.
  • Adopt hostUsers: false and rootless builders; audit --privileged and host mounts.
  • Alert on containerd resident memory growth and on NotReady node flaps.
  • Canary every runtime update; keep rollback artifacts for one release.

Frequently Asked Questions

What is container runtime security?

Container runtime security is the set of controls that protect the software that pulls, unpacks and executes containers, such as containerd, CRI-O, Podman and runc, plus the kernel boundaries that isolate workloads. It covers patching the daemon, running with least privilege through rootless modes and user namespaces, restricting syscalls with seccomp, and controlling which images the runtime accepts. It differs from image scanning, which inspects packages inside an image.

Which containerd versions fix CVE-2026-53495?

The advisory lists patched versions 1.7.35, 2.0.12, 2.2.8 and 2.3.5. Affected ranges are anything earlier on those lines: below 1.7.35, below 2.0.12, from 2.2.0 up to but excluding 2.2.8, and from 2.3.0 up to but excluding 2.3.5. The flaw is in the CRI ExecSync I/O drain on Linux. The stated workaround is to keep exec probes and lifecycle hooks from launching long-lived background child processes.

Was CRI-O affected by the September 2026 CVEs?

We found no CVE in the CRI-O 1.36.5 release notes. They list two bug fixes, concurrent image volume mounting and a high-performance hooks cpuset issue in init containers. A weekly roundup grouped CRI-O with the security releases, but the primary release page did not describe a security fix. Keep CRI-O current for stability, and check your distribution’s advisory feed for any vendor-specific backports.

What does Podman 6.1.1 fix?

Podman 6.1.1 addresses CVE-2026-17106, where a crafted tar archive could write outside the extraction directory through malicious links, a flaw in the go-archive library. It also fixes rootlessport so that separate IPv4 and IPv6 port bindings work, which matters for Podman Machine on WSL. Running rootless limits the reach of out-of-directory writes to the invoking user’s files, but you should still upgrade.

Do Kubernetes user namespaces replace patching?

No. User namespaces, enabled with hostUsers: false and stable since Kubernetes 1.36, reduce the damage from a container escape by mapping container root to an unprivileged host ID. They do not stop a daemon denial of service such as the exec-probe leak, which occurs in containerd itself. Use them as a second layer beside patching, seccomp, dropped capabilities and registry controls.

Should I use gVisor or Kata Containers instead?

Sandboxed runtimes add a stronger boundary by interposing a user-space kernel or a lightweight virtual machine, at a cost in performance, compatibility and operational complexity. They are worth using for untrusted or multi-tenant workloads through runtime classes. They do not remove the need to patch containerd or CRI-O, because the high-level runtime still parses images and handles CRI calls on the host.

Further Reading

By Riju — about

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *