xref: /openbsd/regress/sys/copy/copy.c (revision a6445c1d)
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