ugidfw_vnode.c revision 157986
1164640Sflz/*- 298186Sgordon * Copyright (c) 2005 Tom Rhodes 378344Sobrien * Copyright (c) 1999-2002 Robert N. M. Watson 4157473Sflz * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 578344Sobrien * All rights reserved. 678344Sobrien * 778344Sobrien * This software was developed by Robert Watson for the TrustedBSD Project. 878344Sobrien * It was later enhanced by Tom Rhodes for the TrustedBSD Project. 978344Sobrien * 1078344Sobrien * This software was developed for the FreeBSD Project in part by Network 1178344Sobrien * Associates Laboratories, the Security Research Division of Network 1278344Sobrien * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 1378344Sobrien * as part of the DARPA CHATS research program. 1478344Sobrien * 1578344Sobrien * Redistribution and use in source and binary forms, with or without 1678344Sobrien * modification, are permitted provided that the following conditions 1778344Sobrien * are met: 1878344Sobrien * 1. Redistributions of source code must retain the above copyright 1978344Sobrien * notice, this list of conditions and the following disclaimer. 2078344Sobrien * 2. Redistributions in binary form must reproduce the above copyright 2178344Sobrien * notice, this list of conditions and the following disclaimer in the 2278344Sobrien * documentation and/or other materials provided with the distribution. 2378344Sobrien * 2478344Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2578344Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2678344Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2778344Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2878344Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2978344Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3078344Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3178344Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3278344Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3378344Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3478344Sobrien * SUCH DAMAGE. 35169668Smtm * 36157473Sflz * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 157986 2006-04-23 17:06:18Z dwmalone $ 3778344Sobrien */ 3898186Sgordon 3998186Sgordon/* 4098186Sgordon * Developed by the TrustedBSD Project. 41131550Scperciva * "BSD Extended" MAC policy, allowing the administrator to impose 42131550Scperciva * mandatory rules regarding users and some system objects. 43131550Scperciva */ 44131550Scperciva 4598186Sgordon#include <sys/types.h> 4698186Sgordon#include <sys/param.h> 47202988Semaste#include <sys/acl.h> 48124832Smtm#include <sys/conf.h> 49124832Smtm#include <sys/kernel.h> 50161435Syar#include <sys/jail.h> 51161435Syar#include <sys/lock.h> 5298186Sgordon#include <sys/mac.h> 5398186Sgordon#include <sys/malloc.h> 5478344Sobrien#include <sys/mount.h> 5578344Sobrien#include <sys/mutex.h> 5678344Sobrien#include <sys/proc.h> 57197144Shrs#include <sys/systm.h> 58197144Shrs#include <sys/sysproto.h> 59197144Shrs#include <sys/sysent.h> 6098186Sgordon#include <sys/vnode.h> 61197144Shrs#include <sys/file.h> 62197144Shrs#include <sys/socket.h> 63197144Shrs#include <sys/socketvar.h> 64197144Shrs#include <sys/sysctl.h> 65197144Shrs#include <sys/syslog.h> 66197144Shrs#include <sys/ucred.h> 67197144Shrs 68197144Shrs#include <net/bpfdesc.h> 69197144Shrs#include <net/if.h> 70197144Shrs#include <net/if_types.h> 71197144Shrs#include <net/if_var.h> 72197144Shrs 73197144Shrs#include <vm/vm.h> 7498186Sgordon 7598186Sgordon#include <sys/mac_policy.h> 7698186Sgordon 7798186Sgordon#include <security/mac_bsdextended/mac_bsdextended.h> 7898186Sgordon 7998186Sgordonstatic struct mtx mac_bsdextended_mtx; 8098186Sgordon 8198186SgordonSYSCTL_DECL(_security_mac); 8298186Sgordon 8398186SgordonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 8498186Sgordon "TrustedBSD extended BSD MAC policy controls"); 85146490Sschweikh 8698186Sgordonstatic int mac_bsdextended_enabled = 1; 8798186SgordonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 8898186Sgordon &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 8998186SgordonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 9098186Sgordon 9198186SgordonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 9298186Sgordon 9378344Sobrien#define MAC_BSDEXTENDED_MAXRULES 250 9478344Sobrienstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 9578344Sobrienstatic int rule_count = 0; 9678344Sobrienstatic int rule_slots = 0; 9778344Sobrienstatic int rule_version = MB_VERSION; 9878344Sobrien 9978344SobrienSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 10098186Sgordon &rule_count, 0, "Number of defined rules\n"); 10178344SobrienSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 10278344Sobrien &rule_slots, 0, "Number of used rule slots\n"); 10378344SobrienSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD, 10478344Sobrien &rule_version, 0, "Version number for API\n"); 10578344Sobrien 10678344Sobrien/* 10778344Sobrien * This is just used for logging purposes, eventually we would like 10878344Sobrien * to log much more then failed requests. 10978344Sobrien */ 11078344Sobrienstatic int mac_bsdextended_logging; 11178344SobrienSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 11278344Sobrien &mac_bsdextended_logging, 0, "Log failed authorization requests"); 113229822Sdougb 11478344Sobrien/* 11578344Sobrien * This tunable is here for compatibility. It will allow the user 11678344Sobrien * to switch between the new mode (first rule matches) and the old 11778344Sobrien * functionality (all rules match). 11878344Sobrien */ 119157473Sflzstatic int 12098186Sgordonmac_bsdextended_firstmatch_enabled; 12198186SgordonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 12278344Sobrien CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 12398186Sgordon "Disable/enable match first rule functionality"); 12498186Sgordon 12598186Sgordonstatic int 126126286Smtmmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 12798186Sgordon{ 12898186Sgordon 12998186Sgordon if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 13098186Sgordon return (EINVAL); 13198186Sgordon 132169668Smtm if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS) 133169668Smtm return (EINVAL); 134169668Smtm 135169668Smtm if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 13678344Sobrien return (EINVAL); 137169668Smtm 138169668Smtm if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS) 139169668Smtm return (EINVAL); 140169668Smtm 141178776Smaxim if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) && 142178776Smaxim (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE) 143178770Smtm return (EINVAL); 144169668Smtm 145178770Smtm if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 146178770Smtm return (EINVAL); 147169668Smtm 148178770Smtm return (0); 149178775Smaxim} 150169668Smtm 151169668Smtmstatic int 152169668Smtmsysctl_rule(SYSCTL_HANDLER_ARGS) 153169668Smtm{ 154169668Smtm struct mac_bsdextended_rule temprule, *ruleptr; 155169668Smtm u_int namelen; 156169668Smtm int error, index, *name; 157169668Smtm 15898186Sgordon error = 0; 15998186Sgordon name = (int *)arg1; 16098186Sgordon namelen = arg2; 16198186Sgordon 16298186Sgordon /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 16378344Sobrien 16478344Sobrien if (namelen != 1) 16598186Sgordon return (EINVAL); 16678344Sobrien 16778344Sobrien index = name[0]; 168126285Smtm if (index >= MAC_BSDEXTENDED_MAXRULES) 16978344Sobrien return (ENOENT); 17078344Sobrien 171126285Smtm ruleptr = NULL; 17278344Sobrien if (req->newptr && req->newlen != 0) { 17378344Sobrien error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 174126285Smtm if (error) 175126285Smtm return (error); 176126285Smtm MALLOC(ruleptr, struct mac_bsdextended_rule *, 17778344Sobrien sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); 17878344Sobrien } 17998186Sgordon 18078344Sobrien mtx_lock(&mac_bsdextended_mtx); 18178344Sobrien 18278344Sobrien if (req->oldptr) { 18378344Sobrien if (index < 0 || index > rule_slots + 1) { 18498186Sgordon error = ENOENT; 18598186Sgordon goto out; 18678344Sobrien } 18798186Sgordon if (rules[index] == NULL) { 18898186Sgordon error = ENOENT; 18978344Sobrien goto out; 19078344Sobrien } 19178344Sobrien temprule = *rules[index]; 19278344Sobrien } 19378344Sobrien 19498186Sgordon if (req->newptr && req->newlen == 0) { 19578344Sobrien /* printf("deletion\n"); */ 19698186Sgordon KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 19778344Sobrien ruleptr = rules[index]; 19878344Sobrien if (ruleptr == NULL) { 199131061Smtm error = ENOENT; 20078344Sobrien goto out; 20178344Sobrien } 20278344Sobrien rule_count--; 20378344Sobrien rules[index] = NULL; 204139949Skeramida } else if (req->newptr) { 20578344Sobrien error = mac_bsdextended_rule_valid(&temprule); 20678344Sobrien if (error) 20798186Sgordon goto out; 20878344Sobrien 20978344Sobrien if (rules[index] == NULL) { 21078344Sobrien /* printf("addition\n"); */ 21198186Sgordon *ruleptr = temprule; 21278344Sobrien rules[index] = ruleptr; 21398186Sgordon ruleptr = NULL; 21498186Sgordon if (index + 1 > rule_slots) 21578344Sobrien rule_slots = index + 1; 21678344Sobrien rule_count++; 21778344Sobrien } else { 21878344Sobrien /* printf("replacement\n"); */ 21998186Sgordon *rules[index] = temprule; 22078344Sobrien } 22198186Sgordon } 22278344Sobrien 22398186Sgordonout: 22498186Sgordon mtx_unlock(&mac_bsdextended_mtx); 22598186Sgordon if (ruleptr != NULL) 22698186Sgordon FREE(ruleptr, M_MACBSDEXTENDED); 22798186Sgordon if (req->oldptr && error == 0) 22898186Sgordon error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 22998186Sgordon 23098186Sgordon return (error); 23198186Sgordon} 23298186Sgordon 23398186SgordonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 23498186Sgordon CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 23598186Sgordon 23698186Sgordonstatic void 237155719Scerimac_bsdextended_init(struct mac_policy_conf *mpc) 23898186Sgordon{ 23998186Sgordon 24098186Sgordon /* Initialize ruleset lock. */ 24198186Sgordon mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 242157841Sflz 243157841Sflz /* Register dynamic sysctl's for rules. */ 244157841Sflz} 24598186Sgordon 24698186Sgordonstatic void 24798186Sgordonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 24898186Sgordon{ 24998186Sgordon 25098186Sgordon /* Destroy ruleset lock. */ 25198186Sgordon mtx_destroy(&mac_bsdextended_mtx); 25298186Sgordon 25398186Sgordon /* Tear down sysctls. */ 25498186Sgordon} 25578344Sobrien 25698186Sgordonstatic int 257170282Syarmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 258170282Syar struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode) 259170282Syar{ 260170282Syar int match; 261170282Syar int i; 262170282Syar 263170282Syar /* 264170282Syar * Is there a subject match? 265170282Syar */ 266170282Syar mtx_assert(&mac_bsdextended_mtx, MA_OWNED); 267170282Syar if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) { 268170282Syar match = ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max && 269170282Syar cred->cr_uid >= rule->mbr_subject.mbs_uid_min) || 270170282Syar (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max && 271170282Syar cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) || 272170282Syar (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max && 273170282Syar cred->cr_svuid >= rule->mbr_subject.mbs_uid_min)); 274170282Syar 275170282Syar if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED) 276170282Syar match = !match; 277170282Syar 278170282Syar if (!match) 279170282Syar return (0); 280170282Syar } 28178344Sobrien 28298186Sgordon if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) { 283157841Sflz match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max && 28498186Sgordon cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) || 28598186Sgordon (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max && 286157841Sflz cred->cr_svgid >= rule->mbr_subject.mbs_gid_min)); 28798186Sgordon 28898186Sgordon if (!match) { 28998186Sgordon for (i = 0; i < cred->cr_ngroups; i++) 29098186Sgordon if (cred->cr_groups[i] 291151426Sjhb <= rule->mbr_subject.mbs_gid_max && 29298186Sgordon cred->cr_groups[i] 29398186Sgordon >= rule->mbr_subject.mbs_gid_min) { 294161435Syar match = 1; 295161436Syar break; 296157657Sflz } 297161436Syar } 298157657Sflz 299157657Sflz if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED) 300157657Sflz match = !match; 301157657Sflz 30298186Sgordon if (!match) 30398186Sgordon return (0); 30498186Sgordon } 30598186Sgordon 306114272Smtm if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) { 30798186Sgordon match = (cred->cr_prison != NULL && 30898186Sgordon cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison); 30998186Sgordon 31098186Sgordon if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED) 31198186Sgordon match = !match; 31298186Sgordon 31398186Sgordon if (!match) 31498186Sgordon return (0); 31598186Sgordon } 316206248Sdougb 317206248Sdougb /* 318126286Smtm * Is there an object match? 31998186Sgordon */ 32098186Sgordon if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) { 32198186Sgordon match = (vap->va_uid <= rule->mbr_object.mbo_uid_max && 32298186Sgordon vap->va_uid >= rule->mbr_object.mbo_uid_min); 32398186Sgordon 32498186Sgordon if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED) 32598186Sgordon match = !match; 32698186Sgordon 32798186Sgordon if (!match) 328206248Sdougb return (0); 32998186Sgordon } 33098186Sgordon 33198186Sgordon if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) { 33298186Sgordon match = (vap->va_gid <= rule->mbr_object.mbo_gid_max && 33378344Sobrien vap->va_gid >= rule->mbr_object.mbo_gid_min); 33498186Sgordon 33598186Sgordon if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED) 33698186Sgordon match = !match; 337206248Sdougb 33878344Sobrien if (!match) 33998186Sgordon return (0); 34098186Sgordon } 34198186Sgordon 34278344Sobrien if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) { 34378344Sobrien match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid), 34478344Sobrien &(rule->mbr_object.mbo_fsid), 345220962Sdougb sizeof(rule->mbr_object.mbo_fsid)) == 0); 346220962Sdougb 347220962Sdougb if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED) 348220962Sdougb match = !match; 349220962Sdougb 350220962Sdougb if (!match) 351220962Sdougb return 0; 352220962Sdougb } 353220962Sdougb 354220962Sdougb if (rule->mbr_object.mbo_flags & MBO_SUID) { 355220962Sdougb match = (vap->va_mode & VSUID); 356220962Sdougb 357220962Sdougb if (rule->mbr_object.mbo_neg & MBO_SUID) 358220962Sdougb match = !match; 359220962Sdougb 360220963Sdougb if (!match) 361220963Sdougb return 0; 362220963Sdougb } 363220963Sdougb 364220962Sdougb if (rule->mbr_object.mbo_flags & MBO_SGID) { 365220962Sdougb match = (vap->va_mode & VSGID); 366220962Sdougb 367220962Sdougb if (rule->mbr_object.mbo_neg & MBO_SGID) 368220963Sdougb match = !match; 369220963Sdougb 370220962Sdougb if (!match) 371220962Sdougb return 0; 372220962Sdougb } 373220962Sdougb 374220962Sdougb if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) { 375220962Sdougb match = (vap->va_uid == cred->cr_uid || 376220962Sdougb vap->va_uid == cred->cr_ruid || 377220962Sdougb vap->va_uid == cred->cr_svuid); 378220962Sdougb 379220962Sdougb if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT) 380220962Sdougb match = !match; 381220962Sdougb 382220962Sdougb if (!match) 383220962Sdougb return 0; 384220962Sdougb } 385220962Sdougb 386220962Sdougb if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) { 387220962Sdougb match = (groupmember(vap->va_gid, cred) || 388197947Sdougb vap->va_gid == cred->cr_rgid || 389197947Sdougb vap->va_gid == cred->cr_svgid); 390197947Sdougb 391197947Sdougb if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT) 392197947Sdougb match = !match; 393197947Sdougb 394197947Sdougb if (!match) 395197947Sdougb return 0; 396197947Sdougb } 397197947Sdougb 398197947Sdougb if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) { 399197947Sdougb switch (vap->va_type) { 400197947Sdougb case VREG: 401197947Sdougb match = (rule->mbr_object.mbo_type & MBO_TYPE_REG); 40298186Sgordon break; 40398186Sgordon case VDIR: 40498186Sgordon match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR); 40598186Sgordon break; 40698186Sgordon case VBLK: 40778344Sobrien match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK); 40898186Sgordon break; 40998186Sgordon case VCHR: 41078344Sobrien match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR); 411175676Smtm break; 41298186Sgordon case VLNK: 413126303Smtm match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK); 414175676Smtm break; 41578344Sobrien case VSOCK: 41678344Sobrien match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK); 41778344Sobrien break; 41898186Sgordon case VFIFO: 41998186Sgordon match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO); 42078344Sobrien break; 42178344Sobrien default: 42278344Sobrien match = 0; 42398186Sgordon } 42478344Sobrien 42578344Sobrien if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED) 42678344Sobrien match = !match; 42778344Sobrien 42898186Sgordon if (!match) 42998186Sgordon return 0; 43098186Sgordon } 431197144Shrs 432197144Shrs /* 43378344Sobrien * Is the access permitted? 43478344Sobrien */ 43598186Sgordon if ((rule->mbr_mode & acc_mode) != acc_mode) { 43698186Sgordon if (mac_bsdextended_logging) 43798186Sgordon log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 43878344Sobrien " on %d:%d failed. \n", cred->cr_ruid, 43998186Sgordon cred->cr_rgid, acc_mode, vap->va_uid, vap->va_gid); 44098186Sgordon return (EACCES); /* Matching rule denies access */ 44178344Sobrien } 44278344Sobrien 44378344Sobrien /* 444157653Sflz * If the rule matched, permits access, and first match is enabled, 445157653Sflz * return success. 446157653Sflz */ 447157653Sflz if (mac_bsdextended_firstmatch_enabled) 44878344Sobrien return (EJUSTRETURN); 44998186Sgordon else 45078344Sobrien return(0); 45178344Sobrien} 45278344Sobrien 45378344Sobrienstatic int 45478344Sobrienmac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap, 45578344Sobrien int acc_mode) 45678344Sobrien{ 45778344Sobrien int error, i; 45878344Sobrien 45978344Sobrien if (suser_cred(cred, 0) == 0) 46078344Sobrien return (0); 46178344Sobrien 46298186Sgordon mtx_lock(&mac_bsdextended_mtx); 46378344Sobrien for (i = 0; i < rule_slots; i++) { 46478344Sobrien if (rules[i] == NULL) 46598186Sgordon continue; 46678344Sobrien 46798186Sgordon /* 46898186Sgordon * Since we do not separately handle append, map append to 46998186Sgordon * write. 47078344Sobrien */ 47198186Sgordon if (acc_mode & MBI_APPEND) { 47278344Sobrien acc_mode &= ~MBI_APPEND; 47378344Sobrien acc_mode |= MBI_WRITE; 47498186Sgordon } 47598186Sgordon 47698186Sgordon error = mac_bsdextended_rulecheck(rules[i], cred, 47798186Sgordon vp, vap, acc_mode); 47878344Sobrien if (error == EJUSTRETURN) 47998186Sgordon break; 48078344Sobrien if (error) { 48198186Sgordon mtx_unlock(&mac_bsdextended_mtx); 48298186Sgordon return (error); 48398186Sgordon } 48498186Sgordon } 48578344Sobrien mtx_unlock(&mac_bsdextended_mtx); 486165565Syar return (0); 48778344Sobrien} 48878344Sobrien 489165565Syarstatic int 49078344Sobrienmac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode) 491165565Syar{ 492165565Syar int error; 493165565Syar struct vattr vap; 494165565Syar 495165565Syar if (!mac_bsdextended_enabled) 496165565Syar return (0); 497165565Syar 498165565Syar error = VOP_GETATTR(vp, &vap, cred, curthread); 499165565Syar if (error) 500165565Syar return (error); 501165565Syar 502165565Syar return (mac_bsdextended_check(cred, vp, &vap, acc_mode)); 503165565Syar} 504165565Syar 505165565Syarstatic int 50678344Sobrienmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 50778344Sobrien struct label *label) 50878344Sobrien{ 50978344Sobrien 51098186Sgordon return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 51198186Sgordon} 51278344Sobrien 51398186Sgordonstatic int 51498186Sgordonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 51578344Sobrien struct label *label, int acc_mode) 51678344Sobrien{ 51778344Sobrien 51878344Sobrien return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 51998186Sgordon} 52078344Sobrien 52198186Sgordonstatic int 52298186Sgordonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 52398186Sgordon struct label *dlabel) 52498186Sgordon{ 52578344Sobrien 52698186Sgordon return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 52798186Sgordon} 52878344Sobrien 529151685Syarstatic int 530151685Syarmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 53178344Sobrien struct label *dlabel) 53278344Sobrien{ 53378344Sobrien 53498186Sgordon return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 53578344Sobrien} 53698186Sgordon 53798186Sgordonstatic int 53898186Sgordonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 53998186Sgordon struct label *dlabel, struct componentname *cnp, struct vattr *vap) 54098186Sgordon{ 54198186Sgordon 54298186Sgordon return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE)); 54398186Sgordon} 54498186Sgordon 545126303Smtmstatic int 54698186Sgordonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 54798186Sgordon struct label *dlabel, struct vnode *vp, struct label *label, 54898186Sgordon struct componentname *cnp) 54998186Sgordon{ 55098186Sgordon int error; 55198186Sgordon 55298186Sgordon error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 55398186Sgordon if (error) 55498186Sgordon return (error); 55598186Sgordon 55698186Sgordon return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 55798186Sgordon} 55898186Sgordon 559175676Smtmstatic int 56098186Sgordonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 561175676Smtm struct label *label, acl_type_t type) 56278344Sobrien{ 56378344Sobrien 564116097Smtm return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 56598186Sgordon} 56678344Sobrien 56798186Sgordonstatic int 56878344Sobrienmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 56978344Sobrien struct label *label, int attrnamespace, const char *name) 570132892Smtm{ 571132892Smtm 572132892Smtm return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 573132892Smtm} 574132892Smtm 575132892Smtmstatic int 576126303Smtmmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 57798186Sgordon struct label *label, struct image_params *imgp, 57878344Sobrien struct label *execlabel) 57998186Sgordon{ 58098186Sgordon 581175676Smtm return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC)); 58278344Sobrien} 583198216Sed 58498186Sgordonstatic int 585126303Smtmmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 586126303Smtm struct label *label, acl_type_t type) 58778344Sobrien{ 58878344Sobrien 58978344Sobrien return (mac_bsdextended_check_vp(cred, vp, MBI_STAT)); 59078344Sobrien} 591126303Smtm 592126303Smtmstatic int 593126303Smtmmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 594126303Smtm struct label *label, int attrnamespace, const char *name, struct uio *uio) 595126303Smtm{ 596126303Smtm 597126303Smtm return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 598175676Smtm} 599175676Smtm 600175676Smtmstatic int 601175676Smtmmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 602175676Smtm struct label *dlabel, struct vnode *vp, struct label *label, 60378344Sobrien struct componentname *cnp) 60478344Sobrien{ 605161530Sflz int error; 606198162Sdougb 607161530Sflz error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 60878344Sobrien if (error) 60998186Sgordon return (error); 61078344Sobrien 61198186Sgordon error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 61298186Sgordon if (error) 613131135Smtm return (error); 614131135Smtm return (0); 61578344Sobrien} 61698186Sgordon 61798186Sgordonstatic int 61898186Sgordonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 61978344Sobrien struct label *label, int attrnamespace) 62078344Sobrien{ 62198186Sgordon 62278344Sobrien return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 62378344Sobrien} 62478344Sobrien 62598186Sgordonstatic int 626150796Syarmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 62778344Sobrien struct label *dlabel, struct componentname *cnp) 62878344Sobrien{ 62978344Sobrien 63098186Sgordon return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC)); 63178344Sobrien} 63298186Sgordon 63378344Sobrienstatic int 63498186Sgordonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 63598186Sgordon struct label *filelabel, int acc_mode) 63698186Sgordon{ 63778344Sobrien 63898186Sgordon return (mac_bsdextended_check_vp(cred, vp, acc_mode)); 639124832Smtm} 64098186Sgordon 64198186Sgordonstatic int 64298186Sgordonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 64398186Sgordon struct label *dlabel) 644230374Sdougb{ 645179870Smtm 646179870Smtm return (mac_bsdextended_check_vp(cred, dvp, MBI_READ)); 647179870Smtm} 648179870Smtm 649179870Smtmstatic int 650206686Sdougbmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 651206686Sdougb struct label *label) 65278344Sobrien{ 65378344Sobrien 65478344Sobrien return (mac_bsdextended_check_vp(cred, vp, MBI_READ)); 655220760Sdougb} 656220760Sdougb 657179870Smtmstatic int 658179870Smtmmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 659179870Smtm struct label *dlabel, struct vnode *vp, struct label *label, 660179870Smtm struct componentname *cnp) 661179870Smtm{ 662179870Smtm int error; 663179870Smtm 664175676Smtm error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 665175676Smtm if (error) 66678344Sobrien return (error); 66778344Sobrien error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 66878344Sobrien 66978344Sobrien return (error); 67078344Sobrien} 671165565Syar 672165565Syarstatic int 673165565Syarmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 674165565Syar struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 67578344Sobrien struct componentname *cnp) 676165565Syar{ 677165565Syar int error; 678165565Syar 679116097Smtm error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE); 68078344Sobrien if (error) 68178344Sobrien return (error); 68298186Sgordon 68378344Sobrien if (vp != NULL) 68478344Sobrien error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE); 685165565Syar 68698186Sgordon return (error); 68798186Sgordon} 68878344Sobrien 68978344Sobrienstatic int 69078344Sobrienmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 69178344Sobrien struct label *label) 692165565Syar{ 69378344Sobrien 69478344Sobrien return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 69578344Sobrien} 696131135Smtm 697157473Sflzstatic int 698153152Syarmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 69978344Sobrien struct label *label, acl_type_t type, struct acl *acl) 70078344Sobrien{ 701167413Syar 702160667Syar return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 703153152Syar} 70478344Sobrien 70578344Sobrienstatic int 706179946Smtmmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 707179946Smtm struct label *label, int attrnamespace, const char *name, struct uio *uio) 708179946Smtm{ 709179946Smtm 71078344Sobrien return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE)); 711160668Syar} 71278344Sobrien 713197947Sdougbstatic int 71478344Sobrienmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 71578344Sobrien struct label *label, u_long flags) 71678344Sobrien{ 71778344Sobrien 71898186Sgordon return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 71978344Sobrien} 72078344Sobrien 721161396Syarstatic int 72298186Sgordonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 72398186Sgordon struct label *label, mode_t mode) 72498186Sgordon{ 72598186Sgordon 726161396Syar return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 727161396Syar} 728161396Syar 729201036Sdougbstatic int 730161396Syarmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 731161396Syar struct label *label, uid_t uid, gid_t gid) 73278344Sobrien{ 73398186Sgordon 734165565Syar return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 73598186Sgordon} 736179946Smtm 737179946Smtmstatic int 738179946Smtmmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 739179946Smtm struct label *label, struct timespec atime, struct timespec utime) 74098186Sgordon{ 74198186Sgordon 74298186Sgordon return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN)); 743165565Syar} 74478344Sobrien 74578344Sobrienstatic int 74678344Sobrienmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 74798186Sgordon struct ucred *file_cred, struct vnode *vp, struct label *label) 748153152Syar{ 749165565Syar 750153152Syar return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT)); 75178344Sobrien} 75278344Sobrien 753165565Syarstatic struct mac_policy_ops mac_bsdextended_ops = 75498186Sgordon{ 75598186Sgordon .mpo_destroy = mac_bsdextended_destroy, 75698186Sgordon .mpo_init = mac_bsdextended_init, 75778344Sobrien .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 758165565Syar .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 759165565Syar .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 76098186Sgordon .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 76198186Sgordon .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 76298186Sgordon .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 76398186Sgordon .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 764165565Syar .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 765165565Syar .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 76678344Sobrien .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 76778344Sobrien .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 76878344Sobrien .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 76998186Sgordon .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 770165565Syar .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 771153152Syar .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 77278344Sobrien .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 773165565Syar .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 774165565Syar .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 775165565Syar .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 776165565Syar .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 777165565Syar .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 778165565Syar .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 779165565Syar .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 78078344Sobrien .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 78178344Sobrien .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 78278344Sobrien .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 78378344Sobrien .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 78478344Sobrien}; 78578344Sobrien 786126285SmtmMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 78778344Sobrien "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 78878344Sobrien