xref: /openbsd/regress/sys/copy/copy.c (revision fda352e4)
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 
19 int failure;
20 
21 static void
fail(const char * str)22 fail(const char *str)
23 {
24 	fprintf(stderr, "%s\n", str);
25 	failure++;
26 }
27 
28 int
main(int argc,char ** argv)29 main(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