xref: /freebsd/tools/test/stress2/misc/mmap32.sh (revision d4eeb02986980bf33dd56c41ceb9fc5f180c0d47)
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 uint32_t r[N];
66
67static unsigned long
68makearg(void)
69{
70	unsigned int i;
71	unsigned long val;
72
73	val = arc4random();
74	i   = arc4random() % 100;
75	if (i < 20)
76		val = val & 0xff;
77	if (i >= 20 && i < 40)
78		val = val & 0xffff;
79	if (i >= 40 && i < 60)
80		val = (unsigned long)(r) | (val & 0xffff);
81#if defined(__LP64__)
82	if (i >= 60) {
83		val = (val << 32) | arc4random();
84		if (i > 80)
85			val = val & 0x00007fffffffffffUL;
86	}
87#endif
88
89	return(val);
90}
91
92static void
93fuzz(int arg, void *addr, size_t len, int prot, int flags, int fd,
94    off_t offset)
95{
96	time_t start;
97	void *vp;
98	int n;
99
100	setproctitle("arg%d", arg);
101	n = 0;
102	start = time(NULL);
103	while (time(NULL) - start < 10) {
104		switch (arg) {
105		case 1:
106			addr = (void *)makearg();
107			break;
108		case 2:
109			len = makearg();
110			break;
111		case 3:
112			prot = makearg();
113			break;
114		case 4:
115			flags = makearg();
116			break;
117		case 5:
118			fd = makearg();
119			break;
120		case 6:
121			offset = makearg() & 0xffff;
122			break;
123		case 34:
124			prot = makearg();
125			flags = makearg();
126			break;
127		default:
128			errx(1, "Bad argument %d to %s", arg, __func__);
129		}
130		vp = mmap(addr, len, prot, flags, fd, offset);
131		if (vp != MAP_FAILED) {
132			munmap(vp, len);
133			n++;
134		}
135	}
136#if defined(DEBUG)
137	if (n == 0 && arg != 5)
138		fprintf(stderr, "%s(%d) failed\n", __func__, arg);
139#endif
140	exit(0);
141}
142
143int
144main(void)
145{
146	off_t offset;
147	pid_t pid;
148	size_t len;
149	struct rlimit rl;
150	time_t start;
151	void *addr, *vp;
152	int e, flags, fd, i, prot, status;
153
154	e = 0;
155
156	rl.rlim_max = rl.rlim_cur = 0;
157	if (setrlimit(RLIMIT_CORE, &rl) == -1)
158		warn("setrlimit");
159	addr = 0;
160	len = PAGE_SIZE;
161	prot = PROT_READ | PROT_WRITE;
162	flags = MAP_ANON | MAP_SHARED;
163	fd = -1;
164	offset = 0;
165	vp = mmap(addr, len, prot, flags, fd, offset);
166	if (vp == MAP_FAILED)
167		err(1, "initail mmap");
168	munmap(vp, len);
169
170	start = time(NULL);
171	while (time(NULL) - start < 120) {
172		for (i = 0; i < N; i++)
173			r[i] = arc4random();
174		for (i = 0; i < 6; i++) {
175			if ((pid = fork()) == 0)
176				fuzz(i + 1, addr, len, prot, flags, fd,
177				    offset);
178			if (waitpid(pid, &status, 0) != pid)
179				err(1, "waitpid %d", pid);
180			if (status != 0) {
181				if (WIFSIGNALED(status))
182					fprintf(stderr,
183					    "pid %d exit signal %d\n",
184					    pid, WTERMSIG(status));
185			}
186			e += status == 0 ? 0 : 1;
187		}
188		if ((pid = fork()) == 0)
189			fuzz(34, addr, len, prot, flags, fd, offset);
190		if (waitpid(pid, &status, 0) != pid)
191			err(1, "waitpid %d", pid);
192		if (status != 0) {
193			if (WIFSIGNALED(status))
194				fprintf(stderr,
195				    "pid %d exit signal %d\n",
196				    pid, WTERMSIG(status));
197		}
198		e += status == 0 ? 0 : 1;
199	}
200
201	return (e);
202}
203