⬢ DragonFlyBSD Kernel Audit
DF-3561 / kernel_dm_crypt_demo.log
← back to finding ↓ download raw
# End-to-end kernel demonstration of DF-3561 (live DragonFly kernel, dm-crypt XTS)
# Guest: DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 (stock INVARIANTS kernel)
# /usr/src verified byte-identical to audited tree (sha256 563d468a... for cryptoapi.c)

# kldload dm_target_crypt; sysctl hw.aesni_disable=1 (force software XTS path)
hw.aesni_disable: 0 -> 1
vnconfig: /dev/vn0: /crypt.img, complete file mapped   (64 MB backing file)
dmsetup create cry0 --table "0 131072 crypt aes-xts-plain64 <256-bit key> 0 /dev/vn0 0"
dmsetup ls: cry0    (255, 504430599)

# --- serial baseline (write A then B, read back, compare) ---
serial A OK
serial B OK

# --- concurrent race: two dd writers to disjoint halves of the SAME volume ---
round 1: A=CORRUPT B=CORRUPT
round 2: A=CORRUPT B=CORRUPT
round 3: A=CORRUPT B=CORRUPT
round 4: A=CORRUPT B=CORRUPT
round 5: A=CORRUPT B=CORRUPT

# Interpretation: with two bios in flight, dmtc_bio_encdec() runs concurrently on
# the shared priv->crypto_session; aes_xts_crypt() (sys/crypto/cryptoapi/cryptoapi.c:431)
# calls aes_xts_reinit() which writes the tweak into the SHARED heap context
# (struct aes_xts_ctx.tweak, cryptoapi.c:373) and crypt_data_xts() then advances that
# shared tweak block-by-block (crypt_block_xts, cryptoapi.c:217-236). The second CPU's
# reinit/multiply tears the first CPU's tweak mid-sector -> wrong ciphertext persisted
# to the backing device; reads decrypt to garbage. Silent, persistent data corruption.
# (Same test with hw.aesni_disable=0 / AES-NI CPU would take the aesni_encrypt_xts
# path which keeps the tweak on the stack and is race-free.)