mac_partition.c revision 168976
1105828Srwatson/*- 2166533Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3126097Srwatson * Copyright (c) 2001-2002 Networks Associates Technology, Inc. 4105828Srwatson * All rights reserved. 5105828Srwatson * 6105828Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7105828Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12105828Srwatson * 13105828Srwatson * Redistribution and use in source and binary forms, with or without 14105828Srwatson * modification, are permitted provided that the following conditions 15105828Srwatson * are met: 16105828Srwatson * 1. Redistributions of source code must retain the above copyright 17105828Srwatson * notice, this list of conditions and the following disclaimer. 18105828Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19105828Srwatson * notice, this list of conditions and the following disclaimer in the 20105828Srwatson * documentation and/or other materials provided with the distribution. 21105828Srwatson * 22105828Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23105828Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24105828Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25105828Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26105828Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27105828Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28105828Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29105828Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30105828Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31105828Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32105828Srwatson * SUCH DAMAGE. 33105828Srwatson * 34105828Srwatson * $FreeBSD: head/sys/security/mac_partition/mac_partition.c 168976 2007-04-23 13:15:23Z rwatson $ 35105828Srwatson */ 36105828Srwatson 37105828Srwatson/* 38105828Srwatson * Developed by the TrustedBSD Project. 39105828Srwatson * Experiment with a partition-like model. 40105828Srwatson */ 41105828Srwatson 42105828Srwatson#include <sys/param.h> 43105828Srwatson#include <sys/kernel.h> 44166905Srwatson#include <sys/module.h> 45164033Srwatson#include <sys/priv.h> 46105828Srwatson#include <sys/proc.h> 47116701Srwatson#include <sys/sbuf.h> 48105828Srwatson#include <sys/systm.h> 49105828Srwatson#include <sys/sysctl.h> 50105828Srwatson 51165469Srwatson#include <security/mac/mac_policy.h> 52105828Srwatson#include <security/mac_partition/mac_partition.h> 53105828Srwatson 54105828SrwatsonSYSCTL_DECL(_security_mac); 55105828Srwatson 56105828SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, partition, CTLFLAG_RW, 0, 57105828Srwatson "TrustedBSD mac_partition policy controls"); 58105828Srwatson 59105828Srwatsonstatic int mac_partition_enabled = 1; 60105828SrwatsonSYSCTL_INT(_security_mac_partition, OID_AUTO, enabled, CTLFLAG_RW, 61105828Srwatson &mac_partition_enabled, 0, "Enforce partition policy"); 62105828Srwatson 63105828Srwatsonstatic int partition_slot; 64166533Srwatson#define SLOT(l) mac_label_get((l), partition_slot) 65166533Srwatson#define SLOT_SET(l, v) mac_label_set((l), partition_slot, (v)) 66105828Srwatson 67105828Srwatsonstatic void 68105828Srwatsonmac_partition_init_label(struct label *label) 69105828Srwatson{ 70105828Srwatson 71166533Srwatson SLOT_SET(label, 0); 72105828Srwatson} 73105828Srwatson 74105828Srwatsonstatic void 75105828Srwatsonmac_partition_destroy_label(struct label *label) 76105828Srwatson{ 77105828Srwatson 78166533Srwatson SLOT_SET(label, 0); 79105828Srwatson} 80105828Srwatson 81123173Srwatsonstatic void 82123173Srwatsonmac_partition_copy_label(struct label *src, struct label *dest) 83123173Srwatson{ 84123173Srwatson 85166533Srwatson SLOT_SET(dest, SLOT(src)); 86123173Srwatson} 87123173Srwatson 88105828Srwatsonstatic int 89105828Srwatsonmac_partition_externalize_label(struct label *label, char *element_name, 90116701Srwatson struct sbuf *sb, int *claimed) 91105828Srwatson{ 92105828Srwatson 93105828Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 94105828Srwatson return (0); 95105828Srwatson 96105828Srwatson (*claimed)++; 97116701Srwatson 98166538Srwatson if (sbuf_printf(sb, "%jd", (intmax_t)SLOT(label)) == -1) 99116701Srwatson return (EINVAL); 100116701Srwatson else 101116701Srwatson return (0); 102105828Srwatson} 103105828Srwatson 104105828Srwatsonstatic int 105105828Srwatsonmac_partition_internalize_label(struct label *label, char *element_name, 106105828Srwatson char *element_data, int *claimed) 107105828Srwatson{ 108105828Srwatson 109105828Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 110105828Srwatson return (0); 111105828Srwatson 112105828Srwatson (*claimed)++; 113166533Srwatson SLOT_SET(label, strtol(element_data, NULL, 10)); 114105828Srwatson return (0); 115105828Srwatson} 116105828Srwatson 117105828Srwatsonstatic void 118105828Srwatsonmac_partition_create_proc0(struct ucred *cred) 119105828Srwatson{ 120105828Srwatson 121166533Srwatson SLOT_SET(cred->cr_label, 0); 122105828Srwatson} 123105828Srwatson 124105828Srwatsonstatic void 125105828Srwatsonmac_partition_create_proc1(struct ucred *cred) 126105828Srwatson{ 127105828Srwatson 128166533Srwatson SLOT_SET(cred->cr_label, 0); 129105828Srwatson} 130105828Srwatson 131105828Srwatsonstatic void 132105828Srwatsonmac_partition_relabel_cred(struct ucred *cred, struct label *newlabel) 133105828Srwatson{ 134105828Srwatson 135105828Srwatson if (SLOT(newlabel) != 0) 136166533Srwatson SLOT_SET(cred->cr_label, SLOT(newlabel)); 137105828Srwatson} 138105828Srwatson 139105828Srwatsonstatic int 140105828Srwatsonlabel_on_label(struct label *subject, struct label *object) 141105828Srwatson{ 142105828Srwatson 143105828Srwatson if (mac_partition_enabled == 0) 144105828Srwatson return (0); 145105828Srwatson 146105828Srwatson if (SLOT(subject) == 0) 147105828Srwatson return (0); 148105828Srwatson 149105828Srwatson if (SLOT(subject) == SLOT(object)) 150105828Srwatson return (0); 151105828Srwatson 152105828Srwatson return (EPERM); 153105828Srwatson} 154105828Srwatson 155105828Srwatsonstatic int 156105828Srwatsonmac_partition_check_cred_relabel(struct ucred *cred, struct label *newlabel) 157105828Srwatson{ 158105828Srwatson int error; 159105828Srwatson 160105828Srwatson error = 0; 161105828Srwatson 162105828Srwatson /* Treat "0" as a no-op request. */ 163105828Srwatson if (SLOT(newlabel) != 0) { 164105828Srwatson /* 165106367Srwatson * Require BSD privilege in order to change the partition. 166106367Srwatson * Originally we also required that the process not be 167106367Srwatson * in a partition in the first place, but this didn't 168106367Srwatson * interact well with sendmail. 169105828Srwatson */ 170164033Srwatson error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0); 171105828Srwatson } 172105828Srwatson 173105828Srwatson return (error); 174105828Srwatson} 175105828Srwatson 176105828Srwatsonstatic int 177168976Srwatsonmac_partition_check_cred_visible(struct ucred *cr1, struct ucred *cr2) 178105828Srwatson{ 179105828Srwatson int error; 180105828Srwatson 181168976Srwatson error = label_on_label(cr1->cr_label, cr2->cr_label); 182105828Srwatson 183105828Srwatson return (error == 0 ? 0 : ESRCH); 184105828Srwatson} 185105828Srwatson 186105828Srwatsonstatic int 187168976Srwatsonmac_partition_check_proc_debug(struct ucred *cred, struct proc *p) 188105828Srwatson{ 189105828Srwatson int error; 190105828Srwatson 191168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 192105828Srwatson 193105828Srwatson return (error ? ESRCH : 0); 194105828Srwatson} 195105828Srwatson 196105828Srwatsonstatic int 197168976Srwatsonmac_partition_check_proc_sched(struct ucred *cred, struct proc *p) 198105828Srwatson{ 199105828Srwatson int error; 200105828Srwatson 201168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 202105828Srwatson 203105828Srwatson return (error ? ESRCH : 0); 204105828Srwatson} 205105828Srwatson 206105828Srwatsonstatic int 207168976Srwatsonmac_partition_check_proc_signal(struct ucred *cred, struct proc *p, 208105828Srwatson int signum) 209105828Srwatson{ 210105828Srwatson int error; 211105828Srwatson 212168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 213105828Srwatson 214105828Srwatson return (error ? ESRCH : 0); 215105828Srwatson} 216105828Srwatson 217105828Srwatsonstatic int 218168976Srwatsonmac_partition_check_socket_visible(struct ucred *cred, struct socket *so, 219168976Srwatson struct label *solabel) 220105828Srwatson{ 221105828Srwatson int error; 222105828Srwatson 223168976Srwatson error = label_on_label(cred->cr_label, solabel); 224105828Srwatson 225105828Srwatson return (error ? ENOENT : 0); 226105828Srwatson} 227105828Srwatson 228106648Srwatsonstatic int 229106648Srwatsonmac_partition_check_vnode_exec(struct ucred *cred, struct vnode *vp, 230168976Srwatson struct label *vplabel, struct image_params *imgp, 231168976Srwatson struct label *execlabel) 232106648Srwatson{ 233106648Srwatson 234106648Srwatson if (execlabel != NULL) { 235106648Srwatson /* 236106648Srwatson * We currently don't permit labels to be changed at 237106648Srwatson * exec-time as part of the partition model, so disallow 238106648Srwatson * non-NULL partition label changes in execlabel. 239106648Srwatson */ 240106648Srwatson if (SLOT(execlabel) != 0) 241106648Srwatson return (EINVAL); 242106648Srwatson } 243106648Srwatson 244106648Srwatson return (0); 245106648Srwatson} 246106648Srwatson 247106217Srwatsonstatic struct mac_policy_ops mac_partition_ops = 248105828Srwatson{ 249106217Srwatson .mpo_init_cred_label = mac_partition_init_label, 250106217Srwatson .mpo_destroy_cred_label = mac_partition_destroy_label, 251123173Srwatson .mpo_copy_cred_label = mac_partition_copy_label, 252106217Srwatson .mpo_externalize_cred_label = mac_partition_externalize_label, 253106217Srwatson .mpo_internalize_cred_label = mac_partition_internalize_label, 254106217Srwatson .mpo_create_proc0 = mac_partition_create_proc0, 255106217Srwatson .mpo_create_proc1 = mac_partition_create_proc1, 256106217Srwatson .mpo_relabel_cred = mac_partition_relabel_cred, 257106217Srwatson .mpo_check_cred_relabel = mac_partition_check_cred_relabel, 258106217Srwatson .mpo_check_cred_visible = mac_partition_check_cred_visible, 259106217Srwatson .mpo_check_proc_debug = mac_partition_check_proc_debug, 260106217Srwatson .mpo_check_proc_sched = mac_partition_check_proc_sched, 261106217Srwatson .mpo_check_proc_signal = mac_partition_check_proc_signal, 262106217Srwatson .mpo_check_socket_visible = mac_partition_check_socket_visible, 263106648Srwatson .mpo_check_vnode_exec = mac_partition_check_vnode_exec, 264105828Srwatson}; 265105828Srwatson 266112717SrwatsonMAC_POLICY_SET(&mac_partition_ops, mac_partition, "TrustedBSD MAC/Partition", 267112717Srwatson MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot); 268