ugidfw_vnode.c revision 170689
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 170689 2007-06-13 22:42:43Z 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> 54170689Srwatson#include <sys/priv.h> 55101099Srwatson#include <sys/systm.h> 56101099Srwatson#include <sys/vnode.h> 57101099Srwatson#include <sys/sysctl.h> 58134132Strhodes#include <sys/syslog.h> 59101099Srwatson 60165469Srwatson#include <security/mac/mac_policy.h> 61101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 62101099Srwatson 63145412Strhodesstatic struct mtx mac_bsdextended_mtx; 64145412Strhodes 65101099SrwatsonSYSCTL_DECL(_security_mac); 66101099Srwatson 67101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 68101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 69101099Srwatson 70101099Srwatsonstatic int mac_bsdextended_enabled = 1; 71101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 72101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 73101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 74101099Srwatson 75101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 76101099Srwatson 77101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 78101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 79101099Srwatsonstatic int rule_count = 0; 80101099Srwatsonstatic int rule_slots = 0; 81157986Sdwmalonestatic int rule_version = MB_VERSION; 82101099Srwatson 83101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 84101099Srwatson &rule_count, 0, "Number of defined rules\n"); 85101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 86101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 87157986SdwmaloneSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD, 88157986Sdwmalone &rule_version, 0, "Version number for API\n"); 89101099Srwatson 90134132Strhodes/* 91145412Strhodes * This is just used for logging purposes, eventually we would like 92134132Strhodes * to log much more then failed requests. 93134132Strhodes */ 94134132Strhodesstatic int mac_bsdextended_logging; 95134132StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 96134132Strhodes &mac_bsdextended_logging, 0, "Log failed authorization requests"); 97134132Strhodes 98134132Strhodes/* 99134131Strhodes * This tunable is here for compatibility. It will allow the user 100134131Strhodes * to switch between the new mode (first rule matches) and the old 101134131Strhodes * functionality (all rules match). 102134131Strhodes */ 103101099Srwatsonstatic int 104134131Strhodesmac_bsdextended_firstmatch_enabled; 105134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 106135039Strhodes CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 107134131Strhodes "Disable/enable match first rule functionality"); 108134131Strhodes 109134131Strhodesstatic int 110101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 111101099Srwatson{ 112101099Srwatson 113157986Sdwmalone if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 114101099Srwatson return (EINVAL); 115101099Srwatson 116157986Sdwmalone if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 117101099Srwatson return (EINVAL); 118101099Srwatson 119157986Sdwmalone if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 120157986Sdwmalone return (EINVAL); 121157986Sdwmalone 122157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 123157986Sdwmalone return (EINVAL); 124157986Sdwmalone 125157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) && 126157986Sdwmalone (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE) 127157986Sdwmalone return (EINVAL); 128157986Sdwmalone 129136739Srwatson if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 130101099Srwatson return (EINVAL); 131101099Srwatson 132101099Srwatson return (0); 133101099Srwatson} 134101099Srwatson 135101099Srwatsonstatic int 136101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 137101099Srwatson{ 138101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 139101099Srwatson u_int namelen; 140101099Srwatson int error, index, *name; 141101099Srwatson 142145412Strhodes error = 0; 143101099Srwatson name = (int *)arg1; 144101099Srwatson namelen = arg2; 145101099Srwatson 146101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 147101099Srwatson 148101099Srwatson if (namelen != 1) 149101099Srwatson return (EINVAL); 150101099Srwatson 151101099Srwatson index = name[0]; 152154386Scsjp if (index >= MAC_BSDEXTENDED_MAXRULES) 153101099Srwatson return (ENOENT); 154101099Srwatson 155145412Strhodes ruleptr = NULL; 156145412Strhodes if (req->newptr && req->newlen != 0) { 157145412Strhodes error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 158101099Srwatson if (error) 159101099Srwatson return (error); 160145412Strhodes MALLOC(ruleptr, struct mac_bsdextended_rule *, 161145412Strhodes sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); 162101099Srwatson } 163101099Srwatson 164145412Strhodes mtx_lock(&mac_bsdextended_mtx); 165145412Strhodes 166145412Strhodes if (req->oldptr) { 167145412Strhodes if (index < 0 || index > rule_slots + 1) { 168145412Strhodes error = ENOENT; 169145412Strhodes goto out; 170101099Srwatson } 171145412Strhodes if (rules[index] == NULL) { 172145412Strhodes error = ENOENT; 173145412Strhodes goto out; 174145412Strhodes } 175145412Strhodes temprule = *rules[index]; 176145412Strhodes } 177101099Srwatson 178145412Strhodes if (req->newptr && req->newlen == 0) { 179145412Strhodes /* printf("deletion\n"); */ 180145412Strhodes KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 181145412Strhodes ruleptr = rules[index]; 182145412Strhodes if (ruleptr == NULL) { 183145412Strhodes error = ENOENT; 184145412Strhodes goto out; 185145412Strhodes } 186145412Strhodes rule_count--; 187145412Strhodes rules[index] = NULL; 188145412Strhodes } else if (req->newptr) { 189101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 190101099Srwatson if (error) 191145412Strhodes goto out; 192101099Srwatson 193101099Srwatson if (rules[index] == NULL) { 194101099Srwatson /* printf("addition\n"); */ 195101099Srwatson *ruleptr = temprule; 196101099Srwatson rules[index] = ruleptr; 197145412Strhodes ruleptr = NULL; 198145412Strhodes if (index + 1 > rule_slots) 199145412Strhodes rule_slots = index + 1; 200101099Srwatson rule_count++; 201101099Srwatson } else { 202101099Srwatson /* printf("replacement\n"); */ 203101099Srwatson *rules[index] = temprule; 204101099Srwatson } 205101099Srwatson } 206101099Srwatson 207145412Strhodesout: 208145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 209145412Strhodes if (ruleptr != NULL) 210145412Strhodes FREE(ruleptr, M_MACBSDEXTENDED); 211148482Strhodes if (req->oldptr && error == 0) 212145412Strhodes error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 213145412Strhodes 214148482Strhodes return (error); 215101099Srwatson} 216101099Srwatson 217101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 218101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 219101099Srwatson 220101099Srwatsonstatic void 221101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 222101099Srwatson{ 223101099Srwatson 224101099Srwatson /* Initialize ruleset lock. */ 225145412Strhodes mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 226145412Strhodes 227101099Srwatson /* Register dynamic sysctl's for rules. */ 228101099Srwatson} 229101099Srwatson 230101099Srwatsonstatic void 231101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 232101099Srwatson{ 233101099Srwatson 234145412Strhodes /* Destroy ruleset lock. */ 235145412Strhodes mtx_destroy(&mac_bsdextended_mtx); 236145412Strhodes 237101099Srwatson /* Tear down sysctls. */ 238101099Srwatson} 239101099Srwatson 240101099Srwatsonstatic int 241101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 242157986Sdwmalone struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode) 243101099Srwatson{ 244101099Srwatson int match; 245157986Sdwmalone int i; 246101099Srwatson 247101099Srwatson /* 248101099Srwatson * Is there a subject match? 249101099Srwatson */ 250145412Strhodes mtx_assert(&mac_bsdextended_mtx, MA_OWNED); 251157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) { 252157986Sdwmalone match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max && 253157986Sdwmalone cred->cr_uid >= rule->mbr_subject.mbs_uid_min) || 254157986Sdwmalone (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max && 255157986Sdwmalone cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) || 256157986Sdwmalone (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max && 257157986Sdwmalone cred->cr_svuid >= rule->mbr_subject.mbs_uid_min)); 258101099Srwatson 259157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED) 260101099Srwatson match = !match; 261101099Srwatson 262101099Srwatson if (!match) 263101099Srwatson return (0); 264101099Srwatson } 265101099Srwatson 266157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) { 267157986Sdwmalone match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max && 268157986Sdwmalone cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) || 269157986Sdwmalone (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max && 270157986Sdwmalone cred->cr_svgid >= rule->mbr_subject.mbs_gid_min)); 271101099Srwatson 272157986Sdwmalone if (!match) { 273157986Sdwmalone for (i = 0; i < cred->cr_ngroups; i++) 274157986Sdwmalone if (cred->cr_groups[i] 275157986Sdwmalone <= rule->mbr_subject.mbs_gid_max && 276157986Sdwmalone cred->cr_groups[i] 277157986Sdwmalone >= rule->mbr_subject.mbs_gid_min) { 278157986Sdwmalone match = 1; 279157986Sdwmalone break; 280157986Sdwmalone } 281157986Sdwmalone } 282157986Sdwmalone 283157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED) 284101099Srwatson match = !match; 285101099Srwatson 286101099Srwatson if (!match) 287101099Srwatson return (0); 288101099Srwatson } 289101099Srwatson 290157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) { 291157986Sdwmalone match = (cred->cr_prison != NULL && 292157986Sdwmalone cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison); 293157986Sdwmalone 294157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED) 295157986Sdwmalone match = !match; 296157986Sdwmalone 297157986Sdwmalone if (!match) 298157986Sdwmalone return (0); 299157986Sdwmalone } 300157986Sdwmalone 301101099Srwatson /* 302101099Srwatson * Is there an object match? 303101099Srwatson */ 304157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) { 305157986Sdwmalone match = (vap->va_uid <= rule->mbr_object.mbo_uid_max && 306157986Sdwmalone vap->va_uid >= rule->mbr_object.mbo_uid_min); 307101099Srwatson 308157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED) 309101099Srwatson match = !match; 310101099Srwatson 311101099Srwatson if (!match) 312101099Srwatson return (0); 313101099Srwatson } 314101099Srwatson 315157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) { 316157986Sdwmalone match = (vap->va_gid <= rule->mbr_object.mbo_gid_max && 317157986Sdwmalone vap->va_gid >= rule->mbr_object.mbo_gid_min); 318101099Srwatson 319157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED) 320101099Srwatson match = !match; 321101099Srwatson 322101099Srwatson if (!match) 323101099Srwatson return (0); 324101099Srwatson } 325101099Srwatson 326157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) { 327157986Sdwmalone match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid), 328157986Sdwmalone &(rule->mbr_object.mbo_fsid), 329157986Sdwmalone sizeof(rule->mbr_object.mbo_fsid)) == 0); 330157986Sdwmalone 331157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED) 332157986Sdwmalone match = !match; 333157986Sdwmalone 334157986Sdwmalone if (!match) 335157986Sdwmalone return 0; 336157986Sdwmalone } 337157986Sdwmalone 338157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SUID) { 339157986Sdwmalone match = (vap->va_mode & VSUID); 340157986Sdwmalone 341157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SUID) 342157986Sdwmalone match = !match; 343157986Sdwmalone 344157986Sdwmalone if (!match) 345157986Sdwmalone return 0; 346157986Sdwmalone } 347157986Sdwmalone 348157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SGID) { 349157986Sdwmalone match = (vap->va_mode & VSGID); 350157986Sdwmalone 351157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SGID) 352157986Sdwmalone match = !match; 353157986Sdwmalone 354157986Sdwmalone if (!match) 355157986Sdwmalone return 0; 356157986Sdwmalone } 357157986Sdwmalone 358157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) { 359157986Sdwmalone match = (vap->va_uid == cred->cr_uid || 360157986Sdwmalone vap->va_uid == cred->cr_ruid || 361157986Sdwmalone vap->va_uid == cred->cr_svuid); 362157986Sdwmalone 363157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT) 364157986Sdwmalone match = !match; 365157986Sdwmalone 366157986Sdwmalone if (!match) 367157986Sdwmalone return 0; 368157986Sdwmalone } 369157986Sdwmalone 370157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) { 371157986Sdwmalone match = (groupmember(vap->va_gid, cred) || 372157986Sdwmalone vap->va_gid == cred->cr_rgid || 373157986Sdwmalone vap->va_gid == cred->cr_svgid); 374157986Sdwmalone 375157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT) 376157986Sdwmalone match = !match; 377157986Sdwmalone 378157986Sdwmalone if (!match) 379157986Sdwmalone return 0; 380157986Sdwmalone } 381157986Sdwmalone 382157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) { 383157986Sdwmalone switch (vap->va_type) { 384157986Sdwmalone case VREG: 385157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_REG); 386157986Sdwmalone break; 387157986Sdwmalone case VDIR: 388157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR); 389157986Sdwmalone break; 390157986Sdwmalone case VBLK: 391157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK); 392157986Sdwmalone break; 393157986Sdwmalone case VCHR: 394157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR); 395157986Sdwmalone break; 396157986Sdwmalone case VLNK: 397157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK); 398157986Sdwmalone break; 399157986Sdwmalone case VSOCK: 400157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK); 401157986Sdwmalone break; 402157986Sdwmalone case VFIFO: 403157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO); 404157986Sdwmalone break; 405157986Sdwmalone default: 406157986Sdwmalone match = 0; 407157986Sdwmalone } 408157986Sdwmalone 409157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED) 410157986Sdwmalone match = !match; 411157986Sdwmalone 412157986Sdwmalone if (!match) 413157986Sdwmalone return 0; 414157986Sdwmalone } 415157986Sdwmalone 416101099Srwatson /* 417101099Srwatson * Is the access permitted? 418101099Srwatson */ 419101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 420134132Strhodes if (mac_bsdextended_logging) 421134132Strhodes log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 422134132Strhodes " on %d:%d failed. \n", cred->cr_ruid, 423157986Sdwmalone cred->cr_rgid, acc_mode, vap->va_uid, vap->va_gid); 424134132Strhodes return (EACCES); /* Matching rule denies access */ 425101099Srwatson } 426145412Strhodes 427134131Strhodes /* 428145412Strhodes * If the rule matched, permits access, and first match is enabled, 429145412Strhodes * return success. 430134131Strhodes */ 431134131Strhodes if (mac_bsdextended_firstmatch_enabled) 432134131Strhodes return (EJUSTRETURN); 433134131Strhodes else 434134131Strhodes return(0); 435101099Srwatson} 436101099Srwatson 437101099Srwatsonstatic int 438157986Sdwmalonemac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap, 439106212Srwatson int acc_mode) 440101099Srwatson{ 441101099Srwatson int error, i; 442101099Srwatson 443164033Srwatson /* 444164033Srwatson * XXXRW: More specific privilege selection needed? 445164033Srwatson */ 446132563Srwatson if (suser_cred(cred, 0) == 0) 447132563Srwatson return (0); 448132563Srwatson 449166843Srwatson /* 450166843Srwatson * Since we do not separately handle append, map append to write. 451166843Srwatson */ 452166843Srwatson if (acc_mode & MBI_APPEND) { 453166843Srwatson acc_mode &= ~MBI_APPEND; 454166843Srwatson acc_mode |= MBI_WRITE; 455166843Srwatson } 456166843Srwatson 457145412Strhodes mtx_lock(&mac_bsdextended_mtx); 458101099Srwatson for (i = 0; i < rule_slots; i++) { 459101099Srwatson if (rules[i] == NULL) 460101099Srwatson continue; 461101099Srwatson 462157986Sdwmalone error = mac_bsdextended_rulecheck(rules[i], cred, 463157986Sdwmalone vp, vap, acc_mode); 464134131Strhodes if (error == EJUSTRETURN) 465134131Strhodes break; 466145412Strhodes if (error) { 467145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 468101099Srwatson return (error); 469145412Strhodes } 470101099Srwatson } 471145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 472101099Srwatson return (0); 473101099Srwatson} 474101099Srwatson 475101099Srwatsonstatic int 476156300Sdwmalonemac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode) 477112575Srwatson{ 478156300Sdwmalone int error; 479112575Srwatson struct vattr vap; 480112575Srwatson 481112575Srwatson if (!mac_bsdextended_enabled) 482112575Srwatson return (0); 483112575Srwatson 484112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 485112575Srwatson if (error) 486112575Srwatson return (error); 487156300Sdwmalone 488157986Sdwmalone return (mac_bsdextended_check(cred, vp, &vap, acc_mode)); 489112575Srwatson} 490112575Srwatson 491112575Srwatsonstatic int 492168933Srwatsonmac_bsdextended_check_system_acct(struct ucred *cred, struct vnode *vp, 493168976Srwatson struct label *vplabel) 494168933Srwatson{ 495168933Srwatson 496168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 497168933Srwatson} 498168933Srwatson 499168933Srwatsonstatic int 500168933Srwatsonmac_bsdextended_check_system_auditctl(struct ucred *cred, struct vnode *vp, 501168976Srwatson struct label *vplabel) 502168933Srwatson{ 503168933Srwatson 504168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 505168933Srwatson} 506168933Srwatson 507168933Srwatsonstatic int 508168933Srwatsonmac_bsdextended_check_system_swapoff(struct ucred *cred, struct vnode *vp, 509168976Srwatson struct label *vplabel) 510168933Srwatson{ 511168933Srwatson 512168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 513168933Srwatson} 514168933Srwatson 515168933Srwatsonstatic int 516156300Sdwmalonemac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 517168976Srwatson struct label *vplabel) 518156300Sdwmalone{ 519156300Sdwmalone 520156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 521156300Sdwmalone} 522156300Sdwmalone 523156300Sdwmalonestatic int 524101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 525168976Srwatson struct label *vplabel, int acc_mode) 526101099Srwatson{ 527101099Srwatson 528156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 529101099Srwatson} 530101099Srwatson 531101099Srwatsonstatic int 532101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 533168976Srwatson struct label *dvplabel) 534101099Srwatson{ 535101099Srwatson 536156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 537101099Srwatson} 538101099Srwatson 539101099Srwatsonstatic int 540101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 541168976Srwatson struct label *dvplabel) 542101099Srwatson{ 543101099Srwatson 544156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 545101099Srwatson} 546101099Srwatson 547101099Srwatsonstatic int 548101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 549168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 550101099Srwatson{ 551101099Srwatson 552156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE)); 553101099Srwatson} 554101099Srwatson 555101099Srwatsonstatic int 556101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 557168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 558101099Srwatson struct componentname *cnp) 559101099Srwatson{ 560101099Srwatson int error; 561101099Srwatson 562156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 563101099Srwatson if (error) 564101099Srwatson return (error); 565101099Srwatson 566156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 567101099Srwatson} 568101099Srwatson 569101099Srwatsonstatic int 570101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 571168976Srwatson struct label *vplabel, acl_type_t type) 572101099Srwatson{ 573101099Srwatson 574156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 575101099Srwatson} 576101099Srwatson 577101099Srwatsonstatic int 578168976Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, 579168976Srwatson struct vnode *vp, struct label *vplabel, int attrnamespace, 580168976Srwatson const char *name) 581119202Srwatson{ 582119202Srwatson 583156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 584119202Srwatson} 585119202Srwatson 586119202Srwatsonstatic int 587101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 588168976Srwatson struct label *vplabel, struct image_params *imgp, 589106648Srwatson struct label *execlabel) 590101099Srwatson{ 591101099Srwatson 592156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC)); 593101099Srwatson} 594101099Srwatson 595101099Srwatsonstatic int 596101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 597168976Srwatson struct label *vplabel, acl_type_t type) 598101099Srwatson{ 599101099Srwatson 600156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_STAT)); 601101099Srwatson} 602101099Srwatson 603101099Srwatsonstatic int 604101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 605168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 606168976Srwatson struct uio *uio) 607101099Srwatson{ 608101099Srwatson 609156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 610101099Srwatson} 611101099Srwatson 612101099Srwatsonstatic int 613104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 614168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *label, 615104530Srwatson struct componentname *cnp) 616104530Srwatson{ 617104530Srwatson int error; 618104530Srwatson 619156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 620104530Srwatson if (error) 621104530Srwatson return (error); 622104530Srwatson 623156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 624104530Srwatson if (error) 625104530Srwatson return (error); 626104530Srwatson return (0); 627104530Srwatson} 628104530Srwatson 629104530Srwatsonstatic int 630119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 631168976Srwatson struct label *vplabel, int attrnamespace) 632119202Srwatson{ 633119202Srwatson 634156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 635119202Srwatson} 636119202Srwatson 637119202Srwatsonstatic int 638101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 639168976Srwatson struct label *dvplabel, struct componentname *cnp) 640101099Srwatson{ 641117247Srwatson 642156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 643101099Srwatson} 644101099Srwatson 645101099Srwatsonstatic int 646101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 647168976Srwatson struct label *vplabel, int acc_mode) 648101099Srwatson{ 649101099Srwatson 650156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 651101099Srwatson} 652101099Srwatson 653101099Srwatsonstatic int 654101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 655168976Srwatson struct label *dvplabel) 656101099Srwatson{ 657101099Srwatson 658156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_READ)); 659101099Srwatson} 660101099Srwatson 661101099Srwatsonstatic int 662101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 663168976Srwatson struct label *vplabel) 664101099Srwatson{ 665101099Srwatson 666156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 667101099Srwatson} 668101099Srwatson 669101099Srwatsonstatic int 670101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 671168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 672101099Srwatson struct componentname *cnp) 673101099Srwatson{ 674101099Srwatson int error; 675101099Srwatson 676156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 677101099Srwatson if (error) 678101099Srwatson return (error); 679156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 680101099Srwatson 681101099Srwatson return (error); 682101099Srwatson} 683101099Srwatson 684101099Srwatsonstatic int 685101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 686168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 687168976Srwatson int samedir, struct componentname *cnp) 688101099Srwatson{ 689101099Srwatson int error; 690101099Srwatson 691156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 692101099Srwatson if (error) 693101099Srwatson return (error); 694101099Srwatson 695156300Sdwmalone if (vp != NULL) 696156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 697101099Srwatson 698101099Srwatson return (error); 699101099Srwatson} 700101099Srwatson 701101099Srwatsonstatic int 702101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 703168976Srwatson struct label *vplabel) 704101099Srwatson{ 705101099Srwatson 706156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 707101099Srwatson} 708101099Srwatson 709101099Srwatsonstatic int 710101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 711168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 712101099Srwatson{ 713101099Srwatson 714156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 715101099Srwatson} 716101099Srwatson 717101099Srwatsonstatic int 718101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 719168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 720168976Srwatson struct uio *uio) 721101099Srwatson{ 722101099Srwatson 723156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 724101099Srwatson} 725101099Srwatson 726101099Srwatsonstatic int 727101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 728168976Srwatson struct label *vplabel, u_long flags) 729101099Srwatson{ 730101099Srwatson 731156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 732101099Srwatson} 733101099Srwatson 734101099Srwatsonstatic int 735101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 736168976Srwatson struct label *vplabel, mode_t mode) 737101099Srwatson{ 738101099Srwatson 739156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 740101099Srwatson} 741101099Srwatson 742101099Srwatsonstatic int 743101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 744168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 745101099Srwatson{ 746101099Srwatson 747156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 748101099Srwatson} 749101099Srwatson 750101099Srwatsonstatic int 751101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 752168976Srwatson struct label *vplabel, struct timespec atime, struct timespec utime) 753101099Srwatson{ 754101099Srwatson 755156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 756101099Srwatson} 757101099Srwatson 758101099Srwatsonstatic int 759102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 760168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 761101099Srwatson{ 762101099Srwatson 763156300Sdwmalone return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT)); 764101099Srwatson} 765101099Srwatson 766106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 767101099Srwatson{ 768106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 769106217Srwatson .mpo_init = mac_bsdextended_init, 770168933Srwatson .mpo_check_system_acct = mac_bsdextended_check_system_acct, 771168933Srwatson .mpo_check_system_auditctl = mac_bsdextended_check_system_auditctl, 772168933Srwatson .mpo_check_system_swapoff = mac_bsdextended_check_system_swapoff, 773112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 774106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 775106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 776106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 777106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 778106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 779106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 780119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 781106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 782106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 783106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 784106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 785119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 786106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 787106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 788106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 789106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 790106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 791106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 792106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 793106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 794106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 795106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 796106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 797106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 798106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 799106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 800101099Srwatson}; 801101099Srwatson 802112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 803101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 804