1 /* $OpenBSD: copy.c,v 1.4 2011/04/10 03:20:59 guenther Exp $ */ 2 3 /* Written by Ted Unangst 2004 Public Domain */ 4 5 #include <sys/param.h> 6 #include <sys/mount.h> 7 #include <sys/sysctl.h> 8 #include <sys/types.h> 9 #include <sys/socket.h> 10 #include <sys/ioctl.h> 11 #include <sys/syslimits.h> 12 #include <net/if.h> 13 #include <strings.h> 14 #include <errno.h> 15 16 #include <stdio.h> 17 #include <err.h> 18 #include <unistd.h> 19 20 int failure; 21 22 static void 23 fail(const char *str) 24 { 25 fprintf(stderr, "%s\n", str); 26 failure++; 27 } 28 29 int 30 main(int argc, char **argv) 31 { 32 char buf[4096]; 33 char path[PATH_MAX + 1]; 34 void *goodbuf; 35 void *badbuf; 36 int mib[6]; 37 struct kinfo_proc kinfo; 38 size_t kinfosize = sizeof(kinfo); 39 int s, i; 40 struct ifreq ifrdesc; 41 42 43 s = socket(AF_INET, SOCK_DGRAM, 0); 44 if (s == -1) 45 err(1, "socket"); 46 47 mib[0] = CTL_KERN; 48 mib[1] = KERN_PROC; 49 mib[2] = KERN_PROC_PID; 50 mib[3] = getpid(); 51 mib[4] = sizeof(struct kinfo_proc); 52 mib[5] = 1; 53 54 if (sysctl(mib, 6, &kinfo, &kinfosize, 0, 0)) 55 err(1, "sysctl"); 56 57 for (i = 0; i < PATH_MAX; i++) 58 path[i] = (i % NAME_MAX) ? 'a' : '/'; 59 path[PATH_MAX] = '\0'; 60 61 goodbuf = buf; 62 badbuf = (void*)(long)kinfo.p_paddr; 63 64 /* printf("goodbuf %p badbuf %p\n", goodbuf, badbuf); */ 65 66 /* copyin */ 67 if (!syscall(202, 0, 6, &kinfo, &kinfosize, 0, 0)) 68 fail("copyin did not fail on 0 buf\n"); 69 if (!syscall(202, badbuf, 6, &kinfo, &kinfosize, 0, 0)) 70 fail("copyin did not fail on bad buf\n"); 71 72 /* copyout */ 73 if (statfs("/", goodbuf)) 74 fail("copyout failed on a good buf\n"); 75 if (!statfs("/", 0) || errno != EFAULT) 76 fail("copyout didn't fail on 0 buf\n"); 77 if (!statfs("/", badbuf) || errno != EFAULT) 78 fail("copyout didn't fail on bad buf\n"); 79 80 /* copyoutstr */ 81 memset(&ifrdesc, 0, sizeof(ifrdesc)); 82 strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); 83 ifrdesc.ifr_data = goodbuf; 84 if (ioctl(s, SIOCGIFDESCR, &ifrdesc)) 85 fail("SIOCIFDESCR ioctl failed\n"); 86 memset(&ifrdesc, 0, sizeof(ifrdesc)); 87 strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); 88 ifrdesc.ifr_data = 0; 89 if (!ioctl(s, SIOCGIFDESCR, &ifrdesc)) 90 fail("copyoutstr didn't fail on 0 buf\n"); 91 memset(&ifrdesc, 0, sizeof(ifrdesc)); 92 strlcpy(ifrdesc.ifr_name, "lo0", sizeof(ifrdesc.ifr_name)); 93 ifrdesc.ifr_data = badbuf; 94 if (!ioctl(s, SIOCGIFDESCR, &ifrdesc)) 95 fail("copyoutstr didn't fail on badbuf\n"); 96 97 /* copyinstr */ 98 if (statfs("/", goodbuf)) 99 fail("copyinstr failed on a good buf\n"); 100 if (!statfs(0, goodbuf) || errno != EFAULT) 101 fail("copyinstr didn't fail on 0 buf\n"); 102 if (!statfs(badbuf, goodbuf) || errno != EFAULT) 103 fail("copyinstr didn't fail on bad buf\n"); 104 if (!statfs(path, goodbuf) || errno != ENAMETOOLONG) 105 fail("copyinstr didn't fail on long string\n"); 106 107 if (failure) 108 errx(1, "%d failures", failure); 109 return 0; 110 } 111