xref: /freebsd/tools/test/stress2/misc/kevent7.sh (revision 02e9120893770924227138ba49df1edb3896112a)
1#!/bin/sh
2
3#
4# Copyright (c) 2013 EMC Corp.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# Threaded syscall(2) fuzz test inspired by the iknowthis test suite
30# by Tavis Ormandy <taviso  cmpxchg8b com>
31
32# kevent(2) with random arguments.
33# Spinning threads seen.
34# Fixed in r255877.
35
36# "panic: softclock_call_cc: act 0xfffff801219a0840 0" seen:
37# https://people.freebsd.org/~pho/stress/log/kevent7.txt
38# Fixed by r315289
39
40[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
41
42. ../default.cfg
43
44ulimit -t 200
45odir=`pwd`
46cd /tmp
47sed '1,/^EOF/d' < $odir/$0 > kevent7.c
48rm -f /tmp/kevent7
49mycc -o kevent7 -Wall -Wextra -O2 -g kevent7.c -lpthread || exit 1
50rm -f kevent7.c
51
52mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
53mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
54
55mdconfig -a -t swap -s 2g -u $mdstart || exit 1
56newfs $newfs_flags md$mdstart > /dev/null
57mount /dev/md$mdstart $mntpoint
58chmod 777 $mntpoint
59
60for i in `jot 5`; do
61	(cd $mntpoint; /tmp/kevent7 $* < /dev/null) &
62	sleep 60
63	while pgrep -q kevent7; do
64		pkill -9 kevent7
65		sleep 1
66	done
67done
68
69for i in `jot 5`; do
70	mount | grep -q md$mdstart  && \
71		umount $mntpoint && mdconfig -d -u $mdstart && break
72	sleep 10
73done
74if mount | grep -q md$mdstart; then
75	fstat $mntpoint
76	echo "umount $mntpoint failed"
77	exit 1
78fi
79rm -f /tmp/kevent7
80exit 0
81EOF
82#include <sys/types.h>
83#include <sys/event.h>
84#include <sys/param.h>
85#include <sys/stat.h>
86#include <sys/syscall.h>
87#include <sys/wait.h>
88
89#include <err.h>
90#include <errno.h>
91#include <fcntl.h>
92#include <fts.h>
93#include <libutil.h>
94#include <pthread.h>
95#include <pwd.h>
96#include <signal.h>
97#include <sys/socket.h>
98#include <stdint.h>
99#include <stdio.h>
100#include <stdlib.h>
101#include <string.h>
102#include <unistd.h>
103
104#define THREADS 50
105
106int fd[900], fds[2], socketpr[2];
107#define N (128 * 1024 / (int)sizeof(u_int32_t))
108static u_int32_t r[N];
109static int syscallno;
110
111static void
112hand(int i __unused) {	/* handler */
113	_exit(1);
114}
115
116static unsigned long
117makearg(void)
118{
119	unsigned int i;
120	unsigned long val;
121
122	val = arc4random();
123	i   = arc4random() % 100;
124	if (i < 20)
125		val = val & 0xff;
126	if (i >= 20 && i < 40)
127		val = val & 0xffff;
128	if (i >= 40 && i < 60)
129		val = (unsigned long)(r) | (val & 0xffff);
130#if defined(__LP64__)
131	if (i >= 60) {
132		val = (val << 32) | arc4random();
133		if (i > 80)
134			val = val & 0x00007fffffffffffUL;
135	}
136#endif
137
138	return(val);
139}
140
141static void *
142test(void *arg __unused)
143{
144
145	FTS		*fts;
146	FTSENT		*p;
147	int		ftsoptions;
148	int i;
149	char		*args[5];
150
151	ftsoptions = FTS_PHYSICAL;
152	args[0] = "/dev";
153	args[1] = "/proc";
154	args[2] = "/usr/compat/linux/proc";
155	args[3] = ".";
156	args[4] = 0;
157
158	for (;;) {
159		for (i = 0; i < N; i++)
160			r[i] = arc4random();
161		if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
162			err(1, "fts_open");
163
164		i = 0;
165		while ((p = fts_read(fts)) != NULL) {
166			if (fd[i] > 0)
167				close(fd[i]);
168			if ((fd[i] = open(p->fts_path, O_RDWR)) == -1)
169				if ((fd[i] = open(p->fts_path, O_WRONLY)) ==
170				    -1)
171					if ((fd[i] = open(p->fts_path,
172					    O_RDONLY)) == -1)
173						continue;
174			i++;
175			i = i % nitems(fd);
176		}
177
178		if (fts_close(fts) == -1)
179			if (errno != ENOTDIR)
180				warn("fts_close()");
181		if (pipe(fds) == -1)
182			err(1, "pipe()");
183		if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, socketpr) == -1)
184			err(1, "socketpair()");
185		sleep(1);
186		close(socketpr[0]);
187		close(socketpr[1]);
188		close(fds[0]);
189		close(fds[1]);
190	}
191	return(0);
192}
193
194static void *
195calls(void *arg __unused)
196{
197	unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
198	int i, kq, num;
199
200	if ((kq = kqueue()) < 0)
201		err(1, "kqueue()");
202	for (i = 0; i < 1000; i++) {
203		if (i == 0)
204			usleep(1000);
205		num = syscallno;
206		arg1 = makearg();
207		arg2 = makearg();
208		arg3 = makearg();
209		arg4 = makearg();
210		arg5 = makearg();
211		arg6 = makearg();
212		arg7 = makearg();
213
214#if 0
215		fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx,"
216		   " %lx, %lx)\n",
217			i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
218#endif
219		alarm(1);
220		syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
221		num = 0;
222	}
223	close(kq);
224
225	return (0);
226}
227
228int
229main(void)
230{
231	struct passwd *pw;
232	time_t start;
233	pthread_t rp, cp[THREADS];
234	int e, j, n;
235
236	if ((pw = getpwnam("nobody")) == NULL)
237		err(1, "no such user: nobody");
238
239	if (setgroups(1, &pw->pw_gid) ||
240	    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
241	    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
242		err(1, "Can't drop privileges to \"nobody\"");
243	endpwent();
244
245	signal(SIGALRM, hand);
246	signal(SIGILL,  hand);
247	signal(SIGFPE,  hand);
248	signal(SIGSEGV, hand);
249	signal(SIGBUS,  hand);
250	signal(SIGURG,  hand);
251	signal(SIGSYS,  hand);
252	signal(SIGTRAP, hand);
253
254	syscallno = SYS_kevent;
255
256	n = 0;
257	start = time(NULL);
258	while (time(NULL) - start < 120) {
259		if (fork() == 0) {
260			if ((e = pthread_create(&rp, NULL, test, NULL)) != 0)
261				errc(1, e, "pthread_create");
262			usleep(1000);
263			for (j = 0; j < THREADS; j++) {
264				if ((e = pthread_create(&cp[j], NULL, calls,
265				    NULL)) != 0)
266					errc(1, e, "pthread_create");
267			}
268			for (j = 0; j < THREADS; j++)
269				pthread_join(cp[j], NULL);
270			if ((e = pthread_kill(rp, SIGINT)) != 0)
271				errc(1, e, "pthread_kill");
272			_exit(0);
273		}
274		wait(NULL);
275		if (n++ > 5000)
276			break;
277	}
278
279	return (0);
280}
281