xref: /freebsd/tools/test/stress2/misc/pread.sh (revision 2e3f49888ec8851bafb22011533217487764fdb0)
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
73newfs $newfs_flags md$mdstart > /dev/null
74mount /dev/md$mdstart $mntpoint
75cp -a /usr/include $mntpoint
76echo "Testing FFS"
77/tmp/pread $mntpoint
78while mount | grep -q "on $mntpoint "; do
79	umount $mntpoint || sleep 1
80done
81mdconfig -d -u $mdstart
82
83mount -t nullfs /bin $mntpoint
84echo "Testing nullfs(5)"
85/tmp/pread $mntpoint
86while mount | grep -q "on $mntpoint "; do
87	umount $mntpoint || sleep 1
88done
89
90echo "Testing procfs(5)"
91mount -t procfs procfs $mntpoint
92/tmp/pread $mntpoint
93while mount | grep -q "on $mntpoint "; do
94	umount $mntpoint || sleep 1
95done
96
97echo "Testing devfs(8)"
98mount -t devfs devfs $mntpoint
99/tmp/pread $mntpoint
100while mount | grep -q "on $mntpoint "; do
101	umount $mntpoint || sleep 1
102done
103
104rm -f /tmp/pread
105exit 0
106EOF
107#include <sys/types.h>
108#include <strings.h>
109#include <dirent.h>
110#include <err.h>
111#include <errno.h>
112#include <fcntl.h>
113#include <fts.h>
114#include <pwd.h>
115#include <signal.h>
116#include <stdio.h>
117#include <stdlib.h>
118#include <sys/uio.h>
119#include <unistd.h>
120#include <sys/wait.h>
121
122static void
123hand(int i __unused) {	/* handler */
124	_exit(1);
125}
126
127int
128test(char *path)
129{
130
131	FTS		*fts;
132	FTSENT		*p;
133	int		ftsoptions;
134	char		*args[2];
135	int buf[64], fd;
136
137	signal(SIGSEGV, hand);
138	signal(SIGABRT, hand);
139	ftsoptions = FTS_PHYSICAL;
140	args[0] = path;
141	args[1] = 0;
142
143	if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
144		err(1, "fts_open");
145
146	while ((p = fts_read(fts)) != NULL) {
147		if ((fd = open(p->fts_path, O_RDONLY)) == -1) {
148			if (errno != EACCES && errno != ENXIO)
149				warn("open(%s)", p->fts_path);
150			continue;
151		}
152		alarm(1);
153		pread(fd, (void *)0xdeadc0de, 0x7ffffff, 0xffffffff);
154		pread(fd, buf, 0x7ffffff, 0xffffffff);
155		pread(fd, buf, sizeof(buf), 0xffffffff);
156		pread(fd, buf, sizeof(buf), 0);
157		close(fd);
158	}
159	fts_close(fts);
160
161	exit(0);
162}
163
164int
165main(int argc __unused, char **argv)
166{
167	int i;
168        struct passwd *pw;
169
170        if ((pw = getpwnam("nobody")) == NULL)
171                err(1, "no such user: nobody");
172
173        if (setgroups(1, &pw->pw_gid) ||
174            setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
175            seteuid(pw->pw_uid) || setuid(pw->pw_uid))
176                err(1, "Can't drop privileges to \"nobody\"");
177        endpwent();
178
179	if (daemon(0, 0) == -1)
180		err(1, "daemon()");
181
182	for (i = 0; i < 10; i++) {
183		if (fork() == 0)
184			test(argv[1]);
185		wait(NULL);
186	}
187
188	return (0);
189}
190