1 /*- 2 * Copyright (c) 2006 nCircle Network Security, Inc. 3 * Copyright (c) 2007 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * This software was developed by Robert N. M. Watson for the TrustedBSD 7 * Project under contract to nCircle Network Security, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR, NCIRCLE NETWORK SECURITY, 22 * INC., OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $FreeBSD$ 31 */ 32 33 /*- 34 * Test that raising current resource limits above hard resource limits 35 * requires privilege. We test three cases: 36 * 37 * - Raise the current above the maximum (privileged). 38 * - Raise the current to the maximum (unprivileged). 39 * - Raise the maximum (privileged). 40 */ 41 42 #include <sys/types.h> 43 #include <sys/time.h> 44 #include <sys/resource.h> 45 46 #include <err.h> 47 #include <errno.h> 48 #include <unistd.h> 49 50 #include "main.h" 51 52 static int initialized; 53 static struct rlimit rl_base; 54 static struct rlimit rl_lowered; 55 56 int 57 priv_proc_setrlimit_setup(int asroot, int injail, struct test *test) 58 { 59 60 if (getrlimit(RLIMIT_DATA, &rl_base) < 0) { 61 warn("priv_proc_setrlimit_setup: getrlimit"); 62 return (-1); 63 } 64 65 /* 66 * Must lower current and limit to make sure there's room to try to 67 * raise them during tests. Set current lower than max so we can 68 * raise it later also. 69 */ 70 rl_lowered = rl_base; 71 rl_lowered.rlim_cur -= 20; 72 rl_lowered.rlim_max -= 10; 73 if (setrlimit(RLIMIT_DATA, &rl_lowered) < 0) { 74 warn("priv_proc_setrlimit_setup: setrlimit"); 75 return (-1); 76 } 77 initialized = 1; 78 return (0); 79 } 80 81 /* 82 * Try increasing the maximum limits on the process, which requires 83 * privilege. 84 */ 85 void 86 priv_proc_setrlimit_raisemax(int asroot, int injail, struct test *test) 87 { 88 struct rlimit rl; 89 int error; 90 91 rl = rl_lowered; 92 rl.rlim_max = rl_base.rlim_max; 93 error = setrlimit(RLIMIT_DATA, &rl); 94 if (asroot && injail) 95 expect("priv_proc_setrlimit_raisemax(asroot, injail)", error, 96 0, 0); 97 if (asroot && !injail) 98 expect("priv_proc_setrlimit_raisemax(asroot, !injail)", 99 error, 0, 0); 100 if (!asroot && injail) 101 expect("priv_proc_setrlimit_raisemax(!asroot, injail)", 102 error, -1, EPERM); 103 if (!asroot && !injail) 104 expect("priv_proc_setrlimit_raisemax(!asroot, !injail)", 105 error, -1, EPERM); 106 } 107 108 /* 109 * Try setting the current limit to the current maximum, which is allowed 110 * without privilege. 111 */ 112 void 113 priv_proc_setrlimit_raisecur_nopriv(int asroot, int injail, 114 struct test *test) 115 { 116 struct rlimit rl; 117 int error; 118 119 rl = rl_lowered; 120 rl.rlim_cur = rl.rlim_max; 121 error = setrlimit(RLIMIT_DATA, &rl); 122 if (asroot && injail) 123 expect("priv_proc_setrlimit_raiscur_nopriv(asroot, injail)", 124 error, 0, 0); 125 if (asroot && !injail) 126 expect("priv_proc_setrlimit_raisecur_nopriv(asroot, !injail)", 127 error, 0, 0); 128 if (!asroot && injail) 129 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, injail)", 130 error, 0, 0); 131 if (!asroot && !injail) 132 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, !injail)", 133 error, 0, 0); 134 } 135 136 /* 137 * Try raising the current limits above the maximum, which requires 138 * privilege. 139 */ 140 void 141 priv_proc_setrlimit_raisecur(int asroot, int injail, struct test *test) 142 { 143 struct rlimit rl; 144 int error; 145 146 rl = rl_lowered; 147 rl.rlim_cur = rl.rlim_max + 10; 148 error = setrlimit(RLIMIT_DATA, &rl); 149 if (asroot && injail) 150 expect("priv_proc_setrlimit_raisecur(asroot, injail)", error, 151 0, 0); 152 if (asroot && !injail) 153 expect("priv_proc_setrlimit_raisecur(asroot, !injail)", 154 error, 0, 0); 155 if (!asroot && injail) 156 expect("priv_proc_setrlimit_raisecur(!asroot, injail)", 157 error, -1, EPERM); 158 if (!asroot && !injail) 159 expect("priv_proc_setrlimit_raisecur(!asroot, !injail)", 160 error, -1, EPERM); 161 } 162 163 void 164 priv_proc_setrlimit_cleanup(int asroot, int injail, struct test *test) 165 { 166 167 if (initialized) 168 (void)setrlimit(RLIMIT_DATA, &rl_base); 169 initialized = 0; 170 } 171