DF-5746 / trigger_benign.c
/* DF-5746 control — FULL well-formed xlat16 table must keep working * (no-regression control for the fix; also demonstrates in-bounds * behaviour differs from the OOB leak). * * Table: index[0x2E,'A'..'P',0x6B] -> 18 data blocks of 0x80 uint32, * datalen = 4096 + 18*512 = 13312 == exactly what the layout requires. * Block for rank r maps every input char to code 0x4200 | r, so each * converted char prints as 'B' followed by the block rank byte. * * Build: cc -O0 -g -I/usr/src/sys -o trigger_benign trigger_benign.c * Run: ./trigger_benign <suffix> <dev> <mountpoint> */ #include "common_kiconv.h" #include <dirent.h> #define IDX_BYTES (0x200 * 8) #define BLK_BYTES (0x80 * 4) #define NSLOTS 18 static void dump_dir(const char *dir) { char buf[32768]; long base = 0; int fd, n; fd = open(dir, O_RDONLY); if (fd < 0) err(1, "open %s", dir); while ((n = getdirentries(fd, buf, sizeof(buf), &base)) > 0) { char *p = buf, *end = buf + n; while (p < end) { struct dirent *d = (struct dirent *)p; printf("--- dirent namlen=%d: ", d->d_namlen); for (int i = 0; i < d->d_namlen; i++) { unsigned char c = (unsigned char)d->d_name[i]; if (c >= 0x20 && c < 0x7f) printf("%c", c); else printf("\\x%02x", c); } printf("\n"); p += _DIRENT_DIRSIZ(d); } } close(fd); } int main(int argc, char **argv) { char name[64], from[64]; static uint8_t tab[IDX_BYTES + NSLOTS * BLK_BYTES]; uint64_t *idx = (uint64_t *)tab; uint32_t *blk; const char *sfx, *dev, *dir; int rank = 0; if (argc != 4) { fprintf(stderr, "usage: %s <suffix> <dev> <mountpoint>\n", argv[0]); return (2); } sfx = argv[1]; dev = argv[2]; dir = argv[3]; /* full, well-formed table: index slots + one 512B block each */ idx['.'] = 1; for (int c = 'A'; c <= 'P'; c++) idx[c] = 1; idx['k'] = 1; for (int c = 0; c < 0x200; c++) { if (idx[c] == 0) continue; blk = (uint32_t *)(tab + IDX_BYTES + rank * BLK_BYTES); for (int j = 0; j < 0x80; j++) blk[j] = 0x4200 | rank; rank++; } snprintf(name, sizeof(name), "BEN%s", sfx); if (reg_pair("xlat16", name, "UTF-16BE", tab, sizeof(tab)) < 0) errx(1, "benign registration failed"); snprintf(from, sizeof(from), "BND%s", sfx); reg_pair("xlat16", "UTF-16BE", name, tab, sizeof(tab)); reg_pair("xlat16", from, name, tab, sizeof(tab)); reg_pair("xlat16", name, from, tab, sizeof(tab)); if (mount_kiconv(dev, dir, name, from) < 0) errx(1, "mount failed (regression!)"); fflush(stdout); dump_dir(dir); unmount(dir, 0); printf("[+] benign control done\n"); return (0); } |