Skip to content

Latest commit

 

History

History
98 lines (80 loc) · 6 KB

File metadata and controls

98 lines (80 loc) · 6 KB

Kernel Rust Coverage Map: Phase 1 Inventory

Sweep of all Rust in the kernel tree, grouped into logical verification units, with the metrics that drive Charon/Aeneas planning. Full per-unit data in inventory.csv.

Environment: kernel ~/linux v7.2-rc2 (read-only) · Charon ~/charon commit 909ff09a, v0.1.220.

Summary

  • 122 units total; 117 in-scope (5 vendored third-party crates excluded from verification).
  • In-scope code totals 92,308 lines across three tiers: kernel crate (55.3k), drivers (27.5k), samples + support + misc (9.5k).
  • The in-scope code has 2,020 unsafe blocks, 84% of them in the kernel crate (1,703), which is the FFI surface.
  • 13 units parse untrusted input, the verification-target candidates.
  • 12 units touch a union (own Rust union or a C __bindgen_anon field), the known Aeneas blocker (AeneasVerif/aeneas#1199).
  • 4 units are both (parse untrusted input and touch a union): nova_core, android_binder, kernel::drm, kernel::iov. Each carries a known downstream blocker.

Units by category

Category Units LOC unsafe blocks
kernel-crate (rust/kernel/*) 80 55,317 1,703
driver (drivers/**) 10 27,541 183
support (rust/macros, pin-init, ffi, …) 5 6,487 128
sample (samples/rust/*) 15 2,044 4
misc-host (build tooling) 2 654 0
misc-test (in-tree tests) 2 126 2
support-gen (generated shims) 2 115 0
sample-host (userspace) 1 24 0
in-scope total 117 92,308 2,020
vendored (out of scope) 5 90,111 344

Vendored (zerocopy, zerocopy-derive, syn, quote, proc-macro2) are third-party crates pulled in for the build (proc-macro toolchain / byte-cast helpers), not kernel verification targets.

Verification-target shortlist: units that parse untrusted input

Sorted by LOC. The union column flags the known Aeneas blocker; together these two columns are the planning signal. (Full reasons in the CSV.)

Unit LOC unsafe union Why untrusted
nova_core 13,451 29 yes parses VBIOS image + GSP firmware/command-queue blobs from the device
android_binder 9,489 147 yes parses binder transaction buffers & flat objects from userspace IPC
kernel::drm 2,770 144 yes DRM ioctl dispatch decodes userspace ioctl argument structs
drm_tyr 2,167 1 no panthor GPU dev_query ioctl args come from userspace
kernel::debugfs 1,752 31 no read/write file callbacks exchange bytes with userspace
kernel::str 1,066 18 no (marginal) CStr/BStr constructors validate arbitrary byte slices
kernel::configfs 1,044 40 no store callbacks parse userspace-written attribute bytes
kernel::uaccess 664 14 no UserSliceReader/Writer over untrusted user memory
kernel::miscdevice 439 30 no dispatches userspace ioctl/read/write to driver callbacks
kernel::iov 314 15 yes iov_iter ingesting user-supplied I/O vectors
sample_rust_misc_device 291 0 no ioctl + copy_from_user handling (demo)
drm_nova 226 0 no GPU ioctl args from userspace (skeleton driver)
sample_rust_debugfs_scoped 144 0 no reads userspace bytes via uaccess write callback

The smallest untrusted-input, union-free, low-unsafe units are the natural Phase 2 starting points: kernel::uaccess, kernel::miscdevice, and the debugfs samples. The larger targets (nova_core, android_binder, kernel::drm, kernel::iov) all carry the union blocker, so even a CLEAN Charon pass leaves an open Aeneas item on them.

Union-touching units (Aeneas blocker)

own = Rust union declared in the unit; anon = references to C __bindgen_anon_* union fields.

Unit own anon untrusted Note
android_binder 1 10 yes BinderObject union + binder_transaction_data uapi unions
nova_core 4 8 yes GSP firmware bindgen unions (GspFwWprMeta, RPC message)
kernel::drm 0 3 yes drm.h ioctl unions via gpuvm sm_ops
kernel::mm 0 6 no VMA/page bindgen union fields
kernel::iov 0 4 yes iov_iter bindgen union
kernel::iommu 0 2 no page-table bindgen union
kernel::gpu 0 2 no GPU buddy-allocator bindgen union
kernel::maple_tree 0 1 no maple-node bindgen union
kernel::module_param 0 1 no kernel_param bindgen union
kernel::bitmap 1 0 no BitmapRepr inline/pointer Rust union
rust_macros 0 1 no module! macro emits a kernel_param union field
vendor_zerocopy 5 0 n/a vendored (out of scope)

The Rust UAPI surface is narrow. Only 8 C headers are bindgen'd (binder.h, drm.h, panthor_drm.h, nova_drm.h, mdio.h, mii.h, ethtool.h, ioctl.h), of which binder.h, drm.h, panthor_drm.h, and ethtool.h contain unions. Union exposure concentrates in binder, the DRM/GPU stack, and the mm/iommu bindgen fields.

Notes on method

  • LOC = raw line count of the unit's .rs files. unsafe blocks = unsafe { … } occurrences (separately, unsafe_items counts unsafe fn/impl/trait, in the CSV).
  • own_union_decls counts real union Name { … } declarations (doc-comment examples excluded). bindgen_anon_refs counts __bindgen_anon field accesses, i.e. use of a C union member.
  • kernel_deps = most-frequent kernel::<x> references per unit (includes prelude macros).
  • Generated bindings (uapi_generated.rs, bindings_generated.rs) are build outputs and are not in the read-only tree; union exposure via UAPI was assessed from the C headers directly.
  • Two kernel submodules (kernel::drm, kernel::iommu) are declared via mod.rs with no top-level .rs file and are included as units.

Reproduce: SP=<scratch> python3 tools/metrics.py > $SP/metrics.csv && python3 tools/classify.py.