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