xref: /freebsd/tools/test/stress2/misc/pread.sh (revision 8881d206f4e68b564c2c5f50fc717086fc3e827a)
1#!/bin/sh
2
3#
4# Copyright (c) 2011 Peter Holm <pho@FreeBSD.org>
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# pread(2) fuzzing inspired by the iknowthis test suite
30# by Tavis Ormandy <taviso  cmpxchg8b com>
31
32# Fixed in r227527.
33
34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35
36. ../default.cfg
37
38here=`pwd`
39cd /tmp
40sed '1,/^EOF/d' < $here/$0 > pread.c
41mycc -o pread -Wall -Wextra pread.c
42rm -f pread.c
43
44mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
45mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
46
47mount -t tmpfs tmpfs $mntpoint
48cp -a /usr/include $mntpoint
49echo "Testing tmpfs(5)"
50/tmp/pread $mntpoint
51while mount | grep -q "on $mntpoint "; do
52	umount $mntpoint || sleep 1
53done
54
55echo "Testing fdescfs(5)"
56mount -t fdescfs null /dev/fd
57for i in `jot 100`; do
58	/tmp/pread /dev/fd
59done
60
61while mount | grep -q "on /dev/fd "; do
62	umount /dev/fd || sleep 1
63done
64
65echo "Testing procfs(5)"
66mount -t procfs procfs $mntpoint
67/tmp/pread $mntpoint
68while mount | grep -q "on $mntpoint "; do
69	umount $mntpoint || sleep 1
70done
71
72mdconfig -a -t swap -s 1g -u $mdstart || exit 1
73bsdlabel -w md$mdstart auto
74newfs $newfs_flags md${mdstart}$part > /dev/null
75mount /dev/md${mdstart}$part $mntpoint
76cp -a /usr/include $mntpoint
77echo "Testing FFS"
78/tmp/pread $mntpoint
79while mount | grep -q "on $mntpoint "; do
80	umount $mntpoint || sleep 1
81done
82mdconfig -d -u $mdstart
83
84mount -t nullfs /bin $mntpoint
85echo "Testing nullfs(5)"
86/tmp/pread $mntpoint
87while mount | grep -q "on $mntpoint "; do
88	umount $mntpoint || sleep 1
89done
90
91echo "Testing procfs(5)"
92mount -t procfs procfs $mntpoint
93/tmp/pread $mntpoint
94while mount | grep -q "on $mntpoint "; do
95	umount $mntpoint || sleep 1
96done
97
98echo "Testing devfs(8)"
99mount -t devfs devfs $mntpoint
100/tmp/pread $mntpoint
101while mount | grep -q "on $mntpoint "; do
102	umount $mntpoint || sleep 1
103done
104
105rm -f /tmp/pread
106exit 0
107EOF
108#include <sys/types.h>
109#include <strings.h>
110#include <dirent.h>
111#include <err.h>
112#include <errno.h>
113#include <fcntl.h>
114#include <fts.h>
115#include <pwd.h>
116#include <signal.h>
117#include <stdio.h>
118#include <stdlib.h>
119#include <sys/uio.h>
120#include <unistd.h>
121#include <sys/wait.h>
122
123static void
124hand(int i __unused) {	/* handler */
125	_exit(1);
126}
127
128int
129test(char *path)
130{
131
132	FTS		*fts;
133	FTSENT		*p;
134	int		ftsoptions;
135	char		*args[2];
136	int buf[64], fd;
137
138	signal(SIGSEGV, hand);
139	signal(SIGABRT, hand);
140	ftsoptions = FTS_PHYSICAL;
141	args[0] = path;
142	args[1] = 0;
143
144	if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
145		err(1, "fts_open");
146
147	while ((p = fts_read(fts)) != NULL) {
148		if ((fd = open(p->fts_path, O_RDONLY)) == -1) {
149			if (errno != EACCES && errno != ENXIO)
150				warn("open(%s)", p->fts_path);
151			continue;
152		}
153		alarm(1);
154		pread(fd, (void *)0xdeadc0de, 0x7ffffff, 0xffffffff);
155		pread(fd, buf, 0x7ffffff, 0xffffffff);
156		pread(fd, buf, sizeof(buf), 0xffffffff);
157		pread(fd, buf, sizeof(buf), 0);
158		close(fd);
159	}
160	fts_close(fts);
161
162	exit(0);
163}
164
165int
166main(int argc __unused, char **argv)
167{
168	int i;
169        struct passwd *pw;
170
171        if ((pw = getpwnam("nobody")) == NULL)
172                err(1, "no such user: nobody");
173
174        if (setgroups(1, &pw->pw_gid) ||
175            setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
176            seteuid(pw->pw_uid) || setuid(pw->pw_uid))
177                err(1, "Can't drop privileges to \"nobody\"");
178        endpwent();
179
180	if (daemon(0, 0) == -1)
181		err(1, "daemon()");
182
183	for (i = 0; i < 10; i++) {
184		if (fork() == 0)
185			test(argv[1]);
186		wait(NULL);
187	}
188
189	return (0);
190}
191