DEV Community

jeffrey
jeffrey

Posted on

Cgroup v2 device access is an eBPF policy

Cgroup v2 device access is an eBPF policy

Cgroup v2 does not expose a devices.allow file like the older cgroup interface. The Linux kernel documentation says device access is managed through BPF_PROG_TYPE_CGROUP_DEVICE programs attached to a cgroup with the BPF_CGROUP_DEVICE flag. The program receives the access type and device numbers and returns a decision for mknod, read, and write attempts.

That design is flexible, but it changes the review surface. The policy may exist in a BPF program, a container runtime configuration, a systemd unit, or a distribution default. A missing text file is not evidence that device access is unrestricted. Conversely, an allow-list in a container manifest is not proof that the program is attached on the host.

What the controller enforces

The controller covers creation of new device nodes and access to existing ones. The relevant context identifies the operation and the device type, major number, and minor number. A denied operation returns -EPERM. The policy has to account for the device numbers that actually appear on the host and inside the container.

This is not the same as filesystem permissions. A process may have a path to a device node and still be denied by the BPF program. A process may also be allowed by the program and then be restricted by file ownership, mount propagation, seccomp, or a LSM. Security reviewers need to understand which layer produces the final denial and which layer could be changed independently.

Delegation and failure modes

Cgroup delegation is powerful because a delegated manager can create child cgroups and move processes. If it can also attach device programs, the ability to change device policy becomes part of the delegated authority. A workload that can write to a delegated cgroup hierarchy must not be treated as an ordinary application process.

Check whether the cgroup namespace confines the process's view of the hierarchy. A namespace can limit visibility without removing host authority from the controlling process. Check who owns the BPF program, which map data it uses, and whether the program is pinned or loaded by a trusted manager. A runtime may reattach a default program after a restart, silently replacing a custom policy.

There is also a failure-mode question. If the BPF program cannot load, does the runtime start the workload without device controls, or refuse to start it? A container platform should state the default and make failure explicit. The answer should be tested after upgrades, not inferred from documentation.

Practical verification

Start with the host device inventory. Record device type, major and minor numbers, and the cgroup or container that needs access. Build the smallest allow-list the workload can operate with. Separate read from write and mknod where the program supports it.

Inside an isolated test workload, attempt a permitted device operation and a denied one. Confirm the result at the kernel policy layer and in application logs. Try creating a device node with an unexpected major number. Test after a runtime restart, after changing cgroup membership, and after applying the next kernel update.

On the host, inspect loaded BPF programs and their attachment points using the available BPF tooling. Confirm the program identity and map contents rather than trusting a configuration file alone. Restrict access to the tooling that can load or replace programs. A user who can alter the device policy is effectively an administrator of the workload boundary.

Defensive baseline

Treat device control as a layered policy. Keep the host device set small, attach an explicit cgroup device program, preserve the program through the intended manager, and test both allow and deny paths. Restrict cgroup delegation and BPF loading to trusted control-plane accounts. Audit runtime defaults after every upgrade.

The cgroup v2 design gives operators precise control. That precision only helps if the program, its attachment, and its failure behavior are visible in the operating model.

References

Top comments (0)