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