1#!/bin/sh 2 3# 4# Copyright (c) 2009 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# Variation of mmap2.sh with focus on random arguments for mprotect() 30# https://people.freebsd.org/~pho/stress/log/kostik209.txt 31 32. ../default.cfg 33 34odir=`pwd` 35cd /tmp 36sed '1,/^EOF/d' < $odir/$0 > mmap3.c 37mycc -o mmap3 -Wall mmap3.c -lpthread || exit 1 38rm -f mmap3.c 39 40start=`date '+%s'` 41while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do 42 ./mmap3 43done 44echo "Expect Segmentation faults" 45trap "ls /tmp/mmap3* 2>/dev/null | grep -E 'mmap3\.[0-9]{6}\.[0-9]{4}$' | \ 46 xargs rm -v" EXIT INT 47start=`date '+%s'` 48while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do 49 ./mmap3 random 50done 51rm -f /tmp/mmap3 mmap3.core 52exit 53 54EOF 55/* 56 Stress mmap by having max 100 threads mapping random areas within 57 a 100 Mb range. 58 */ 59#include <sys/types.h> 60#include <err.h> 61#include <stdio.h> 62#include <stdlib.h> 63#include <unistd.h> 64#include <fcntl.h> 65#include <pthread.h> 66#include <sys/mman.h> 67#include <sys/param.h> 68#include <string.h> 69#include <unistd.h> 70#include <errno.h> 71 72#define THREADS 100 73#define STARTADDR 0x50000000U 74#define ADRSPACE 0x06400000U /* 100 Mb */ 75 76static int ra; 77 78void 79trash(void *p) 80{ 81 unsigned long v; 82 83 mprotect(p, 0x570e3d38, 0x2c8fd54f); 84 if (ra) { 85 v = arc4random(); 86#if defined(__LP64__) 87 v = v << 32 | arc4random(); 88#endif 89 madvise((void *)v, arc4random(), arc4random()); 90 mprotect((void *)v, arc4random(), arc4random()); 91 msync((void *)v, arc4random(), arc4random()); 92 } 93 94} 95 96void 97work(int nr) 98{ 99 int fd, m; 100 void *p; 101 size_t len; 102 char path[128]; 103 104 p = (void *)STARTADDR; 105 len = ADRSPACE; 106 107 sprintf(path, "/tmp/mmap3.%06d.%04d", getpid(), nr); 108 if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) 109 err(1,"open()"); 110 if (ftruncate(fd, len) == -1) 111 err(1, "ftruncate"); 112 if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == 113 MAP_FAILED) { 114 if (errno == ENOMEM) 115 return; 116 err(1, "mmap()"); 117 } 118 if (unlink(path) == -1) 119 err(1, "unlink(%s)", path); 120 121 trash(p); 122 123 m = arc4random() % 10; 124 if (madvise(p, len, m) == -1) 125 warn("madvise(%p, %zd, %d)", p, len, m); 126 if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 ) 127 err(1, "mprotect failed with error:"); 128 if (msync(p, 0, MS_SYNC) == -1) 129 err(1, "msync(%p)", p); 130 if (munmap(p, len) == -1) 131 err(1, "munmap(%p)", p); 132 close(fd); 133} 134 135void * 136thr(void *arg) 137{ 138 int i; 139 140 for (i = 0; i < 512; i++) { 141 work(*(int *)arg); 142 } 143 return (0); 144} 145 146int 147main(int argc, char **argv) 148{ 149 pthread_t threads[THREADS]; 150 int nr[THREADS]; 151 int i, n, r; 152 153 n = arc4random() % 14 + 5; 154 ra = argc != 1; 155// printf("Address start 0x%x, address end 0x%x, pages %d, n %d\n", 156// STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT, n); 157 for (i = 0; i < n; i++) { 158 nr[i] = i; 159 if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0) 160 errc(1, r, "pthread_create()"); 161 } 162 163 for (i = 0; i < n; i++) { 164 if ((r = pthread_join(threads[i], NULL)) != 0) 165 errc(1, r, "pthread_join(%d)", i); 166 } 167 168 return (0); 169} 170