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 31 /*- 32 * Test that raising current resource limits above hard resource limits 33 * requires privilege. We test three cases: 34 * 35 * - Raise the current above the maximum (privileged). 36 * - Raise the current to the maximum (unprivileged). 37 * - Raise the maximum (privileged). 38 */ 39 40 #include <sys/types.h> 41 #include <sys/time.h> 42 #include <sys/resource.h> 43 44 #include <err.h> 45 #include <errno.h> 46 #include <unistd.h> 47 48 #include "main.h" 49 50 static int initialized; 51 static struct rlimit rl_base; 52 static struct rlimit rl_lowered; 53 54 int 55 priv_proc_setrlimit_setup(int asroot, int injail, struct test *test) 56 { 57 58 if (getrlimit(RLIMIT_DATA, &rl_base) < 0) { 59 warn("priv_proc_setrlimit_setup: getrlimit"); 60 return (-1); 61 } 62 63 /* 64 * Must lower current and limit to make sure there's room to try to 65 * raise them during tests. Set current lower than max so we can 66 * raise it later also. 67 */ 68 rl_lowered = rl_base; 69 rl_lowered.rlim_cur -= 20; 70 rl_lowered.rlim_max -= 10; 71 if (setrlimit(RLIMIT_DATA, &rl_lowered) < 0) { 72 warn("priv_proc_setrlimit_setup: setrlimit"); 73 return (-1); 74 } 75 initialized = 1; 76 return (0); 77 } 78 79 /* 80 * Try increasing the maximum limits on the process, which requires 81 * privilege. 82 */ 83 void 84 priv_proc_setrlimit_raisemax(int asroot, int injail, struct test *test) 85 { 86 struct rlimit rl; 87 int error; 88 89 rl = rl_lowered; 90 rl.rlim_max = rl_base.rlim_max; 91 error = setrlimit(RLIMIT_DATA, &rl); 92 if (asroot && injail) 93 expect("priv_proc_setrlimit_raisemax(asroot, injail)", error, 94 0, 0); 95 if (asroot && !injail) 96 expect("priv_proc_setrlimit_raisemax(asroot, !injail)", 97 error, 0, 0); 98 if (!asroot && injail) 99 expect("priv_proc_setrlimit_raisemax(!asroot, injail)", 100 error, -1, EPERM); 101 if (!asroot && !injail) 102 expect("priv_proc_setrlimit_raisemax(!asroot, !injail)", 103 error, -1, EPERM); 104 } 105 106 /* 107 * Try setting the current limit to the current maximum, which is allowed 108 * without privilege. 109 */ 110 void 111 priv_proc_setrlimit_raisecur_nopriv(int asroot, int injail, 112 struct test *test) 113 { 114 struct rlimit rl; 115 int error; 116 117 rl = rl_lowered; 118 rl.rlim_cur = rl.rlim_max; 119 error = setrlimit(RLIMIT_DATA, &rl); 120 if (asroot && injail) 121 expect("priv_proc_setrlimit_raiscur_nopriv(asroot, injail)", 122 error, 0, 0); 123 if (asroot && !injail) 124 expect("priv_proc_setrlimit_raisecur_nopriv(asroot, !injail)", 125 error, 0, 0); 126 if (!asroot && injail) 127 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, injail)", 128 error, 0, 0); 129 if (!asroot && !injail) 130 expect("priv_proc_setrlimit_raisecur_nopriv(!asroot, !injail)", 131 error, 0, 0); 132 } 133 134 /* 135 * Try raising the current limits above the maximum, which requires 136 * privilege. 137 */ 138 void 139 priv_proc_setrlimit_raisecur(int asroot, int injail, struct test *test) 140 { 141 struct rlimit rl; 142 int error; 143 144 rl = rl_lowered; 145 rl.rlim_cur = rl.rlim_max + 10; 146 error = setrlimit(RLIMIT_DATA, &rl); 147 if (asroot && injail) 148 expect("priv_proc_setrlimit_raisecur(asroot, injail)", error, 149 0, 0); 150 if (asroot && !injail) 151 expect("priv_proc_setrlimit_raisecur(asroot, !injail)", 152 error, 0, 0); 153 if (!asroot && injail) 154 expect("priv_proc_setrlimit_raisecur(!asroot, injail)", 155 error, -1, EPERM); 156 if (!asroot && !injail) 157 expect("priv_proc_setrlimit_raisecur(!asroot, !injail)", 158 error, -1, EPERM); 159 } 160 161 void 162 priv_proc_setrlimit_cleanup(int asroot, int injail, struct test *test) 163 { 164 165 if (initialized) 166 (void)setrlimit(RLIMIT_DATA, &rl_base); 167 initialized = 0; 168 } 169