CVE-2023-40082 AI-generated analysis
platform/packages/modules/Virtualization, pvmfw (protected VM firmware), device tree preparation for the guest payload
pvmfw now generates a random 64-bit value and writes it into the guest device tree's /chosen/kaslr-seed property, so the template's constant placeholder (-1) is no longer passed to the guest.
Root cause
The pvmfw template device tree has a placeholder /chosen/kaslr-seed value (the commit message says the constant -1). modify_for_next_stage in pvmfw/src/fdt.rs patched the DICE node, set the strict-boot and new-instance chosen flags and filtered bootargs, but never wrote kaslr-seed. As a result the constant placeholder was passed to the guest.
How the fix works
- pvmfw/src/main.rs:main: before it configures the device tree, main calls rand::random_array() and converts the result with u64::from_ne_bytes into kaslr_seed. If the RNG fails, the error is logged ('Failed to generated guest KASLR seed') and mapped to RebootReason::InternalError, so the payload is not started.
- pvmfw/src/main.rs:main: passes kaslr_seed to modify_for_next_stage as a new trailing argument.
- pvmfw/src/fdt.rs:modify_for_next_stage: adds a new parameter kaslr_seed: u64. After setting the avf,strict-boot and avf,new-instance chosen flags, it writes the seed with fdt.chosen_mut()?.unwrap().setprop_inplace(cstr!("kaslr-seed"), &kaslr_seed.to_be_bytes()), i.e. it replaces the existing property in place with a big-endian value. libfdt errors propagate and main maps them to RebootReason::InternalError.
Completeness
- Covers the one place in the material where pvmfw builds the next-stage device tree: modify_for_next_stage, called once from main in pvmfw/src/main.rs. No other caller appears in the material.
- The write uses setprop_inplace, which replaces an existing property rather than creating one, so the fix relies on the template DT already containing a kaslr-seed placeholder. The template DT is not part of the diff.
- The write is unconditional (it does not depend on debuggable, strict_boot or debug_policy) and happens after debug-policy application, so that step cannot leave the placeholder in place.
- The quality of the seed depends on rand::random_array(), whose implementation is not shown in the material.
Behavior changes
- Guest kernels now receive a randomly generated /chosen/kaslr-seed value from pvmfw instead of the constant placeholder.
- New failure path: if rand::random_array() fails, pvmfw logs an error and returns RebootReason::InternalError instead of starting the payload.
- New failure path: a libfdt error when writing kaslr-seed is mapped to RebootReason::InternalError ('Failed to configure device tree'). A missing /chosen node would hit the .unwrap() and panic.
Per major
- Android 14: same fix: commit 0cf463e9949d in android-security-14.0.0_r3. All 8 lines of the patched region are still present at android-security-14.0.0_r29.
- Android 15: not affected per the bulletin. At android-security-15.0.0_r17, 5/8 lines of the patched region are present.
- Android 16: not affected per the bulletin. pvmfw/src/fdt.rs and pvmfw/src/main.rs are absent at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin. The patched files are absent at android-security-17.0.0_r1.
Unknowns
- The material does not show the implementation or entropy source of rand::random_array().
- The template DT change (if any) that defines the kaslr-seed placeholder is not shown. The commit only patches fdt.rs and main.rs.
- Whether Android 15's partially matching region writes kaslr-seed in an equivalent way is not shown. The material only shows that the bulletin does not list 15.
- How severely the constant seed weakened guest KASLR is not described beyond the commit message.