ugidfw_system.c revision 172107
1101099Srwatson/*- 2166905Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3145412Strhodes * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 4171253Srwatson * Copyright (c) 2005 Tom Rhodes 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 172107 2007-09-10 00:00:18Z rwatson $ 37101099Srwatson */ 38136774Srwatson 39101099Srwatson/* 40101099Srwatson * Developed by the TrustedBSD Project. 41171253Srwatson * 42171253Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose mandatory 43171253Srwatson * firewall-like rules regarding users and file system objects. 44101099Srwatson */ 45101099Srwatson 46101099Srwatson#include <sys/param.h> 47101099Srwatson#include <sys/acl.h> 48101099Srwatson#include <sys/kernel.h> 49157986Sdwmalone#include <sys/jail.h> 50145412Strhodes#include <sys/lock.h> 51101099Srwatson#include <sys/malloc.h> 52166905Srwatson#include <sys/module.h> 53101099Srwatson#include <sys/mount.h> 54145412Strhodes#include <sys/mutex.h> 55170689Srwatson#include <sys/priv.h> 56101099Srwatson#include <sys/systm.h> 57101099Srwatson#include <sys/vnode.h> 58101099Srwatson#include <sys/sysctl.h> 59134132Strhodes#include <sys/syslog.h> 60101099Srwatson 61165469Srwatson#include <security/mac/mac_policy.h> 62101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 63101099Srwatson 64145412Strhodesstatic struct mtx mac_bsdextended_mtx; 65145412Strhodes 66101099SrwatsonSYSCTL_DECL(_security_mac); 67101099Srwatson 68101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 69101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 70101099Srwatson 71101099Srwatsonstatic int mac_bsdextended_enabled = 1; 72101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 73101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 74101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 75101099Srwatson 76101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 77101099Srwatson 78101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 79101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 80101099Srwatsonstatic int rule_count = 0; 81101099Srwatsonstatic int rule_slots = 0; 82157986Sdwmalonestatic int rule_version = MB_VERSION; 83101099Srwatson 84101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 85101099Srwatson &rule_count, 0, "Number of defined rules\n"); 86101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 87101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 88157986SdwmaloneSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD, 89157986Sdwmalone &rule_version, 0, "Version number for API\n"); 90101099Srwatson 91134132Strhodes/* 92171253Srwatson * This is just used for logging purposes, eventually we would like to log 93171253Srwatson * much more then failed requests. 94134132Strhodes */ 95134132Strhodesstatic int mac_bsdextended_logging; 96134132StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 97134132Strhodes &mac_bsdextended_logging, 0, "Log failed authorization requests"); 98134132Strhodes 99134132Strhodes/* 100171253Srwatson * This tunable is here for compatibility. It will allow the user to switch 101171253Srwatson * between the new mode (first rule matches) and the old functionality (all 102171253Srwatson * rules match). 103134131Strhodes */ 104101099Srwatsonstatic int 105134131Strhodesmac_bsdextended_firstmatch_enabled; 106134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 107171253Srwatson CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 108171253Srwatson "Disable/enable match first rule functionality"); 109134131Strhodes 110134131Strhodesstatic int 111101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 112101099Srwatson{ 113101099Srwatson 114157986Sdwmalone if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 115101099Srwatson return (EINVAL); 116157986Sdwmalone if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 117101099Srwatson return (EINVAL); 118157986Sdwmalone if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 119157986Sdwmalone return (EINVAL); 120157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 121157986Sdwmalone return (EINVAL); 122157986Sdwmalone if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) && 123157986Sdwmalone (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE) 124157986Sdwmalone return (EINVAL); 125136739Srwatson if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 126101099Srwatson return (EINVAL); 127101099Srwatson return (0); 128101099Srwatson} 129101099Srwatson 130101099Srwatsonstatic int 131101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 132101099Srwatson{ 133101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 134101099Srwatson u_int namelen; 135101099Srwatson int error, index, *name; 136101099Srwatson 137145412Strhodes error = 0; 138101099Srwatson name = (int *)arg1; 139101099Srwatson namelen = arg2; 140101099Srwatson if (namelen != 1) 141101099Srwatson return (EINVAL); 142101099Srwatson index = name[0]; 143154386Scsjp if (index >= MAC_BSDEXTENDED_MAXRULES) 144101099Srwatson return (ENOENT); 145101099Srwatson 146145412Strhodes ruleptr = NULL; 147145412Strhodes if (req->newptr && req->newlen != 0) { 148145412Strhodes error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 149101099Srwatson if (error) 150101099Srwatson return (error); 151145412Strhodes MALLOC(ruleptr, struct mac_bsdextended_rule *, 152145412Strhodes sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); 153101099Srwatson } 154101099Srwatson 155145412Strhodes mtx_lock(&mac_bsdextended_mtx); 156145412Strhodes if (req->oldptr) { 157145412Strhodes if (index < 0 || index > rule_slots + 1) { 158145412Strhodes error = ENOENT; 159145412Strhodes goto out; 160101099Srwatson } 161145412Strhodes if (rules[index] == NULL) { 162145412Strhodes error = ENOENT; 163145412Strhodes goto out; 164145412Strhodes } 165145412Strhodes temprule = *rules[index]; 166145412Strhodes } 167145412Strhodes if (req->newptr && req->newlen == 0) { 168145412Strhodes KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 169145412Strhodes ruleptr = rules[index]; 170145412Strhodes if (ruleptr == NULL) { 171145412Strhodes error = ENOENT; 172145412Strhodes goto out; 173145412Strhodes } 174145412Strhodes rule_count--; 175145412Strhodes rules[index] = NULL; 176145412Strhodes } else if (req->newptr) { 177101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 178101099Srwatson if (error) 179145412Strhodes goto out; 180101099Srwatson if (rules[index] == NULL) { 181101099Srwatson *ruleptr = temprule; 182101099Srwatson rules[index] = ruleptr; 183145412Strhodes ruleptr = NULL; 184145412Strhodes if (index + 1 > rule_slots) 185145412Strhodes rule_slots = index + 1; 186101099Srwatson rule_count++; 187171253Srwatson } else 188101099Srwatson *rules[index] = temprule; 189101099Srwatson } 190145412Strhodesout: 191145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 192145412Strhodes if (ruleptr != NULL) 193145412Strhodes FREE(ruleptr, M_MACBSDEXTENDED); 194148482Strhodes if (req->oldptr && error == 0) 195145412Strhodes error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 196148482Strhodes return (error); 197101099Srwatson} 198101099Srwatson 199171253SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, CTLFLAG_RW, 200171253Srwatson sysctl_rule, "BSD extended MAC rules"); 201101099Srwatson 202101099Srwatsonstatic void 203101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 204101099Srwatson{ 205101099Srwatson 206145412Strhodes mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 207101099Srwatson} 208101099Srwatson 209101099Srwatsonstatic void 210101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 211101099Srwatson{ 212101099Srwatson 213145412Strhodes mtx_destroy(&mac_bsdextended_mtx); 214101099Srwatson} 215101099Srwatson 216101099Srwatsonstatic int 217101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 218157986Sdwmalone struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode) 219101099Srwatson{ 220101099Srwatson int match; 221157986Sdwmalone int i; 222101099Srwatson 223101099Srwatson /* 224101099Srwatson * Is there a subject match? 225101099Srwatson */ 226145412Strhodes mtx_assert(&mac_bsdextended_mtx, MA_OWNED); 227157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) { 228157986Sdwmalone match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max && 229157986Sdwmalone cred->cr_uid >= rule->mbr_subject.mbs_uid_min) || 230157986Sdwmalone (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max && 231157986Sdwmalone cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) || 232157986Sdwmalone (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max && 233157986Sdwmalone cred->cr_svuid >= rule->mbr_subject.mbs_uid_min)); 234157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED) 235101099Srwatson match = !match; 236101099Srwatson if (!match) 237101099Srwatson return (0); 238101099Srwatson } 239101099Srwatson 240157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) { 241157986Sdwmalone match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max && 242157986Sdwmalone cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) || 243157986Sdwmalone (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max && 244157986Sdwmalone cred->cr_svgid >= rule->mbr_subject.mbs_gid_min)); 245157986Sdwmalone if (!match) { 246171253Srwatson for (i = 0; i < cred->cr_ngroups; i++) { 247157986Sdwmalone if (cred->cr_groups[i] 248157986Sdwmalone <= rule->mbr_subject.mbs_gid_max && 249157986Sdwmalone cred->cr_groups[i] 250157986Sdwmalone >= rule->mbr_subject.mbs_gid_min) { 251157986Sdwmalone match = 1; 252157986Sdwmalone break; 253157986Sdwmalone } 254171253Srwatson } 255157986Sdwmalone } 256157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED) 257101099Srwatson match = !match; 258101099Srwatson if (!match) 259101099Srwatson return (0); 260101099Srwatson } 261101099Srwatson 262157986Sdwmalone if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) { 263157986Sdwmalone match = (cred->cr_prison != NULL && 264157986Sdwmalone cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison); 265157986Sdwmalone if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED) 266157986Sdwmalone match = !match; 267157986Sdwmalone if (!match) 268157986Sdwmalone return (0); 269157986Sdwmalone } 270157986Sdwmalone 271101099Srwatson /* 272101099Srwatson * Is there an object match? 273101099Srwatson */ 274157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) { 275157986Sdwmalone match = (vap->va_uid <= rule->mbr_object.mbo_uid_max && 276157986Sdwmalone vap->va_uid >= rule->mbr_object.mbo_uid_min); 277157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED) 278101099Srwatson match = !match; 279101099Srwatson if (!match) 280101099Srwatson return (0); 281101099Srwatson } 282101099Srwatson 283157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) { 284157986Sdwmalone match = (vap->va_gid <= rule->mbr_object.mbo_gid_max && 285157986Sdwmalone vap->va_gid >= rule->mbr_object.mbo_gid_min); 286157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED) 287101099Srwatson match = !match; 288101099Srwatson if (!match) 289101099Srwatson return (0); 290101099Srwatson } 291101099Srwatson 292157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) { 293157986Sdwmalone match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid), 294157986Sdwmalone &(rule->mbr_object.mbo_fsid), 295157986Sdwmalone sizeof(rule->mbr_object.mbo_fsid)) == 0); 296157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED) 297157986Sdwmalone match = !match; 298157986Sdwmalone if (!match) 299171253Srwatson return (0); 300157986Sdwmalone } 301157986Sdwmalone 302157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SUID) { 303157986Sdwmalone match = (vap->va_mode & VSUID); 304157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SUID) 305157986Sdwmalone match = !match; 306157986Sdwmalone if (!match) 307171253Srwatson return (0); 308157986Sdwmalone } 309157986Sdwmalone 310157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_SGID) { 311157986Sdwmalone match = (vap->va_mode & VSGID); 312157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_SGID) 313157986Sdwmalone match = !match; 314157986Sdwmalone if (!match) 315171253Srwatson return (0); 316157986Sdwmalone } 317157986Sdwmalone 318157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) { 319157986Sdwmalone match = (vap->va_uid == cred->cr_uid || 320157986Sdwmalone vap->va_uid == cred->cr_ruid || 321157986Sdwmalone vap->va_uid == cred->cr_svuid); 322157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT) 323157986Sdwmalone match = !match; 324157986Sdwmalone if (!match) 325171253Srwatson return (0); 326157986Sdwmalone } 327157986Sdwmalone 328157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) { 329157986Sdwmalone match = (groupmember(vap->va_gid, cred) || 330157986Sdwmalone vap->va_gid == cred->cr_rgid || 331157986Sdwmalone vap->va_gid == cred->cr_svgid); 332157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT) 333157986Sdwmalone match = !match; 334157986Sdwmalone if (!match) 335171253Srwatson return (0); 336157986Sdwmalone } 337157986Sdwmalone 338157986Sdwmalone if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) { 339157986Sdwmalone switch (vap->va_type) { 340157986Sdwmalone case VREG: 341157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_REG); 342157986Sdwmalone break; 343157986Sdwmalone case VDIR: 344157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR); 345157986Sdwmalone break; 346157986Sdwmalone case VBLK: 347157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK); 348157986Sdwmalone break; 349157986Sdwmalone case VCHR: 350157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR); 351157986Sdwmalone break; 352157986Sdwmalone case VLNK: 353157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK); 354157986Sdwmalone break; 355157986Sdwmalone case VSOCK: 356157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK); 357157986Sdwmalone break; 358157986Sdwmalone case VFIFO: 359157986Sdwmalone match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO); 360157986Sdwmalone break; 361157986Sdwmalone default: 362157986Sdwmalone match = 0; 363157986Sdwmalone } 364157986Sdwmalone if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED) 365157986Sdwmalone match = !match; 366157986Sdwmalone if (!match) 367171253Srwatson return (0); 368157986Sdwmalone } 369157986Sdwmalone 370101099Srwatson /* 371101099Srwatson * Is the access permitted? 372101099Srwatson */ 373101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 374134132Strhodes if (mac_bsdextended_logging) 375134132Strhodes log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 376134132Strhodes " on %d:%d failed. \n", cred->cr_ruid, 377171253Srwatson cred->cr_rgid, acc_mode, vap->va_uid, 378171253Srwatson vap->va_gid); 379171253Srwatson return (EACCES); 380101099Srwatson } 381145412Strhodes 382134131Strhodes /* 383145412Strhodes * If the rule matched, permits access, and first match is enabled, 384145412Strhodes * return success. 385134131Strhodes */ 386134131Strhodes if (mac_bsdextended_firstmatch_enabled) 387134131Strhodes return (EJUSTRETURN); 388134131Strhodes else 389171253Srwatson return (0); 390101099Srwatson} 391101099Srwatson 392101099Srwatsonstatic int 393157986Sdwmalonemac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap, 394106212Srwatson int acc_mode) 395101099Srwatson{ 396101099Srwatson int error, i; 397101099Srwatson 398164033Srwatson /* 399171253Srwatson * XXXRW: More specific privilege selection needed. 400164033Srwatson */ 401132563Srwatson if (suser_cred(cred, 0) == 0) 402132563Srwatson return (0); 403132563Srwatson 404166843Srwatson /* 405166843Srwatson * Since we do not separately handle append, map append to write. 406166843Srwatson */ 407166843Srwatson if (acc_mode & MBI_APPEND) { 408166843Srwatson acc_mode &= ~MBI_APPEND; 409166843Srwatson acc_mode |= MBI_WRITE; 410166843Srwatson } 411145412Strhodes mtx_lock(&mac_bsdextended_mtx); 412101099Srwatson for (i = 0; i < rule_slots; i++) { 413101099Srwatson if (rules[i] == NULL) 414101099Srwatson continue; 415157986Sdwmalone error = mac_bsdextended_rulecheck(rules[i], cred, 416157986Sdwmalone vp, vap, acc_mode); 417134131Strhodes if (error == EJUSTRETURN) 418134131Strhodes break; 419145412Strhodes if (error) { 420145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 421101099Srwatson return (error); 422145412Strhodes } 423101099Srwatson } 424145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 425101099Srwatson return (0); 426101099Srwatson} 427101099Srwatson 428101099Srwatsonstatic int 429156300Sdwmalonemac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode) 430112575Srwatson{ 431156300Sdwmalone int error; 432112575Srwatson struct vattr vap; 433112575Srwatson 434112575Srwatson if (!mac_bsdextended_enabled) 435112575Srwatson return (0); 436112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 437112575Srwatson if (error) 438112575Srwatson return (error); 439157986Sdwmalone return (mac_bsdextended_check(cred, vp, &vap, acc_mode)); 440112575Srwatson} 441112575Srwatson 442112575Srwatsonstatic int 443168933Srwatsonmac_bsdextended_check_system_acct(struct ucred *cred, struct vnode *vp, 444168976Srwatson struct label *vplabel) 445168933Srwatson{ 446168933Srwatson 447168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 448168933Srwatson} 449168933Srwatson 450168933Srwatsonstatic int 451168933Srwatsonmac_bsdextended_check_system_auditctl(struct ucred *cred, struct vnode *vp, 452168976Srwatson struct label *vplabel) 453168933Srwatson{ 454168933Srwatson 455168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 456168933Srwatson} 457168933Srwatson 458168933Srwatsonstatic int 459168933Srwatsonmac_bsdextended_check_system_swapoff(struct ucred *cred, struct vnode *vp, 460168976Srwatson struct label *vplabel) 461168933Srwatson{ 462168933Srwatson 463168933Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 464168933Srwatson} 465168933Srwatson 466168933Srwatsonstatic int 467156300Sdwmalonemac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 468168976Srwatson struct label *vplabel) 469156300Sdwmalone{ 470156300Sdwmalone 471156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 472156300Sdwmalone} 473156300Sdwmalone 474156300Sdwmalonestatic int 475101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 476168976Srwatson struct label *vplabel, int acc_mode) 477101099Srwatson{ 478101099Srwatson 479156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 480101099Srwatson} 481101099Srwatson 482101099Srwatsonstatic int 483101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 484168976Srwatson struct label *dvplabel) 485101099Srwatson{ 486101099Srwatson 487156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 488101099Srwatson} 489101099Srwatson 490101099Srwatsonstatic int 491101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 492168976Srwatson struct label *dvplabel) 493101099Srwatson{ 494101099Srwatson 495156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 496101099Srwatson} 497101099Srwatson 498101099Srwatsonstatic int 499101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 500168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 501101099Srwatson{ 502101099Srwatson 503156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE)); 504101099Srwatson} 505101099Srwatson 506101099Srwatsonstatic int 507101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 508168976Srwatson struct label *vplabel, acl_type_t type) 509101099Srwatson{ 510101099Srwatson 511156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 512101099Srwatson} 513101099Srwatson 514101099Srwatsonstatic int 515168976Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, 516168976Srwatson struct vnode *vp, struct label *vplabel, int attrnamespace, 517168976Srwatson const char *name) 518119202Srwatson{ 519119202Srwatson 520156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 521119202Srwatson} 522119202Srwatson 523119202Srwatsonstatic int 524101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 525168976Srwatson struct label *vplabel, struct image_params *imgp, 526106648Srwatson struct label *execlabel) 527101099Srwatson{ 528101099Srwatson 529156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC)); 530101099Srwatson} 531101099Srwatson 532101099Srwatsonstatic int 533101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 534168976Srwatson struct label *vplabel, acl_type_t type) 535101099Srwatson{ 536101099Srwatson 537156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_STAT)); 538101099Srwatson} 539101099Srwatson 540101099Srwatsonstatic int 541101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 542168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 543168976Srwatson struct uio *uio) 544101099Srwatson{ 545101099Srwatson 546156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 547101099Srwatson} 548101099Srwatson 549101099Srwatsonstatic int 550104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 551168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *label, 552104530Srwatson struct componentname *cnp) 553104530Srwatson{ 554104530Srwatson int error; 555104530Srwatson 556156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 557104530Srwatson if (error) 558104530Srwatson return (error); 559156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 560104530Srwatson if (error) 561104530Srwatson return (error); 562104530Srwatson return (0); 563104530Srwatson} 564104530Srwatson 565104530Srwatsonstatic int 566119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 567168976Srwatson struct label *vplabel, int attrnamespace) 568119202Srwatson{ 569119202Srwatson 570156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 571119202Srwatson} 572119202Srwatson 573119202Srwatsonstatic int 574101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 575168976Srwatson struct label *dvplabel, struct componentname *cnp) 576101099Srwatson{ 577117247Srwatson 578156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 579101099Srwatson} 580101099Srwatson 581101099Srwatsonstatic int 582101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 583168976Srwatson struct label *vplabel, int acc_mode) 584101099Srwatson{ 585101099Srwatson 586156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 587101099Srwatson} 588101099Srwatson 589101099Srwatsonstatic int 590101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 591168976Srwatson struct label *dvplabel) 592101099Srwatson{ 593101099Srwatson 594156300Sdwmalone return (mac_bsdextended_check_vp(cred, dvp, MBI_READ)); 595101099Srwatson} 596101099Srwatson 597101099Srwatsonstatic int 598101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 599168976Srwatson struct label *vplabel) 600101099Srwatson{ 601101099Srwatson 602156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 603101099Srwatson} 604101099Srwatson 605101099Srwatsonstatic int 606101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 607168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 608101099Srwatson struct componentname *cnp) 609101099Srwatson{ 610101099Srwatson int error; 611101099Srwatson 612156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 613101099Srwatson if (error) 614101099Srwatson return (error); 615171253Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 616101099Srwatson} 617101099Srwatson 618101099Srwatsonstatic int 619101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 620168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 621168976Srwatson int samedir, struct componentname *cnp) 622101099Srwatson{ 623101099Srwatson int error; 624101099Srwatson 625156300Sdwmalone error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 626101099Srwatson if (error) 627101099Srwatson return (error); 628156300Sdwmalone if (vp != NULL) 629156300Sdwmalone error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 630101099Srwatson return (error); 631101099Srwatson} 632101099Srwatson 633101099Srwatsonstatic int 634101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 635168976Srwatson struct label *vplabel) 636101099Srwatson{ 637101099Srwatson 638156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 639101099Srwatson} 640101099Srwatson 641101099Srwatsonstatic int 642101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 643168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 644101099Srwatson{ 645101099Srwatson 646156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 647101099Srwatson} 648101099Srwatson 649101099Srwatsonstatic int 650101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 651168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 652168976Srwatson struct uio *uio) 653101099Srwatson{ 654101099Srwatson 655156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 656101099Srwatson} 657101099Srwatson 658101099Srwatsonstatic int 659101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 660168976Srwatson struct label *vplabel, u_long flags) 661101099Srwatson{ 662101099Srwatson 663156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 664101099Srwatson} 665101099Srwatson 666101099Srwatsonstatic int 667101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 668168976Srwatson struct label *vplabel, mode_t mode) 669101099Srwatson{ 670101099Srwatson 671156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 672101099Srwatson} 673101099Srwatson 674101099Srwatsonstatic int 675101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 676168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 677101099Srwatson{ 678101099Srwatson 679156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 680101099Srwatson} 681101099Srwatson 682101099Srwatsonstatic int 683101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 684168976Srwatson struct label *vplabel, struct timespec atime, struct timespec utime) 685101099Srwatson{ 686101099Srwatson 687156300Sdwmalone return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 688101099Srwatson} 689101099Srwatson 690101099Srwatsonstatic int 691102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 692168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 693101099Srwatson{ 694101099Srwatson 695156300Sdwmalone return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT)); 696101099Srwatson} 697101099Srwatson 698172107Srwatsonstatic int 699172107Srwatsonmac_bsdextended_check_vnode_unlink(struct ucred *cred, struct vnode *dvp, 700172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 701172107Srwatson struct componentname *cnp) 702172107Srwatson{ 703172107Srwatson int error; 704172107Srwatson 705172107Srwatson error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 706172107Srwatson if (error) 707172107Srwatson return (error); 708172107Srwatson return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 709172107Srwatson} 710172107Srwatson 711106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 712101099Srwatson{ 713106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 714106217Srwatson .mpo_init = mac_bsdextended_init, 715168933Srwatson .mpo_check_system_acct = mac_bsdextended_check_system_acct, 716168933Srwatson .mpo_check_system_auditctl = mac_bsdextended_check_system_auditctl, 717168933Srwatson .mpo_check_system_swapoff = mac_bsdextended_check_system_swapoff, 718112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 719106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 720106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 721106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 722106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 723106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 724119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 725106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 726106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 727106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 728106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 729119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 730106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 731106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 732106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 733106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 734106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 735106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 736106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 737106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 738106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 739106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 740106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 741106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 742106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 743106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 744172107Srwatson .mpo_check_vnode_unlink = mac_bsdextended_check_vnode_unlink, 745101099Srwatson}; 746101099Srwatson 747112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 748101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 749