1977d8fb9SPeter Holm#!/bin/sh 2977d8fb9SPeter Holm 3977d8fb9SPeter Holm# 4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 5977d8fb9SPeter Holm# 6977d8fb9SPeter Holm# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org> 7977d8fb9SPeter Holm# 8977d8fb9SPeter Holm# Redistribution and use in source and binary forms, with or without 9977d8fb9SPeter Holm# modification, are permitted provided that the following conditions 10977d8fb9SPeter Holm# are met: 11977d8fb9SPeter Holm# 1. Redistributions of source code must retain the above copyright 12977d8fb9SPeter Holm# notice, this list of conditions and the following disclaimer. 13977d8fb9SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 14977d8fb9SPeter Holm# notice, this list of conditions and the following disclaimer in the 15977d8fb9SPeter Holm# documentation and/or other materials provided with the distribution. 16977d8fb9SPeter Holm# 17977d8fb9SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18977d8fb9SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19977d8fb9SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20977d8fb9SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21977d8fb9SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22977d8fb9SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23977d8fb9SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24977d8fb9SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25977d8fb9SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26977d8fb9SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27977d8fb9SPeter Holm# SUCH DAMAGE. 28977d8fb9SPeter Holm# 29977d8fb9SPeter Holm 30977d8fb9SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 31977d8fb9SPeter Holm 32977d8fb9SPeter Holm# Test setrlimit() max file size and ftruncate() 33977d8fb9SPeter Holm 34977d8fb9SPeter Holm# Problem seen: 35977d8fb9SPeter Holm# Testing UFS -O1 36977d8fb9SPeter Holm# setrlimit: ftruncate(5413) did not fail. limit = 2791 37977d8fb9SPeter Holm# Testing FFS -U 38977d8fb9SPeter Holm# setrlimit: ftruncate(9956) did not fail. limit = 7880 39977d8fb9SPeter Holm# Testing msdosfs 40977d8fb9SPeter Holm# setrlimit: ftruncate(9033) did not fail. limit = 5884 41977d8fb9SPeter Holm# Testing tmpfs 42977d8fb9SPeter Holm# setrlimit: ftruncate(123) did not fail. limit = 86 43977d8fb9SPeter Holm 44977d8fb9SPeter Holm. ../default.cfg 45977d8fb9SPeter Holm 46977d8fb9SPeter Holmcat > /tmp/setrlimit.c <<EOF 47977d8fb9SPeter Holm#include <sys/types.h> 48977d8fb9SPeter Holm#include <sys/resource.h> 49977d8fb9SPeter Holm#include <sys/stat.h> 50977d8fb9SPeter Holm 51977d8fb9SPeter Holm#include <err.h> 52977d8fb9SPeter Holm#include <errno.h> 53977d8fb9SPeter Holm#include <fcntl.h> 54977d8fb9SPeter Holm#include <signal.h> 55977d8fb9SPeter Holm#include <stdio.h> 56977d8fb9SPeter Holm#include <stdlib.h> 57977d8fb9SPeter Holm#include <unistd.h> 58977d8fb9SPeter Holm 59977d8fb9SPeter Holmstatic int signals; 60977d8fb9SPeter Holm 61977d8fb9SPeter Holmstatic void 62977d8fb9SPeter Holmhandler(int sig __unused) 63977d8fb9SPeter Holm{ 64977d8fb9SPeter Holm#if defined(DEBUG) 65977d8fb9SPeter Holm fprintf(stderr, "Got signal SIGXFSZ\n"); 66977d8fb9SPeter Holm#endif 67977d8fb9SPeter Holm signals++; 68977d8fb9SPeter Holm} 69977d8fb9SPeter Holm 70977d8fb9SPeter Holmvoid 71977d8fb9SPeter Holmtest(int argc, char *argv[]) 72977d8fb9SPeter Holm{ 73977d8fb9SPeter Holm struct rlimit rlim; 74977d8fb9SPeter Holm rlim_t limit, sz; 75977d8fb9SPeter Holm struct sigaction act; 76977d8fb9SPeter Holm long pos; 77977d8fb9SPeter Holm int e, expected, fd; 78977d8fb9SPeter Holm char file[] = "setrlimit.file"; 79977d8fb9SPeter Holm 80977d8fb9SPeter Holm if (argc != 2) { 81977d8fb9SPeter Holm fprintf(stderr, "Usage: %s <FS size>\n", argv[0]); 82977d8fb9SPeter Holm exit(1); 83977d8fb9SPeter Holm } 84977d8fb9SPeter Holm expected = signals = 0; 85977d8fb9SPeter Holm sz = atol(argv[1]); 86977d8fb9SPeter Holm arc4random_buf(&limit, sizeof(limit)); 87977d8fb9SPeter Holm if (limit < 0) 88977d8fb9SPeter Holm limit = -limit; 89977d8fb9SPeter Holm limit = limit % sz + 1; 90977d8fb9SPeter Holm rlim.rlim_cur = rlim.rlim_max = limit; 91977d8fb9SPeter Holm if (setrlimit(RLIMIT_FSIZE, &rlim) == -1) 92977d8fb9SPeter Holm err(1, "setrlimit(%ld)", limit); 93977d8fb9SPeter Holm 94977d8fb9SPeter Holm act.sa_handler = handler; 95977d8fb9SPeter Holm act.sa_flags = 0; 96977d8fb9SPeter Holm sigemptyset(&act.sa_mask); 97977d8fb9SPeter Holm if (sigaction(SIGXFSZ, &act, NULL) != 0) 98977d8fb9SPeter Holm err(1, "sigaction"); 99977d8fb9SPeter Holm 100977d8fb9SPeter Holm if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE)) == -1) 101977d8fb9SPeter Holm err(1, "open(%s)", file); 102977d8fb9SPeter Holm 103977d8fb9SPeter Holm e = 0; 104977d8fb9SPeter Holm arc4random_buf(&pos, sizeof(pos)); 105977d8fb9SPeter Holm if (pos < 0) 106977d8fb9SPeter Holm pos = -pos; 107977d8fb9SPeter Holm pos = pos % (limit * 2); 108977d8fb9SPeter Holm if (pos > limit) 109977d8fb9SPeter Holm expected = 1; 110977d8fb9SPeter Holm if (ftruncate(fd, pos) == -1) { 111977d8fb9SPeter Holm e = errno; 112977d8fb9SPeter Holm if (pos <= limit) 113977d8fb9SPeter Holm errc(1, e, "ftruncate(%ld), limit = %ld", pos, limit); 114977d8fb9SPeter Holm } else { 115977d8fb9SPeter Holm if (pos > limit) 116977d8fb9SPeter Holm errx(1, "ftruncate(%ld) did not fail. limit = %ld", pos, limit); 117977d8fb9SPeter Holm } 118977d8fb9SPeter Holm 119977d8fb9SPeter Holm if (lseek(fd, limit - 1, SEEK_SET) == -1) 120977d8fb9SPeter Holm err(1, "lseek(limit - 1)"); 121977d8fb9SPeter Holm if (write(fd, "a", 1) != 1) 122977d8fb9SPeter Holm err(1, "write() at limit - 1. limit = %ld", limit); 123977d8fb9SPeter Holm 124977d8fb9SPeter Holm if (write(fd, "b", 1) != -1) 125977d8fb9SPeter Holm err(1, "write() at limit. limit = %ld", limit); 126977d8fb9SPeter Holm expected++; 127977d8fb9SPeter Holm 128977d8fb9SPeter Holm /* Partial write test. No signal is expected */ 129977d8fb9SPeter Holm if (lseek(fd, limit - 1, SEEK_SET) == -1) 130977d8fb9SPeter Holm err(1, "lseek(limit - 1)"); 131977d8fb9SPeter Holm if (write(fd, "12", 2) != 1) 132977d8fb9SPeter Holm err(1, "write() at limit - 1. limit = %ld", limit); 133977d8fb9SPeter Holm 134977d8fb9SPeter Holm if (signals != expected) 135977d8fb9SPeter Holm errx(1, "Expected %d signals, got %d", expected, signals); 136977d8fb9SPeter Holm 137977d8fb9SPeter Holm close(fd); 138977d8fb9SPeter Holm unlink(file); 139977d8fb9SPeter Holm} 140977d8fb9SPeter Holm 141977d8fb9SPeter Holmint 142977d8fb9SPeter Holmmain(int argc, char *argv[]) 143977d8fb9SPeter Holm{ 144977d8fb9SPeter Holm int i; 145977d8fb9SPeter Holm 146977d8fb9SPeter Holm for (i = 0; i < 100; i++) 147977d8fb9SPeter Holm test(argc, argv); 148977d8fb9SPeter Holm 149977d8fb9SPeter Holm} 150977d8fb9SPeter HolmEOF 151977d8fb9SPeter Holm 152977d8fb9SPeter Holmhere=`pwd` 153977d8fb9SPeter Holms=0 154977d8fb9SPeter Holmcc -o /tmp/setrlimit -Wall -Wextra -O0 -g /tmp/setrlimit.c || exit 1 155977d8fb9SPeter Holm 156977d8fb9SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 157977d8fb9SPeter Holm[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 158977d8fb9SPeter Holm 159977d8fb9SPeter Holmecho "Testing UFS -O1" 160977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 161977d8fb9SPeter Holmnewfs -O1 /dev/md$mdstart > /dev/null 162977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint 163977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=1 164977d8fb9SPeter Holmcd $here 165977d8fb9SPeter Holmumount $mntpoint 166977d8fb9SPeter Holmmdconfig -d -u $mdstart 167977d8fb9SPeter Holm 168977d8fb9SPeter Holmecho "Testing FFS -U" 169977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 170977d8fb9SPeter Holmnewfs -U /dev/md$mdstart > /dev/null 171977d8fb9SPeter Holmmount /dev/md$mdstart $mntpoint 172977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 2)) 173977d8fb9SPeter Holmcd $here 174977d8fb9SPeter Holmumount $mntpoint 175977d8fb9SPeter Holmmdconfig -d -u $mdstart 176977d8fb9SPeter Holm 177977d8fb9SPeter Holmecho "Testing msdosfs" 178977d8fb9SPeter Holmmdconfig -t swap -s 1g -u $mdstart 179977d8fb9SPeter Holmnewfs_msdos -F 32 -b 8192 /dev/md$mdstart > /dev/null 2>&1 180977d8fb9SPeter Holmmount -t msdosfs /dev/md$mdstart $mntpoint 181977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 4)) 182977d8fb9SPeter Holmcd $here 183977d8fb9SPeter Holmumount $mntpoint 184977d8fb9SPeter Holmmdconfig -d -u $mdstart 185977d8fb9SPeter Holm 186977d8fb9SPeter Holmecho "Testing tmpfs" 187977d8fb9SPeter Holmmount -o size=20000 -t tmpfs dummy $mntpoint 188977d8fb9SPeter Holmcd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 8)) 189977d8fb9SPeter Holmcd $here 190977d8fb9SPeter Holmumount $mntpoint 191977d8fb9SPeter Holm 192977d8fb9SPeter Holmrm -f /tmp/setrlimit /tmp/setrlimit.c 193977d8fb9SPeter Holmexit $s 194