DF-5756 / kread5756.c
/* DF-5756 — mount the crafted image with KICONV (cs_local=cs_dos=UTF-8) and * readdir: shows how the kernel's iconv_ucs handles the unpaired surrogates * stored in the LFN entries (sys/libiconv/iconv_ucs.c:255 checks only the * 0xd8 high-surrogate prefix; a leading U+DC00-DFFF unit is accepted at * :264-266 and only fails later in ucs4_to_utf8 when outbuf is too small, * degrading to a silent '?' instead of an invalid-input rejection). */ #include <sys/param.h> #include <sys/mount.h> #include <sys/iconv.h> #include <vfs/msdosfs/msdosfsmount.h> #include <dirent.h> #include <err.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { struct msdosfs_args args; char buf[8192]; long basep = 0; int fd, n; if (argc != 3) errx(1, "usage: %s <dev> <dir>", argv[0]); memset(&args, 0, sizeof(args)); args.fspec = argv[1]; args.uid = 0; args.gid = 0; args.mask = 0777 & ALLPERMS; /* literal mode bits (not umask) */ args.dirmask = 0777 & ALLPERMS; args.flags = MSDOSFSMNT_KICONV | MSDOSFSMNT_LONGNAME; strlcpy(args.cs_local, "UTF-8", sizeof(args.cs_local)); strlcpy(args.cs_dos, "UTF-8", sizeof(args.cs_dos)); if (mount("msdos", argv[2], 0, &args) < 0) err(1, "mount msdos %s", argv[1]); printf("[+] mounted %s at %s (KICONV cs_local=UTF-8 cs_dos=UTF-8)\n", argv[1], argv[2]); fd = open(argv[2], O_RDONLY); if (fd < 0) err(1, "open %s", argv[2]); printf("--- dirents:\n"); for (;;) { n = getdirentries(fd, buf, sizeof(buf), &basep); if (n <= 0) break; off_t off; for (off = 0; off < n;) { struct dirent *d = (struct dirent *)(buf + off); size_t i; printf(" namlen=%d name=\"", d->d_namlen); for (i = 0; i < d->d_namlen; i++) { unsigned char c = (unsigned char)d->d_name[i]; if (c >= 0x20 && c < 0x7f) putchar(c); else printf("\\x%02x", c); } printf("\"\n hex: "); for (i = 0; i < d->d_namlen; i++) printf("%02x ", (unsigned char)d->d_name[i]); printf("\n"); off += _DIRENT_DIRSIZ(d); } } close(fd); printf("[+] done (unmount from shell)\n"); return 0; } |