/* $OpenBSD: copy.c,v 1.6 2021/12/13 16:56:49 deraadt Exp $ */ /* Written by Ted Unangst 2004 Public Domain */ #include #include #include #include #include #include #include #include #include #include #include #include int failure; static void fail(const char *str) { fprintf(stderr, "%s\n", str); failure++; } int main(int argc, char **argv) { char buf[4096]; char path[PATH_MAX + 1]; void *goodbuf; void *badbuf; int mib[6]; struct kinfo_proc kinfo; size_t kinfosize = sizeof(kinfo); int s, i; struct ifreq ifrdesc; s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) err(1, "socket"); mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); mib[4] = sizeof(struct kinfo_proc); mib[5] = 1; if (sysctl(mib, 6, &kinfo, &kinfosize, 0, 0)) err(1, "sysctl"); for (i = 0; i < PATH_MAX; i++) path[i] = (i % NAME_MAX) ? 'a' : '/'; path[PATH_MAX] = '\0'; goodbuf = buf; badbuf = (void*)(long)kinfo.p_paddr; /* printf("goodbuf %p badbuf %p\n", goodbuf, badbuf); */ /* copyin */ if (!syscall(202, 0, 6, &kinfo, &kinfosize, 0, 0)) fail("copyin did not fail on 0 buf\n"); if (!syscall(202, badbuf, 6, &kinfo, &kinfosize, 0, 0)) fail("copyin did not fail on bad buf\n"); /* copyout */ if (statfs("/", goodbuf)) fail("copyout failed on a good buf\n"); if (!statfs("/", 0) || errno != EFAULT) fail("copyout didn't fail on 0 buf\n"); if (!statfs("/", badbuf) || errno != EFAULT) fail("copyout didn't fail on bad buf\n"); /* copyoutstr */ memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = goodbuf; if (ioctl(s, SIOCGIFDESCR, &ifrdesc)) fail("SIOCIFDESCR ioctl failed\n"); memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = 0; if (!ioctl(s, SIOCGIFDESCR, &ifrdesc)) fail("copyoutstr didn't fail on 0 buf\n"); memset(&ifrdesc, 0, sizeof(ifrdesc)); strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); ifrdesc.ifr_data = badbuf; if (!ioctl(s, SIOCGIFDESCR, &ifrdesc)) fail("copyoutstr didn't fail on badbuf\n"); /* copyinstr */ if (statfs("/", goodbuf)) fail("copyinstr failed on a good buf\n"); if (!statfs(0, goodbuf) || errno != EFAULT) fail("copyinstr didn't fail on 0 buf\n"); if (!statfs(badbuf, goodbuf) || errno != EFAULT) fail("copyinstr didn't fail on bad buf\n"); if (!statfs(path, goodbuf) || errno != ENAMETOOLONG) fail("copyinstr didn't fail on long string\n"); if (failure) errx(1, "%d failures", failure); return 0; }