DF-3105 / df3105_craft.py
#!/usr/bin/env python3 # DF-3105 - craft a UDF image with a regular file whose extents span >4GB. # File BIG: 5 x 0x3FFFF000-byte extents (pos=4) + final 0x2000 extent (pos=6). # inf_len = 5*0x3FFFF000 + 0x2000 = 0x140001000 (~5.0GB) # - part-sec 4 (first sector of ext1): 0xBB fill # - part-sec 12 (intra-ext1 offset 0x4000 -> the CORRECT block for file # offset 4GB when the kernel used the full 64-bit offset): # 0x55 fill # - part-sec 6..7 (ext6 data): 0xCC fill # Expected correct behavior: mmap offset 0x100000000 (4GiB) reads 0x55 # (ext5 covers [0xFFFFC000, 0x13FFFF000); 4GiB-0xFFFFC000 = 0x4000 into # ext5 -> part-sec 4 + 8 = 12) # Buggy (uint32 truncation in udf_bmap_internal): offset 4GiB -> 0 -> ext1 # part-sec 4 -> 0xBB import sys, struct sys.path.insert(0, '/tmp/opencode/v30') import udflib as U BSIZE=2048; PART_ST=64 EXT=0x3FFFF000 ADS=[(EXT,4)]*5 + [(0x2000,6)] INF=EXT*5+0x2000 def fe_big(pr_sec): return U.file_entry(pr_sec, 5, 0, 0, 8*len(ADS), INF, INF//2048, ads=ADS) def root_extent(): buf=bytearray(BSIZE) fids=[] fids.append((U.fid_desc(0x08|0x01,0,0,b"",1),38)) fids.append((U.fid_desc(0x01,4,0,b"\x08BIG",2),42)) off=0 for f,tot in fids: buf[off:off+len(f)]=f; off+=(tot+3)&~3 assert off==84,off return bytes(buf), off img=bytearray(4096*BSIZE) def put(sec,data): img[sec*BSIZE:sec*BSIZE+BSIZE]=data[:BSIZE] put(16,U.vrs_entry("BEA01")); put(17,U.vrs_entry("NSR02")); put(18,U.vrs_entry("TEA01")) put(32,U.pvd()); put(33,U.pd()); put(34,U.lvd()) put(64+0,U.fsd()) rde,dlen=root_extent() put(64+1,U.file_entry(1,4,0,0,8,dlen,1,ads=[(2048,40)])) put(64+2,fe_big(2)) put(64+40,rde) # root dir extent at part-sec 40 b=bytearray(BSIZE) for i in range(BSIZE): b[i]=0xBB put(64+4,bytes(b)) # ext1 first sector for i in range(BSIZE): b[i]=0x55 put(64+12,bytes(b)) # correct block for 4GiB offset (via ext5) for i in range(BSIZE): b[i]=0xCC put(64+6,bytes(b)); put(64+7,bytes(b)) # ext6 put(256,U.anchor()) open('/tmp/opencode/v30/df3105.udf','wb').write(bytes(img)) print("wrote df3105.udf inf_len=%#x (%d bytes)" % (INF, INF)) |