Repository navigation
Start on kernels without any cgroup device gate - #1
Merged
Merged
Conversation
Linux added BPF_PROG_TYPE_CGROUP_DEVICE in 4.15, and a kernel built without CONFIG_CGROUP_DEVICE has no cgroup v1 `devices` controller. On such kernels the v2 probe fails at BPF_PROG_LOAD with EINVAL and the v1 fallback fails at mount(2) with ENOENT, because cgroup v1 rejects unknown subsystem names, so the launcher cannot start Debian at all: BFU_DEBIAN_LAUNCHER_FAILED stage=cgroup_v2_device_bpf_load errno=22 BFU_DEBIAN_LAUNCHER_FAILED stage=cgroup_v1_devices_mount errno=2 BFU_DEBIAN_START_FAILED stage=namespace_setup exit=91 Add a last legacy tier that delegates only the `name=systemd` hierarchy, reported as cgroup_mode=v1-nodev. The device gate is used solely by the blocked USB policy, so the new tier starts only while USB passthrough is off; direct and exclusive passthrough still require a device gate and now fail with a named stage instead of a bare mount errno. /dev/bus/usb keeps its empty read-only overmount, and the USB log lines report whether major 189 is actually denied instead of asserting it unconditionally. Probe /proc/cgroups for the controller rather than inferring it from a mount errno, extend the health probe with a v1-nodev branch (and a systemd_path field), and keep systemd on the legacy cgroup command line for the new mode.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Important
Disclaimer: This PR was created by Claude Opus 5.
directandexclusivenever used the gate. Should they also be allowed onthese kernels, or is refusing them the intended conservative stance? The
patch currently refuses.
CAP_MKNODbe dropped from the bounding set in this tier, mirroringthe existing
CAP_SYS_BOOTdrop? That would close themknodpath. It isleft out here because it also affects Docker device creation, which seems
like your call.
kernel ≥ 4.15withCONFIG_CGROUP_BPF=nbut usable cgroup2 is the mirrorcase (v2 delegation fine, gate missing). Adding a
v2-nodevtier would needhealth to distinguish an attached program from an absent one, which is not
observable from inside the container; a launcher-written marker would be
required. Out of scope here.
Start on kernels without any cgroup device gate
Summary
On kernels that provide neither cgroup device policy backend,
startfailsduring namespace setup and Debian never boots, even with USB passthrough off.
This adds a last legacy tier that delegates only the
name=systemdhierarchy(
cgroup_mode=v1-nodev), allowed only while USB passthrough is off, and makesthe USB log lines state whether major 189 is actually denied.
Symptom
debian-lifecycle.log, start from the app button:Host diagnostics from the same run:
Kernel configuration on the affected device:
Device: Samsung Exynos 9610, Linux 4.14.194 (Mint Beta 1413), host USB mode off.
Root cause
Both device policy backends are unavailable, and each failure is currently
fatal.
v2 path.
BPF_PROG_TYPE_CGROUP_DEVICEwas added in Linux 4.15. On 4.14the program type does not exist, so
bpf(BPF_PROG_LOAD)returns-EINVALfrom
find_prog_type()regardless ofCONFIG_CGROUP_BPF:v1 fallback. The kernel is built without
CONFIG_CGROUP_DEVICE, so thereis no
devicesrow in/proc/cgroups, and mounting the controller fails withENOENTrather thanEINVAL, because cgroup v1 option parsing reports anunknown subsystem name that way (4.14
parse_cgroupfs_options()):A relevant detail: the device gate is used by exactly one policy today. Both
apply_host_usb_v2_policy()andprepare_devices_cgroup_mount()install a denyrule only when the policy is
off, and return early withaction=allow_parent_policyfordirectandexclusive. So on these kernelsthe launcher refuses to start for a capability that the requested policy may not
even use.
Change
CGROUP_MODE_V1_NO_DEVICES(v1-nodev): thename=systemdhierarchy isdelegated as before, the
deviceshierarchy is skipped in mount, move, viewand PID 1 setup.
/proc/cgroupsfor thedevicescontroller instead of inferringavailability from a mount errno, so a known kernel limit is not reported as a
mount fault.
off.directandexclusivenow fail with
stage=cgroup_devices_controller error=device_gate_unavailable_for_usb_passthrough(exit 120) instead of abare mount errno.
cgroup_major_189_denied=andfuture_hotplug_cgroup_enforced=astrueonly when a device gate is actually active.
/dev/bus/usbkeeps the emptyread-only overmount in every case.
v1-nodevbranch that reportscgroup_delegation=delegated devices_cgroup=unavailable, plus a newsystemd_path=field for diagnosis. The app's health requirement(
cgroup_delegation=delegated) is unchanged.(
systemd.unified_cgroup_hierarchy=0,SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1)for the new mode.
docs/architecture.mdanddocs/architecture.ko.md.The v2 path is untouched: a kernel that cannot load the device BPF program still
does not resolve to v2, so
devices_cgroup=bpfnever becomes a false claim.Security considerations
In
v1-nodevthe blocked USB policy loses its defence in depth. What remains isthe empty read-only overmount on
/dev/bus/usb; what is gone is the major 189deny rule, so a root process inside Debian could recreate a usbfs node with
mknodunder the shared/devand open it. The patch therefore keeps this tierlimited to the policy that requests no USB access, and states the weaker
guarantee in the log and the docs rather than implying enforcement.
Compatibility
format=6. Only a newcgroup_modevalue isintroduced; an older binary reading a
v1-nodevstate resolves it to unknownand asks for a restart, which is the existing behaviour for unrecognised
modes.
LauncherState.cgroup_modegrows from 8 to 16 bytes to hold the new name. Thestate file is text, so no layout compatibility is involved.
enter_debian_probe) passesCGROUP_MODE_UNKNOWN, so its USBlog line now reads
future_hotplug_cgroup_enforced=false. That path neversets up a device cgroup, so the previous
truewas inaccurate.Testing
gcc -fsyntax-only -Wall -Wextra -std=c11 app/src/main/cpp/bfu_namespace_probe.cis clean (host headers; the NDK build runs in CI).
ANDROID_HEALTH ... cgroup_mode=v1-nodev cgroup_delegation=delegated devices_cgroup=unavailable, SSH login,stop,restart.devicescontroller present (the v1 pathshould be unchanged), and Docker inside the new tier.