1162271Srwatson/*- 2162271Srwatson * Copyright (c) 2006 nCircle Network Security, Inc. 3172106Srwatson * Copyright (c) 2007 Robert N. M. Watson 4162271Srwatson * All rights reserved. 5162271Srwatson * 6162271Srwatson * This software was developed by Robert N. M. Watson for the TrustedBSD 7162271Srwatson * Project under contract to nCircle Network Security, Inc. 8162271Srwatson * 9162271Srwatson * Redistribution and use in source and binary forms, with or without 10162271Srwatson * modification, are permitted provided that the following conditions 11162271Srwatson * are met: 12162271Srwatson * 1. Redistributions of source code must retain the above copyright 13162271Srwatson * notice, this list of conditions and the following disclaimer. 14162271Srwatson * 2. Redistributions in binary form must reproduce the above copyright 15162271Srwatson * notice, this list of conditions and the following disclaimer in the 16162271Srwatson * documentation and/or other materials provided with the distribution. 17162271Srwatson * 18162271Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19162271Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20162271Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21162271Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 22162271Srwatson * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23162271Srwatson * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24162271Srwatson * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25162271Srwatson * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26162271Srwatson * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27162271Srwatson * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28162271Srwatson * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29162271Srwatson * 30162271Srwatson * $FreeBSD$ 31162271Srwatson */ 32162271Srwatson 33172106Srwatson/*- 34162271Srwatson * Test that raising current resource limits above hard resource limits 35172106Srwatson * requires privilege. We test three cases: 36162271Srwatson * 37172106Srwatson * - Raise the current above the maximum (privileged). 38172106Srwatson * - Raise the current to the maximum (unprivileged). 39172106Srwatson * - Raise the maximum (privileged). 40162271Srwatson */ 41162271Srwatson 42162271Srwatson#include <sys/types.h> 43162271Srwatson#include <sys/time.h> 44162271Srwatson#include <sys/resource.h> 45162271Srwatson 46162271Srwatson#include <err.h> 47162271Srwatson#include <errno.h> 48162271Srwatson#include <unistd.h> 49162271Srwatson 50162271Srwatson#include "main.h" 51162271Srwatson 52172106Srwatsonstatic int initialized; 53172106Srwatsonstatic struct rlimit rl_base; 54172106Srwatsonstatic struct rlimit rl_lowered; 55172106Srwatson 56172106Srwatsonint 57172106Srwatsonpriv_proc_setrlimit_setup(int asroot, int injail, struct test *test) 58162271Srwatson{ 59162271Srwatson 60172106Srwatson if (getrlimit(RLIMIT_DATA, &rl_base) < 0) { 61172106Srwatson warn("priv_proc_setrlimit_setup: getrlimit"); 62172106Srwatson return (-1); 63172106Srwatson } 64162271Srwatson 65162271Srwatson /* 66172106Srwatson * Must lower current and limit to make sure there's room to try to 67172106Srwatson * raise them during tests. Set current lower than max so we can 68172106Srwatson * raise it later also. 69162271Srwatson */ 70172106Srwatson rl_lowered = rl_base; 71172106Srwatson rl_lowered.rlim_cur -= 20; 72172106Srwatson rl_lowered.rlim_max -= 10; 73172106Srwatson if (setrlimit(RLIMIT_DATA, &rl_lowered) < 0) { 74172106Srwatson warn("priv_proc_setrlimit_setup: setrlimit"); 75172106Srwatson return (-1); 76172106Srwatson } 77172106Srwatson initialized = 1; 78172106Srwatson return (0); 79172106Srwatson} 80162271Srwatson 81172106Srwatson/* 82172106Srwatson * Try increasing the maximum limits on the process, which requires 83172106Srwatson * privilege. 84172106Srwatson */ 85172106Srwatsonvoid 86172106Srwatsonpriv_proc_setrlimit_raisemax(int asroot, int injail, struct test *test) 87172106Srwatson{ 88172106Srwatson struct rlimit rl; 89172106Srwatson int error; 90162271Srwatson 91172106Srwatson rl = rl_lowered; 92172106Srwatson rl.rlim_max = rl_base.rlim_max; 93172106Srwatson error = setrlimit(RLIMIT_DATA, &rl); 94172106Srwatson if (asroot && injail) 95172106Srwatson expect("priv_proc_setrlimit_raisemax(asroot, injail)", error, 96172106Srwatson 0, 0); 97172106Srwatson if (asroot && !injail) 98172106Srwatson expect("priv_proc_setrlimit_raisemax(asroot, !injail)", 99172106Srwatson error, 0, 0); 100172106Srwatson if (!asroot && injail) 101172106Srwatson expect("priv_proc_setrlimit_raisemax(!asroot, injail)", 102172106Srwatson error, -1, EPERM); 103172106Srwatson if (!asroot && !injail) 104172106Srwatson expect("priv_proc_setrlimit_raisemax(!asroot, !injail)", 105172106Srwatson error, -1, EPERM); 106172106Srwatson} 107162271Srwatson 108172106Srwatson/* 109172106Srwatson * Try setting the current limit to the current maximum, which is allowed 110172106Srwatson * without privilege. 111172106Srwatson */ 112172106Srwatsonvoid 113172106Srwatsonpriv_proc_setrlimit_raisecur_nopriv(int asroot, int injail, 114172106Srwatson struct test *test) 115172106Srwatson{ 116172106Srwatson struct rlimit rl; 117172106Srwatson int error; 118162271Srwatson 119172106Srwatson rl = rl_lowered; 120172106Srwatson rl.rlim_cur = rl.rlim_max; 121172106Srwatson error = setrlimit(RLIMIT_DATA, &rl); 122172106Srwatson if (asroot && injail) 123172106Srwatson expect("priv_proc_setrlimit_raiscur_nopriv(asroot, injail)", 124172106Srwatson error, 0, 0); 125172106Srwatson if (asroot && !injail) 126172106Srwatson expect("priv_proc_setrlimit_raisecur_nopriv(asroot, !injail)", 127172106Srwatson error, 0, 0); 128172106Srwatson if (!asroot && injail) 129172106Srwatson expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, injail)", 130172106Srwatson error, 0, 0); 131172106Srwatson if (!asroot && !injail) 132172106Srwatson expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, !injail)", 133172106Srwatson error, 0, 0); 134172106Srwatson} 135162271Srwatson 136172106Srwatson/* 137172106Srwatson * Try raising the current limits above the maximum, which requires 138172106Srwatson * privilege. 139172106Srwatson */ 140172106Srwatsonvoid 141172106Srwatsonpriv_proc_setrlimit_raisecur(int asroot, int injail, struct test *test) 142172106Srwatson{ 143172106Srwatson struct rlimit rl; 144172106Srwatson int error; 145162271Srwatson 146172106Srwatson rl = rl_lowered; 147172106Srwatson rl.rlim_cur = rl.rlim_max + 10; 148172106Srwatson error = setrlimit(RLIMIT_DATA, &rl); 149172106Srwatson if (asroot && injail) 150172106Srwatson expect("priv_proc_setrlimit_raisecur(asroot, injail)", error, 151172106Srwatson 0, 0); 152172106Srwatson if (asroot && !injail) 153172106Srwatson expect("priv_proc_setrlimit_raisecur(asroot, !injail)", 154172106Srwatson error, 0, 0); 155172106Srwatson if (!asroot && injail) 156172106Srwatson expect("priv_proc_setrlimit_raisecur(!asroot, injail)", 157172106Srwatson error, -1, EPERM); 158172106Srwatson if (!asroot && !injail) 159172106Srwatson expect("priv_proc_setrlimit_raisecur(!asroot, !injail)", 160172106Srwatson error, -1, EPERM); 161172106Srwatson} 162162271Srwatson 163172106Srwatsonvoid 164172106Srwatsonpriv_proc_setrlimit_cleanup(int asroot, int injail, struct test *test) 165172106Srwatson{ 166162271Srwatson 167172106Srwatson if (initialized) 168172106Srwatson (void)setrlimit(RLIMIT_DATA, &rl_base); 169172106Srwatson initialized = 0; 170162271Srwatson} 171