The vulnerability lies in how User ID and Group ID strings are parsed and converted to numeric types. The patches (1a43cb6, 05044ec, cf158e8) all modify the WithUser function within spec_opts.go (located either in pkg/oci/ or oci/ depending on the containerd version). This function takes a string representation of user/group (e.g., 'UID:GID') and converts the numeric parts to integers. The core issue was that strconv.Atoi was used to parse the numbers (returning an int), and this int was then cast to uint32 without first checking if the value was within the range of a signed 32-bit integer (0 to math.MaxInt32). If a value larger than math.MaxInt32 was provided, it could lead to an integer overflow when the OCI runtime (like runc) processed this uint32 UID/GID, potentially resulting in the container running as root (UID 0). The patches introduce explicit checks to ensure the parsed numeric values are within minUserID/minGroupID (0) and maxUserID/maxGroupID (math.MaxInt32) before casting to uint32. Therefore, the WithUser function is the vulnerable function as it directly processes the malicious input and contained the flawed conversion logic. Two distinct function signatures are identified due to changes in package structure (pkg/oci vs oci) across the patched versions.
| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| github.com/containerd/containerd/v2 | go | < 2.0.4 | 2.0.4 |
| github.com/containerd/containerd | go | >= 1.7.0-beta.0, < 1.7.27 | 1.7.27 |
| github.com/containerd/containerd | go | < 1.6.38 | 1.6.38 |