ugidfw_vnode.c (136774) | ugidfw_vnode.c (145412) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2005 Tom Rhodes |
|
2 * Copyright (c) 1999-2002 Robert N. M. Watson | 3 * Copyright (c) 1999-2002 Robert N. M. Watson |
3 * Copyright (c) 2001-2004 Networks Associates Technology, Inc. | 4 * Copyright (c) 2001-2005 Networks Associates Technology, Inc. |
4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. | 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. |
8 * It was later enhanced by Tom Rhodes for the TrustedBSD Project. |
|
7 * 8 * This software was developed for the FreeBSD Project in part by Network 9 * Associates Laboratories, the Security Research Division of Network 10 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11 * as part of the DARPA CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * | 9 * 10 * This software was developed for the FreeBSD Project in part by Network 11 * Associates Laboratories, the Security Research Division of Network 12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13 * as part of the DARPA CHATS research program. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * |
34 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 136774 2004-10-22 11:15:47Z rwatson $ | 36 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 145412 2005-04-22 18:49:30Z trhodes $ |
35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * "BSD Extended" MAC policy, allowing the administrator to impose 40 * mandatory rules regarding users and some system objects. | 37 */ 38 39/* 40 * Developed by the TrustedBSD Project. 41 * "BSD Extended" MAC policy, allowing the administrator to impose 42 * mandatory rules regarding users and some system objects. |
41 * 42 * XXX: Much locking support required here. | |
43 */ 44 45#include <sys/types.h> 46#include <sys/param.h> 47#include <sys/acl.h> 48#include <sys/conf.h> 49#include <sys/kernel.h> | 43 */ 44 45#include <sys/types.h> 46#include <sys/param.h> 47#include <sys/acl.h> 48#include <sys/conf.h> 49#include <sys/kernel.h> |
50#include <sys/lock.h> |
|
50#include <sys/mac.h> 51#include <sys/malloc.h> 52#include <sys/mount.h> | 51#include <sys/mac.h> 52#include <sys/malloc.h> 53#include <sys/mount.h> |
54#include <sys/mutex.h> |
|
53#include <sys/proc.h> 54#include <sys/systm.h> 55#include <sys/sysproto.h> 56#include <sys/sysent.h> 57#include <sys/vnode.h> 58#include <sys/file.h> 59#include <sys/socket.h> 60#include <sys/socketvar.h> --- 6 unchanged lines hidden (view full) --- 67#include <net/if_var.h> 68 69#include <vm/vm.h> 70 71#include <sys/mac_policy.h> 72 73#include <security/mac_bsdextended/mac_bsdextended.h> 74 | 55#include <sys/proc.h> 56#include <sys/systm.h> 57#include <sys/sysproto.h> 58#include <sys/sysent.h> 59#include <sys/vnode.h> 60#include <sys/file.h> 61#include <sys/socket.h> 62#include <sys/socketvar.h> --- 6 unchanged lines hidden (view full) --- 69#include <net/if_var.h> 70 71#include <vm/vm.h> 72 73#include <sys/mac_policy.h> 74 75#include <security/mac_bsdextended/mac_bsdextended.h> 76 |
77static struct mtx mac_bsdextended_mtx; 78 |
|
75SYSCTL_DECL(_security_mac); 76 77SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 78 "TrustedBSD extended BSD MAC policy controls"); 79 80static int mac_bsdextended_enabled = 1; 81SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 82 &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); --- 7 unchanged lines hidden (view full) --- 90static int rule_slots = 0; 91 92SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 93 &rule_count, 0, "Number of defined rules\n"); 94SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 95 &rule_slots, 0, "Number of used rule slots\n"); 96 97/* | 79SYSCTL_DECL(_security_mac); 80 81SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 82 "TrustedBSD extended BSD MAC policy controls"); 83 84static int mac_bsdextended_enabled = 1; 85SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 86 &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); --- 7 unchanged lines hidden (view full) --- 94static int rule_slots = 0; 95 96SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 97 &rule_count, 0, "Number of defined rules\n"); 98SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 99 &rule_slots, 0, "Number of used rule slots\n"); 100 101/* |
98 * This is just used for logging purposes as eventually we would like | 102 * This is just used for logging purposes, eventually we would like |
99 * to log much more then failed requests. 100 */ 101static int mac_bsdextended_logging; 102SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 103 &mac_bsdextended_logging, 0, "Log failed authorization requests"); 104 105/* 106 * This tunable is here for compatibility. It will allow the user --- 24 unchanged lines hidden (view full) --- 131 132static int 133sysctl_rule(SYSCTL_HANDLER_ARGS) 134{ 135 struct mac_bsdextended_rule temprule, *ruleptr; 136 u_int namelen; 137 int error, index, *name; 138 | 103 * to log much more then failed requests. 104 */ 105static int mac_bsdextended_logging; 106SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 107 &mac_bsdextended_logging, 0, "Log failed authorization requests"); 108 109/* 110 * This tunable is here for compatibility. It will allow the user --- 24 unchanged lines hidden (view full) --- 135 136static int 137sysctl_rule(SYSCTL_HANDLER_ARGS) 138{ 139 struct mac_bsdextended_rule temprule, *ruleptr; 140 u_int namelen; 141 int error, index, *name; 142 |
143 error = 0; |
|
139 name = (int *)arg1; 140 namelen = arg2; 141 142 /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 143 144 if (namelen != 1) 145 return (EINVAL); 146 147 index = name[0]; | 144 name = (int *)arg1; 145 namelen = arg2; 146 147 /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 148 149 if (namelen != 1) 150 return (EINVAL); 151 152 index = name[0]; |
148 if (index < 0 || index > rule_slots + 1) | 153 if (index > MAC_BSDEXTENDED_MAXRULES) |
149 return (ENOENT); | 154 return (ENOENT); |
150 if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 151 return (ENOENT); | |
152 | 155 |
153 if (req->oldptr) { 154 if (rules[index] == NULL) 155 return (ENOENT); 156 157 error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); | 156 ruleptr = NULL; 157 if (req->newptr && req->newlen != 0) { 158 error = SYSCTL_IN(req, &temprule, sizeof(temprule)); |
158 if (error) 159 return (error); | 159 if (error) 160 return (error); |
161 MALLOC(ruleptr, struct mac_bsdextended_rule *, 162 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); |
|
160 } 161 | 163 } 164 |
162 if (req->newptr) { 163 if (req->newlen == 0) { 164 /* printf("deletion\n"); */ 165 ruleptr = rules[index]; 166 if (ruleptr == NULL) 167 return (ENOENT); 168 rule_count--; 169 rules[index] = NULL; 170 FREE(ruleptr, M_MACBSDEXTENDED); 171 return(0); | 165 mtx_lock(&mac_bsdextended_mtx); 166 167 if (req->oldptr) { 168 if (index < 0 || index > rule_slots + 1) { 169 error = ENOENT; 170 goto out; |
172 } | 171 } |
173 error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 174 if (error) 175 return (error); | 172 if (rules[index] == NULL) { 173 error = ENOENT; 174 goto out; 175 } 176 temprule = *rules[index]; 177 } |
176 | 178 |
179 if (req->newptr && req->newlen == 0) { 180 /* printf("deletion\n"); */ 181 KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 182 ruleptr = rules[index]; 183 if (ruleptr == NULL) { 184 error = ENOENT; 185 goto out; 186 } 187 rule_count--; 188 rules[index] = NULL; 189 } else if (req->newptr) { |
|
177 error = mac_bsdextended_rule_valid(&temprule); 178 if (error) | 190 error = mac_bsdextended_rule_valid(&temprule); 191 if (error) |
179 return (error); | 192 goto out; |
180 181 if (rules[index] == NULL) { 182 /* printf("addition\n"); */ | 193 194 if (rules[index] == NULL) { 195 /* printf("addition\n"); */ |
183 MALLOC(ruleptr, struct mac_bsdextended_rule *, 184 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 185 M_ZERO); | |
186 *ruleptr = temprule; 187 rules[index] = ruleptr; | 196 *ruleptr = temprule; 197 rules[index] = ruleptr; |
188 if (index+1 > rule_slots) 189 rule_slots = index+1; | 198 ruleptr = NULL; 199 if (index + 1 > rule_slots) 200 rule_slots = index + 1; |
190 rule_count++; 191 } else { 192 /* printf("replacement\n"); */ 193 *rules[index] = temprule; 194 } 195 } 196 | 201 rule_count++; 202 } else { 203 /* printf("replacement\n"); */ 204 *rules[index] = temprule; 205 } 206 } 207 |
208out: 209 mtx_unlock(&mac_bsdextended_mtx); 210 if (ruleptr != NULL) 211 FREE(ruleptr, M_MACBSDEXTENDED); 212 if (req->oldptr && error == 0) { 213 error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 214 if (error) 215 return (error); 216 } 217 |
|
197 return (0); 198} 199 200SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 201 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 202 203static void 204mac_bsdextended_init(struct mac_policy_conf *mpc) 205{ 206 207 /* Initialize ruleset lock. */ | 218 return (0); 219} 220 221SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 222 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 223 224static void 225mac_bsdextended_init(struct mac_policy_conf *mpc) 226{ 227 228 /* Initialize ruleset lock. */ |
229 mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 230 |
|
208 /* Register dynamic sysctl's for rules. */ 209} 210 211static void 212mac_bsdextended_destroy(struct mac_policy_conf *mpc) 213{ 214 | 231 /* Register dynamic sysctl's for rules. */ 232} 233 234static void 235mac_bsdextended_destroy(struct mac_policy_conf *mpc) 236{ 237 |
215 /* Tear down sysctls. */ | |
216 /* Destroy ruleset lock. */ | 238 /* Destroy ruleset lock. */ |
239 mtx_destroy(&mac_bsdextended_mtx); 240 241 /* Tear down sysctls. */ |
|
217} 218 219static int 220mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 221 struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 222{ 223 int match; 224 225 /* 226 * Is there a subject match? 227 */ | 242} 243 244static int 245mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 246 struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 247{ 248 int match; 249 250 /* 251 * Is there a subject match? 252 */ |
253 mtx_assert(&mac_bsdextended_mtx, MA_OWNED); |
|
228 if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 229 match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 230 rule->mbr_subject.mbi_uid == cred->cr_ruid || 231 rule->mbr_subject.mbi_uid == cred->cr_svuid); 232 233 if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 234 match = !match; 235 --- 41 unchanged lines hidden (view full) --- 277 */ 278 if ((rule->mbr_mode & acc_mode) != acc_mode) { 279 if (mac_bsdextended_logging) 280 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 281 " on %d:%d failed. \n", cred->cr_ruid, 282 cred->cr_rgid, acc_mode, object_uid, object_gid); 283 return (EACCES); /* Matching rule denies access */ 284 } | 254 if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 255 match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 256 rule->mbr_subject.mbi_uid == cred->cr_ruid || 257 rule->mbr_subject.mbi_uid == cred->cr_svuid); 258 259 if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 260 match = !match; 261 --- 41 unchanged lines hidden (view full) --- 303 */ 304 if ((rule->mbr_mode & acc_mode) != acc_mode) { 305 if (mac_bsdextended_logging) 306 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 307 " on %d:%d failed. \n", cred->cr_ruid, 308 cred->cr_rgid, acc_mode, object_uid, object_gid); 309 return (EACCES); /* Matching rule denies access */ 310 } |
311 |
|
285 /* | 312 /* |
286 * If the rule matched and allowed access and first match is 287 * enabled, then return success. | 313 * If the rule matched, permits access, and first match is enabled, 314 * return success. |
288 */ 289 if (mac_bsdextended_firstmatch_enabled) 290 return (EJUSTRETURN); 291 else 292 return(0); 293} 294 295static int 296mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 297 int acc_mode) 298{ 299 int error, i; 300 301 if (suser_cred(cred, 0) == 0) 302 return (0); 303 | 315 */ 316 if (mac_bsdextended_firstmatch_enabled) 317 return (EJUSTRETURN); 318 else 319 return(0); 320} 321 322static int 323mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 324 int acc_mode) 325{ 326 int error, i; 327 328 if (suser_cred(cred, 0) == 0) 329 return (0); 330 |
331 mtx_lock(&mac_bsdextended_mtx); |
|
304 for (i = 0; i < rule_slots; i++) { 305 if (rules[i] == NULL) 306 continue; 307 308 /* | 332 for (i = 0; i < rule_slots; i++) { 333 if (rules[i] == NULL) 334 continue; 335 336 /* |
309 * Since we don't separately handle append, map append to | 337 * Since we do not separately handle append, map append to |
310 * write. 311 */ 312 if (acc_mode & MBI_APPEND) { 313 acc_mode &= ~MBI_APPEND; 314 acc_mode |= MBI_WRITE; 315 } 316 317 error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 318 object_gid, acc_mode); 319 if (error == EJUSTRETURN) 320 break; | 338 * write. 339 */ 340 if (acc_mode & MBI_APPEND) { 341 acc_mode &= ~MBI_APPEND; 342 acc_mode |= MBI_WRITE; 343 } 344 345 error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 346 object_gid, acc_mode); 347 if (error == EJUSTRETURN) 348 break; |
321 if (error) | 349 if (error) { 350 mtx_unlock(&mac_bsdextended_mtx); |
322 return (error); | 351 return (error); |
352 } |
|
323 } | 353 } |
324 | 354 mtx_unlock(&mac_bsdextended_mtx); |
325 return (0); 326} 327 328static int 329mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 330 struct label *label) 331{ 332 struct vattr vap; --- 532 unchanged lines hidden --- | 355 return (0); 356} 357 358static int 359mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 360 struct label *label) 361{ 362 struct vattr vap; --- 532 unchanged lines hidden --- |