DF-1603 / df1603_fixed.c
/* * DF-1603 - fixed-logic variant of the div-by-zero harness. * * Applies the same validation the fix.diff introduces to virtio_blk.c:702-705: * refuse blk_size < DEV_BSIZE or non-power-of-2 and fall back to 512. With * the validation in place, blk_size=0 no longer reaches the division on * line 709 and no SIGFPE/#DE is produced. * * Build: cc -O2 -o df1603_fixed df1603_fixed.c * Run: ./df1603_fixed ; exits 0 if NO div-by-zero happens (fix confirmed) */ #include <stdio.h> #include <stdint.h> #include <string.h> #define DEV_BSIZE 512 static int powerof2_local(unsigned x) { return x && ((x & (x - 1)) == 0); } /* Mirror virtio_blk.c:702-712 AFTER the fix.diff is applied. */ static void vtblk_alloc_disk_fixed(int feature_negotiated, uint64_t capacity, uint32_t blk_size, uint64_t *out_blocks, uint32_t *out_bs) { uint32_t sector_size; if (feature_negotiated && blk_size >= DEV_BSIZE && powerof2_local(blk_size)) sector_size = blk_size; else sector_size = DEV_BSIZE; /* fall back - the fix */ *out_bs = sector_size; *out_blocks = capacity * 512 / sector_size; } int main(void) { uint64_t blocks; uint32_t bs; /* Same malicious input as the trigger PoC: feature negotiated + 0. */ vtblk_alloc_disk_fixed(1, 0x100000ULL, 0, &blocks, &bs); printf("[fixed] blk_size=0 -> sector_size=%u (fell back to 512), " "blocks=%llu - NO div-by-zero\n", bs, (unsigned long long)blocks); if (bs == DEV_BSIZE && blocks == 0x100000ULL) { printf("[OK] fix confirmed: blk_size=0 no longer reaches the " "division; kernel would not panic.\n"); return 0; } printf("[FAIL] unexpected result.\n"); return 1; } |