ugidfw_vnode.c revision 168976
1101099Srwatson/*- 2145412Strhodes * Copyright (c) 2005 Tom Rhodes 3166905Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 4145412Strhodes * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 5101099Srwatson * All rights reserved. 6101099Srwatson * 7101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8145412Strhodes * It was later enhanced by Tom Rhodes for the TrustedBSD Project. 9101099Srwatson * 10106393Srwatson * This software was developed for the FreeBSD Project in part by Network 11106393Srwatson * Associates Laboratories, the Security Research Division of Network 12106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13106393Srwatson * as part of the DARPA CHATS research program. 14101099Srwatson * 15101099Srwatson * Redistribution and use in source and binary forms, with or without 16101099Srwatson * modification, are permitted provided that the following conditions 17101099Srwatson * are met: 18101099Srwatson * 1. Redistributions of source code must retain the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer. 20101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 21101099Srwatson * notice, this list of conditions and the following disclaimer in the 22101099Srwatson * documentation and/or other materials provided with the distribution. 23101099Srwatson * 24101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34101099Srwatson * SUCH DAMAGE. 35101099Srwatson * 36101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 168976 2007-04-23 13:15:23Z rwatson $ 37101099Srwatson */ 38136774Srwatson 39101099Srwatson/* 40101099Srwatson * Developed by the TrustedBSD Project. 41101099Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose 42101099Srwatson * mandatory rules regarding users and some system objects. 43101099Srwatson */ 44101099Srwatson 45101099Srwatson#include <sys/param.h> 46101099Srwatson#include <sys/acl.h> 47101099Srwatson#include <sys/kernel.h> 48157986Sdwmalone#include <sys/jail.h> 49145412Strhodes#include <sys/lock.h> 50101099Srwatson#include <sys/malloc.h> 51166905Srwatson#include <sys/module.h> 52101099Srwatson#include <sys/mount.h> 53145412Strhodes#include <sys/mutex.h> 54101099Srwatson#include <sys/systm.h> 55101099Srwatson#include <sys/vnode.h> 56101099Srwatson#include <sys/sysctl.h> 57134132Strhodes#include <sys/syslog.h> 58101099Srwatson 59165469Srwatson#include <security/mac/mac_policy.h> 60101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 61101099Srwatson 62145412Strhodesstatic struct mtx mac_bsdextended_mtx; 63145412Strhodes 64101099SrwatsonSYSCTL_DECL(_security_mac); 65101099Srwatson 66101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 67101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 68101099Srwatson 69101099Srwatsonstatic int mac_bsdextended_enabled = 1; 70101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 71101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 72101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 73101099Srwatson 74101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 75101099Srwatson 76101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 77101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 78101099Srwatsonstatic int rule_count = 0; 79101099Srwatsonstatic int rule_slots = 0; 80157986Sdwmalonestatic int rule_version = MB_VERSION; 81101099Srwatson 82101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 83101099Srwatson &rule_count, 0, "Number of defined rules\n"); 84101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 85101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 86157986SdwmaloneSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD, 87157986Sdwmalone &rule_version, 0, "Version number for API\n"); 88101099Srwatson 89134132Strhodes/* 90145412Strhodes * This is just used for logging purposes, eventually we would like 91134132Strhodes * to log much more then failed requests. 92134132Strhodes */ 93134132Strhodesstatic int mac_bsdextended_logging; 94134132StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 95134132Strhodes &mac_bsdextended_logging, 0, "Log failed authorization requests"); 96134132Strhodes 97134132Strhodes/* 98134131Strhodes * This tunable is here for compatibility. It will allow the user 99134131Strhodes * to switch between the new mode (first rule matches) and the old 100134131Strhodes * functionality (all rules match). 101134131Strhodes */ 102101099Srwatsonstatic int 103134131Strhodesmac_bsdextended_firstmatch_enabled; 104134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 105135039Strhodes CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 106134131Strhodes "Disable/enable match first rule functionality"); 107134131Strhodes 108134131Strhodesstatic int 109101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 110101099Srwatson{ 111101099Srwatson 112157986Sdwmalone if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 113101099Srwatson return (EINVAL); 114101099Srwatson 115157986Sdwmalone if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 116101099Srwatson return (EINVAL); 117101099Srwatson 118157986Sdwmalone if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 119157986Sdwmalone return (EINVAL); 120157986Sdwmalone 121157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 122157986Sdwmalone return (EINVAL); 123157986Sdwmalone 124157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) && 125157986Sdwmalone (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE) 126157986Sdwmalone return (EINVAL); 127157986Sdwmalone 128136739Srwatson if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 129101099Srwatson return (EINVAL); 130101099Srwatson 131101099Srwatson return (0); 132101099Srwatson} 133101099Srwatson 134101099Srwatsonstatic int 135101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 136101099Srwatson{ 137101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 138101099Srwatson u_int namelen; 139101099Srwatson int error, index, *name; 140101099Srwatson 141145412Strhodes error = 0; 142101099Srwatson name = (int *)arg1; 143101099Srwatson namelen = arg2; 144101099Srwatson 145101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 146101099Srwatson 147101099Srwatson if (namelen != 1) 148101099Srwatson return (EINVAL); 149101099Srwatson 150101099Srwatson index = name[0]; 151154386Scsjp if (index >= MAC_BSDEXTENDED_MAXRULES) 152101099Srwatson return (ENOENT); 153101099Srwatson 154145412Strhodes ruleptr = NULL; 155145412Strhodes if (req->newptr && req->newlen != 0) { 156145412Strhodes error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 157101099Srwatson if (error) 158101099Srwatson return (error); 159145412Strhodes MALLOC(ruleptr, struct mac_bsdextended_rule *, 160145412Strhodes sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); 161101099Srwatson } 162101099Srwatson 163145412Strhodes mtx_lock(&mac_bsdextended_mtx); 164145412Strhodes 165145412Strhodes if (req->oldptr) { 166145412Strhodes if (index < 0 || index > rule_slots + 1) { 167145412Strhodes error = ENOENT; 168145412Strhodes goto out; 169101099Srwatson } 170145412Strhodes if (rules[index] == NULL) { 171145412Strhodes error = ENOENT; 172145412Strhodes goto out; 173145412Strhodes } 174145412Strhodes temprule = *rules[index]; 175145412Strhodes } 176101099Srwatson 177145412Strhodes if (req->newptr && req->newlen == 0) { 178145412Strhodes /* printf("deletion\n"); */ 179145412Strhodes KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 180145412Strhodes ruleptr = rules[index]; 181145412Strhodes if (ruleptr == NULL) { 182145412Strhodes error = ENOENT; 183145412Strhodes goto out; 184145412Strhodes } 185145412Strhodes rule_count--; 186145412Strhodes rules[index] = NULL; 187145412Strhodes } else if (req->newptr) { 188101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 189101099Srwatson if (error) 190145412Strhodes goto out; 191101099Srwatson 192101099Srwatson if (rules[index] == NULL) { 193101099Srwatson /* printf("addition\n"); */ 194101099Srwatson *ruleptr = temprule; 195101099Srwatson rules[index] = ruleptr; 196145412Strhodes ruleptr = NULL; 197145412Strhodes if (index + 1 > rule_slots) 198145412Strhodes rule_slots = index + 1; 199101099Srwatson rule_count++; 200101099Srwatson } else { 201101099Srwatson /* printf("replacement\n"); */ 202101099Srwatson *rules[index] = temprule; 203101099Srwatson } 204101099Srwatson } 205101099Srwatson 206145412Strhodesout: 207145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 208145412Strhodes if (ruleptr != NULL) 209145412Strhodes FREE(ruleptr, M_MACBSDEXTENDED); 210148482Strhodes if (req->oldptr && error == 0) 211145412Strhodes error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 212145412Strhodes 213148482Strhodes return (error); 214101099Srwatson} 215101099Srwatson 216101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 217101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 218101099Srwatson 219101099Srwatsonstatic void 220101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 221101099Srwatson{ 222101099Srwatson 223101099Srwatson /* Initialize ruleset lock. */ 224145412Strhodes mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 225145412Strhodes 226101099Srwatson /* Register dynamic sysctl's for rules. */ 227101099Srwatson} 228101099Srwatson 229101099Srwatsonstatic void 230101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 231101099Srwatson{ 232101099Srwatson 233145412Strhodes /* Destroy ruleset lock. */ 234145412Strhodes mtx_destroy(&mac_bsdextended_mtx); 235145412Strhodes 236101099Srwatson /* Tear down sysctls. */ 237101099Srwatson} 238101099Srwatson 239101099Srwatsonstatic int 240101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 241157986Sdwmalone struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode) 242101099Srwatson{ 243101099Srwatson int match; 244157986Sdwmalone int i; 245101099Srwatson 246101099Srwatson /* 247101099Srwatson * Is there a subject match? 248101099Srwatson */ 249145412Strhodes mtx_assert(&mac_bsdextended_mtx, MA_OWNED); 250157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) { 251157986Sdwmalone match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max && 252157986Sdwmalone cred->cr_uid >= rule->mbr_subject.mbs_uid_min) || 253157986Sdwmalone (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max && 254157986Sdwmalone cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) || 255157986Sdwmalone (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max && 256157986Sdwmalone cred->cr_svuid >= rule->mbr_subject.mbs_uid_min)); 257101099Srwatson 258157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED) 259101099Srwatson match = !match; 260101099Srwatson 261101099Srwatson if (!match) 262101099Srwatson return (0); 263101099Srwatson } 264101099Srwatson 265157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) { 266157986Sdwmalone match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max && 267157986Sdwmalone cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) || 268157986Sdwmalone (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max && 269157986Sdwmalone cred->cr_svgid >= rule->mbr_subject.mbs_gid_min)); 270101099Srwatson 271157986Sdwmalone if (!match) { 272157986Sdwmalone for (i = 0; i < cred->cr_ngroups; i++) 273157986Sdwmalone if (cred->cr_groups[i] 274157986Sdwmalone <= rule->mbr_subject.mbs_gid_max && 275157986Sdwmalone cred->cr_groups[i] 276157986Sdwmalone >= rule->mbr_subject.mbs_gid_min) { 277157986Sdwmalone match = 1; 278157986Sdwmalone break; 279157986Sdwmalone } 280157986Sdwmalone } 281157986Sdwmalone 282157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED) 283101099Srwatson match = !match; 284101099Srwatson 285101099Srwatson if (!match) 286101099Srwatson return (0); 287101099Srwatson } 288101099Srwatson 289157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) { 290157986Sdwmalone match = (cred->cr_prison != NULL && 291157986Sdwmalone cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison); 292157986Sdwmalone 293157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED) 294157986Sdwmalone match = !match; 295157986Sdwmalone 296157986Sdwmalone if (!match) 297157986Sdwmalone return (0); 298157986Sdwmalone } 299157986Sdwmalone 300101099Srwatson /* 301101099Srwatson * Is there an object match? 302101099Srwatson */ 303157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) { 304157986Sdwmalone match = (vap->va_uid <= rule->mbr_object.mbo_uid_max && 305157986Sdwmalone vap->va_uid >= rule->mbr_object.mbo_uid_min); 306101099Srwatson 307157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED) 308101099Srwatson match = !match; 309101099Srwatson 310101099Srwatson if (!match) 311101099Srwatson return (0); 312101099Srwatson } 313101099Srwatson 314157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) { 315157986Sdwmalone match = (vap->va_gid <= rule->mbr_object.mbo_gid_max && 316157986Sdwmalone vap->va_gid >= rule->mbr_object.mbo_gid_min); 317101099Srwatson 318157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED) 319101099Srwatson match = !match; 320101099Srwatson 321101099Srwatson if (!match) 322101099Srwatson return (0); 323101099Srwatson } 324101099Srwatson 325157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) { 326157986Sdwmalone match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid), 327157986Sdwmalone &(rule->mbr_object.mbo_fsid), 328157986Sdwmalone sizeof(rule->mbr_object.mbo_fsid)) == 0); 329157986Sdwmalone 330157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED) 331157986Sdwmalone match = !match; 332157986Sdwmalone 333157986Sdwmalone if (!match) 334157986Sdwmalone return 0; 335157986Sdwmalone } 336157986Sdwmalone 337157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SUID) { 338157986Sdwmalone match = (vap->va_mode & VSUID); 339157986Sdwmalone 340157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SUID) 341157986Sdwmalone match = !match; 342157986Sdwmalone 343157986Sdwmalone if (!match) 344157986Sdwmalone return 0; 345157986Sdwmalone } 346157986Sdwmalone 347157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SGID) { 348157986Sdwmalone match = (vap->va_mode & VSGID); 349157986Sdwmalone 350157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SGID) 351157986Sdwmalone match = !match; 352157986Sdwmalone 353157986Sdwmalone if (!match) 354157986Sdwmalone return 0; 355157986Sdwmalone } 356157986Sdwmalone 357157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) { 358157986Sdwmalone match = (vap->va_uid == cred->cr_uid || 359157986Sdwmalone vap->va_uid == cred->cr_ruid || 360157986Sdwmalone vap->va_uid == cred->cr_svuid); 361157986Sdwmalone 362157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT) 363157986Sdwmalone match = !match; 364157986Sdwmalone 365157986Sdwmalone if (!match) 366157986Sdwmalone return 0; 367157986Sdwmalone } 368157986Sdwmalone 369157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) { 370157986Sdwmalone match = (groupmember(vap->va_gid, cred) || 371157986Sdwmalone vap->va_gid == cred->cr_rgid || 372157986Sdwmalone vap->va_gid == cred->cr_svgid); 373157986Sdwmalone 374157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT) 375157986Sdwmalone match = !match; 376157986Sdwmalone 377157986Sdwmalone if (!match) 378157986Sdwmalone return 0; 379157986Sdwmalone } 380157986Sdwmalone 381157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) { 382157986Sdwmalone switch (vap->va_type) { 383157986Sdwmalone case VREG: 384157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_REG); 385157986Sdwmalone break; 386157986Sdwmalone case VDIR: 387157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR); 388157986Sdwmalone break; 389157986Sdwmalone case VBLK: 390157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK); 391157986Sdwmalone break; 392157986Sdwmalone case VCHR: 393157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR); 394157986Sdwmalone break; 395157986Sdwmalone case VLNK: 396157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK); 397157986Sdwmalone break; 398157986Sdwmalone case VSOCK: 399157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK); 400157986Sdwmalone break; 401157986Sdwmalone case VFIFO: 402157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO); 403157986Sdwmalone break; 404157986Sdwmalone default: 405157986Sdwmalone match = 0; 406157986Sdwmalone } 407157986Sdwmalone 408157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED) 409157986Sdwmalone match = !match; 410157986Sdwmalone 411157986Sdwmalone if (!match) 412157986Sdwmalone return 0; 413157986Sdwmalone } 414157986Sdwmalone 415101099Srwatson /* 416101099Srwatson * Is the access permitted? 417101099Srwatson */ 418101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 419134132Strhodes if (mac_bsdextended_logging) 420134132Strhodes log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 421134132Strhodes " on %d:%d failed. \n", cred->cr_ruid, 422157986Sdwmalone cred->cr_rgid, acc_mode, vap->va_uid, vap->va_gid); 423134132Strhodes return (EACCES); /* Matching rule denies access */ 424101099Srwatson } 425145412Strhodes 426134131Strhodes /* 427145412Strhodes * If the rule matched, permits access, and first match is enabled, 428145412Strhodes * return success. 429134131Strhodes */ 430134131Strhodes if (mac_bsdextended_firstmatch_enabled) 431134131Strhodes return (EJUSTRETURN); 432134131Strhodes else 433134131Strhodes return(0); 434101099Srwatson} 435101099Srwatson 436101099Srwatsonstatic int 437157986Sdwmalonemac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap, 438106212Srwatson int acc_mode) 439101099Srwatson{ 440101099Srwatson int error, i; 441101099Srwatson 442164033Srwatson /* 443164033Srwatson * XXXRW: More specific privilege selection needed? 444164033Srwatson */ 445132563Srwatson if (suser_cred(cred, 0) == 0) 446132563Srwatson return (0); 447132563Srwatson 448166843Srwatson /* 449166843Srwatson * Since we do not separately handle append, map append to write. 450166843Srwatson */ 451166843Srwatson if (acc_mode & MBI_APPEND) { 452166843Srwatson acc_mode &= ~MBI_APPEND; 453166843Srwatson acc_mode |= MBI_WRITE; 454166843Srwatson } 455166843Srwatson 456145412Strhodes mtx_lock(&mac_bsdextended_mtx); 457101099Srwatson for (i = 0; i < rule_slots; i++) { 458101099Srwatson if (rules[i] == NULL) 459101099Srwatson continue; 460101099Srwatson 461157986Sdwmalone error = mac_bsdextended_rulecheck(rules[i], cred, 462157986Sdwmalone vp, vap, acc_mode); 463134131Strhodes if (error == EJUSTRETURN) 464134131Strhodes break; 465145412Strhodes if (error) { 466145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 467101099Srwatson return (error); 468145412Strhodes } 469101099Srwatson } 470145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 471101099Srwatson return (0); 472101099Srwatson} 473101099Srwatson 474101099Srwatsonstatic int 475156300Sdwmalonemac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode) 476112575Srwatson{ 477156300Sdwmalone int error; 478112575Srwatson struct vattr vap; 479112575Srwatson 480112575Srwatson if (!mac_bsdextended_enabled) 481112575Srwatson return (0); 482112575Srwatson 483112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 484112575Srwatson if (error) 485112575Srwatson return (error); 486156300Sdwmalone 487157986Sdwmalone return (mac_bsdextended_check(cred, vp, &vap, acc_mode)); 488112575Srwatson} 489112575Srwatson 490112575Srwatsonstatic int 491168933Srwatsonmac_bsdextended_check_system_acct(struct ucred *cred, struct vnode *vp, 492168976Srwatson struct label *vplabel) 493168933Srwatson{ 494168933Srwatson 495168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 496168933Srwatson} 497168933Srwatson 498168933Srwatsonstatic int 499168933Srwatsonmac_bsdextended_check_system_auditctl(struct ucred *cred, struct vnode *vp, 500168976Srwatson struct label *vplabel) 501168933Srwatson{ 502168933Srwatson 503168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 504168933Srwatson} 505168933Srwatson 506168933Srwatsonstatic int 507168933Srwatsonmac_bsdextended_check_system_swapoff(struct ucred *cred, struct vnode *vp, 508168976Srwatson struct label *vplabel) 509168933Srwatson{ 510168933Srwatson 511168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 512168933Srwatson} 513168933Srwatson 514168933Srwatsonstatic int 515156300Sdwmalonemac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 516168976Srwatson struct label *vplabel) 517156300Sdwmalone{ 518156300Sdwmalone 519156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 520156300Sdwmalone} 521156300Sdwmalone 522156300Sdwmalonestatic int 523101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 524168976Srwatson struct label *vplabel, int acc_mode) 525101099Srwatson{ 526101099Srwatson 527156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 528101099Srwatson} 529101099Srwatson 530101099Srwatsonstatic int 531101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 532168976Srwatson struct label *dvplabel) 533101099Srwatson{ 534101099Srwatson 535156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 536101099Srwatson} 537101099Srwatson 538101099Srwatsonstatic int 539101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 540168976Srwatson struct label *dvplabel) 541101099Srwatson{ 542101099Srwatson 543156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 544101099Srwatson} 545101099Srwatson 546101099Srwatsonstatic int 547101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 548168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 549101099Srwatson{ 550101099Srwatson 551156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE)); 552101099Srwatson} 553101099Srwatson 554101099Srwatsonstatic int 555101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 556168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 557101099Srwatson struct componentname *cnp) 558101099Srwatson{ 559101099Srwatson int error; 560101099Srwatson 561156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 562101099Srwatson if (error) 563101099Srwatson return (error); 564101099Srwatson 565156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 566101099Srwatson} 567101099Srwatson 568101099Srwatsonstatic int 569101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 570168976Srwatson struct label *vplabel, acl_type_t type) 571101099Srwatson{ 572101099Srwatson 573156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 574101099Srwatson} 575101099Srwatson 576101099Srwatsonstatic int 577168976Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, 578168976Srwatson struct vnode *vp, struct label *vplabel, int attrnamespace, 579168976Srwatson const char *name) 580119202Srwatson{ 581119202Srwatson 582156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 583119202Srwatson} 584119202Srwatson 585119202Srwatsonstatic int 586101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 587168976Srwatson struct label *vplabel, struct image_params *imgp, 588106648Srwatson struct label *execlabel) 589101099Srwatson{ 590101099Srwatson 591156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC)); 592101099Srwatson} 593101099Srwatson 594101099Srwatsonstatic int 595101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 596168976Srwatson struct label *vplabel, acl_type_t type) 597101099Srwatson{ 598101099Srwatson 599156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_STAT)); 600101099Srwatson} 601101099Srwatson 602101099Srwatsonstatic int 603101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 604168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 605168976Srwatson struct uio *uio) 606101099Srwatson{ 607101099Srwatson 608156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 609101099Srwatson} 610101099Srwatson 611101099Srwatsonstatic int 612104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 613168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *label, 614104530Srwatson struct componentname *cnp) 615104530Srwatson{ 616104530Srwatson int error; 617104530Srwatson 618156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 619104530Srwatson if (error) 620104530Srwatson return (error); 621104530Srwatson 622156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 623104530Srwatson if (error) 624104530Srwatson return (error); 625104530Srwatson return (0); 626104530Srwatson} 627104530Srwatson 628104530Srwatsonstatic int 629119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 630168976Srwatson struct label *vplabel, int attrnamespace) 631119202Srwatson{ 632119202Srwatson 633156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 634119202Srwatson} 635119202Srwatson 636119202Srwatsonstatic int 637101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 638168976Srwatson struct label *dvplabel, struct componentname *cnp) 639101099Srwatson{ 640117247Srwatson 641156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 642101099Srwatson} 643101099Srwatson 644101099Srwatsonstatic int 645101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 646168976Srwatson struct label *vplabel, int acc_mode) 647101099Srwatson{ 648101099Srwatson 649156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 650101099Srwatson} 651101099Srwatson 652101099Srwatsonstatic int 653101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 654168976Srwatson struct label *dvplabel) 655101099Srwatson{ 656101099Srwatson 657156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_READ)); 658101099Srwatson} 659101099Srwatson 660101099Srwatsonstatic int 661101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 662168976Srwatson struct label *vplabel) 663101099Srwatson{ 664101099Srwatson 665156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 666101099Srwatson} 667101099Srwatson 668101099Srwatsonstatic int 669101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 670168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 671101099Srwatson struct componentname *cnp) 672101099Srwatson{ 673101099Srwatson int error; 674101099Srwatson 675156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 676101099Srwatson if (error) 677101099Srwatson return (error); 678156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 679101099Srwatson 680101099Srwatson return (error); 681101099Srwatson} 682101099Srwatson 683101099Srwatsonstatic int 684101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 685168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 686168976Srwatson int samedir, struct componentname *cnp) 687101099Srwatson{ 688101099Srwatson int error; 689101099Srwatson 690156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 691101099Srwatson if (error) 692101099Srwatson return (error); 693101099Srwatson 694156300Sdwmalone if (vp != NULL) 695156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 696101099Srwatson 697101099Srwatson return (error); 698101099Srwatson} 699101099Srwatson 700101099Srwatsonstatic int 701101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 702168976Srwatson struct label *vplabel) 703101099Srwatson{ 704101099Srwatson 705156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 706101099Srwatson} 707101099Srwatson 708101099Srwatsonstatic int 709101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 710168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 711101099Srwatson{ 712101099Srwatson 713156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 714101099Srwatson} 715101099Srwatson 716101099Srwatsonstatic int 717101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 718168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 719168976Srwatson struct uio *uio) 720101099Srwatson{ 721101099Srwatson 722156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 723101099Srwatson} 724101099Srwatson 725101099Srwatsonstatic int 726101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 727168976Srwatson struct label *vplabel, u_long flags) 728101099Srwatson{ 729101099Srwatson 730156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 731101099Srwatson} 732101099Srwatson 733101099Srwatsonstatic int 734101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 735168976Srwatson struct label *vplabel, mode_t mode) 736101099Srwatson{ 737101099Srwatson 738156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 739101099Srwatson} 740101099Srwatson 741101099Srwatsonstatic int 742101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 743168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 744101099Srwatson{ 745101099Srwatson 746156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 747101099Srwatson} 748101099Srwatson 749101099Srwatsonstatic int 750101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 751168976Srwatson struct label *vplabel, struct timespec atime, struct timespec utime) 752101099Srwatson{ 753101099Srwatson 754156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 755101099Srwatson} 756101099Srwatson 757101099Srwatsonstatic int 758102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 759168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 760101099Srwatson{ 761101099Srwatson 762156300Sdwmalone return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT)); 763101099Srwatson} 764101099Srwatson 765106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 766101099Srwatson{ 767106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 768106217Srwatson .mpo_init = mac_bsdextended_init, 769168933Srwatson .mpo_check_system_acct = mac_bsdextended_check_system_acct, 770168933Srwatson .mpo_check_system_auditctl = mac_bsdextended_check_system_auditctl, 771168933Srwatson .mpo_check_system_swapoff = mac_bsdextended_check_system_swapoff, 772112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 773106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 774106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 775106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 776106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 777106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 778106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 779119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 780106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 781106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 782106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 783106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 784119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 785106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 786106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 787106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 788106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 789106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 790106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 791106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 792106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 793106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 794106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 795106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 796106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 797106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 798106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 799101099Srwatson}; 800101099Srwatson 801112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 802101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 803