xref: /freebsd/tools/test/stress2/misc/mmap32.sh (revision 3494f7c0)
1#!/bin/sh
2
3#
4# Copyright (c) 2017 Dell EMC Isilon
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# Bug 223732 - mmap(2) causes unkillable denial of service with specific
30# flags
31# Test scenario inspired by:  Arto Pekkanen <aksyom@gmail.com>
32
33# Fixed by r326098.
34
35. ../default.cfg
36
37dir=/tmp
38odir=`pwd`
39cd $dir
40sed '1,/^EOF/d' < $odir/$0 > $dir/mmap32.c
41mycc -o mmap32 -Wall -Wextra -O0 -g mmap32.c || exit 1
42rm -f mmap32.c
43
44$dir/mmap32
45s=$?
46[ -f mmap32.core -a $s -eq 0 ] &&
47    { ls -l mmap32.core; mv mmap32.core /tmp; s=1; }
48
49rm -rf $dir/mmap32
50exit $s
51
52EOF
53#include <sys/param.h>
54#include <sys/mman.h>
55#include <sys/resource.h>
56#include <sys/wait.h>
57
58#include <err.h>
59#include <stdlib.h>
60#include <stdio.h>
61#include <time.h>
62#include <unistd.h>
63
64#define N 4096
65static int debug; /* set to 1 for debug output */
66static uint32_t r[N];
67
68static unsigned long
69makearg(void)
70{
71	unsigned int i;
72	unsigned long val;
73
74	val = arc4random();
75	i   = arc4random() % 100;
76	if (i < 20)
77		val = val & 0xff;
78	if (i >= 20 && i < 40)
79		val = val & 0xffff;
80	if (i >= 40 && i < 60)
81		val = (unsigned long)(r) | (val & 0xffff);
82#if defined(__LP64__)
83	if (i >= 60) {
84		val = (val << 32) | arc4random();
85		if (i > 80)
86			val = val & 0x00007fffffffffffUL;
87	}
88#endif
89
90	return(val);
91}
92
93static void
94fuzz(int arg, void *addr, size_t len, int prot, int flags, int fd,
95    off_t offset)
96{
97	time_t start;
98	void *vp;
99	int n;
100
101	setproctitle("arg%d", arg);
102	n = 0;
103	start = time(NULL);
104	while (time(NULL) - start < 10) {
105		switch (arg) {
106		case 1:
107			addr = (void *)makearg();
108			break;
109		case 2:
110			len = makearg();
111			break;
112		case 3:
113			prot = makearg();
114			break;
115		case 4:
116			flags = makearg();
117			break;
118		case 5:
119			fd = makearg();
120			break;
121		case 6:
122			offset = makearg() & 0xffff;
123			break;
124		case 34:
125			prot = makearg();
126			flags = makearg();
127			break;
128		default:
129			errx(1, "Bad argument %d to %s", arg, __func__);
130		}
131		vp = mmap(addr, len, prot, flags, fd, offset);
132		if (vp != MAP_FAILED) {
133			munmap(vp, len);
134			n++;
135		}
136	}
137	if (debug != 0 &&n == 0 && arg != 5)
138		fprintf(stderr, "%s(%d) failed\n", __func__, arg);
139	exit(0);
140}
141
142int
143main(void)
144{
145	off_t offset;
146	pid_t pid;
147	size_t len;
148	struct rlimit rl;
149	time_t start;
150	void *addr, *vp;
151	int e, flags, fd, i, prot, status;
152
153	e = 0;
154
155	rl.rlim_max = rl.rlim_cur = 0;
156	if (setrlimit(RLIMIT_CORE, &rl) == -1)
157		warn("setrlimit");
158	addr = 0;
159	len = PAGE_SIZE;
160	prot = PROT_READ | PROT_WRITE;
161	flags = MAP_ANON | MAP_SHARED;
162	fd = -1;
163	offset = 0;
164	vp = mmap(addr, len, prot, flags, fd, offset);
165	if (vp == MAP_FAILED)
166		err(1, "initail mmap");
167	munmap(vp, len);
168
169	start = time(NULL);
170	while (time(NULL) - start < 120) {
171		for (i = 0; i < N; i++)
172			r[i] = arc4random();
173		for (i = 0; i < 6; i++) {
174			if ((pid = fork()) == 0)
175				fuzz(i + 1, addr, len, prot, flags, fd,
176				    offset);
177			if (waitpid(pid, &status, 0) != pid)
178				err(1, "waitpid %d", pid);
179			if (status != 0) {
180				if (WIFSIGNALED(status))
181					fprintf(stderr,
182					    "pid %d exit signal %d\n",
183					    pid, WTERMSIG(status));
184			}
185			e += status == 0 ? 0 : 1;
186		}
187		if ((pid = fork()) == 0)
188			fuzz(34, addr, len, prot, flags, fd, offset);
189		if (waitpid(pid, &status, 0) != pid)
190			err(1, "waitpid %d", pid);
191		if (status != 0) {
192			if (WIFSIGNALED(status))
193				fprintf(stderr,
194				    "pid %d exit signal %d\n",
195				    pid, WTERMSIG(status));
196		}
197		e += status == 0 ? 0 : 1;
198	}
199
200	return (e);
201}
202