mac_partition.c revision 172955
1105828Srwatson/*- 2166533Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3126097Srwatson * Copyright (c) 2001-2002 Networks Associates Technology, Inc. 4172930Srwatson * Copyright (c) 2006 SPARTA, Inc. 5105828Srwatson * All rights reserved. 6105828Srwatson * 7105828Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8105828Srwatson * 9106393Srwatson * This software was developed for the FreeBSD Project in part by Network 10106393Srwatson * Associates Laboratories, the Security Research Division of Network 11106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 12106393Srwatson * as part of the DARPA CHATS research program. 13105828Srwatson * 14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 15172930Srwatson * N66001-04-C-6019 ("SEFOS"). 16172930Srwatson * 17105828Srwatson * Redistribution and use in source and binary forms, with or without 18105828Srwatson * modification, are permitted provided that the following conditions 19105828Srwatson * are met: 20105828Srwatson * 1. Redistributions of source code must retain the above copyright 21105828Srwatson * notice, this list of conditions and the following disclaimer. 22105828Srwatson * 2. Redistributions in binary form must reproduce the above copyright 23105828Srwatson * notice, this list of conditions and the following disclaimer in the 24105828Srwatson * documentation and/or other materials provided with the distribution. 25105828Srwatson * 26105828Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27105828Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28105828Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29105828Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30105828Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31105828Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32105828Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33105828Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34105828Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35105828Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36105828Srwatson * SUCH DAMAGE. 37105828Srwatson * 38105828Srwatson * $FreeBSD: head/sys/security/mac_partition/mac_partition.c 172955 2007-10-25 11:31:11Z rwatson $ 39105828Srwatson */ 40105828Srwatson 41105828Srwatson/* 42105828Srwatson * Developed by the TrustedBSD Project. 43172955Srwatson * 44105828Srwatson * Experiment with a partition-like model. 45105828Srwatson */ 46105828Srwatson 47105828Srwatson#include <sys/param.h> 48105828Srwatson#include <sys/kernel.h> 49166905Srwatson#include <sys/module.h> 50164033Srwatson#include <sys/priv.h> 51105828Srwatson#include <sys/proc.h> 52116701Srwatson#include <sys/sbuf.h> 53105828Srwatson#include <sys/systm.h> 54105828Srwatson#include <sys/sysctl.h> 55105828Srwatson 56165469Srwatson#include <security/mac/mac_policy.h> 57105828Srwatson#include <security/mac_partition/mac_partition.h> 58105828Srwatson 59105828SrwatsonSYSCTL_DECL(_security_mac); 60105828Srwatson 61105828SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, partition, CTLFLAG_RW, 0, 62105828Srwatson "TrustedBSD mac_partition policy controls"); 63105828Srwatson 64105828Srwatsonstatic int mac_partition_enabled = 1; 65105828SrwatsonSYSCTL_INT(_security_mac_partition, OID_AUTO, enabled, CTLFLAG_RW, 66105828Srwatson &mac_partition_enabled, 0, "Enforce partition policy"); 67105828Srwatson 68105828Srwatsonstatic int partition_slot; 69166533Srwatson#define SLOT(l) mac_label_get((l), partition_slot) 70166533Srwatson#define SLOT_SET(l, v) mac_label_set((l), partition_slot, (v)) 71105828Srwatson 72105828Srwatsonstatic void 73172955Srwatsonpartition_init_label(struct label *label) 74105828Srwatson{ 75105828Srwatson 76166533Srwatson SLOT_SET(label, 0); 77105828Srwatson} 78105828Srwatson 79105828Srwatsonstatic void 80172955Srwatsonpartition_destroy_label(struct label *label) 81105828Srwatson{ 82105828Srwatson 83166533Srwatson SLOT_SET(label, 0); 84105828Srwatson} 85105828Srwatson 86123173Srwatsonstatic void 87172955Srwatsonpartition_copy_label(struct label *src, struct label *dest) 88123173Srwatson{ 89123173Srwatson 90166533Srwatson SLOT_SET(dest, SLOT(src)); 91123173Srwatson} 92123173Srwatson 93105828Srwatsonstatic int 94172955Srwatsonpartition_externalize_label(struct label *label, char *element_name, 95116701Srwatson struct sbuf *sb, int *claimed) 96105828Srwatson{ 97105828Srwatson 98105828Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 99105828Srwatson return (0); 100105828Srwatson 101105828Srwatson (*claimed)++; 102116701Srwatson 103166538Srwatson if (sbuf_printf(sb, "%jd", (intmax_t)SLOT(label)) == -1) 104116701Srwatson return (EINVAL); 105116701Srwatson else 106116701Srwatson return (0); 107105828Srwatson} 108105828Srwatson 109105828Srwatsonstatic int 110172955Srwatsonpartition_internalize_label(struct label *label, char *element_name, 111105828Srwatson char *element_data, int *claimed) 112105828Srwatson{ 113105828Srwatson 114105828Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 115105828Srwatson return (0); 116105828Srwatson 117105828Srwatson (*claimed)++; 118166533Srwatson SLOT_SET(label, strtol(element_data, NULL, 10)); 119105828Srwatson return (0); 120105828Srwatson} 121105828Srwatson 122105828Srwatsonstatic void 123172955Srwatsonpartition_proc_create_swapper(struct ucred *cred) 124105828Srwatson{ 125105828Srwatson 126166533Srwatson SLOT_SET(cred->cr_label, 0); 127105828Srwatson} 128105828Srwatson 129105828Srwatsonstatic void 130172955Srwatsonpartition_proc_create_init(struct ucred *cred) 131105828Srwatson{ 132105828Srwatson 133166533Srwatson SLOT_SET(cred->cr_label, 0); 134105828Srwatson} 135105828Srwatson 136105828Srwatsonstatic void 137172955Srwatsonpartition_cred_relabel(struct ucred *cred, struct label *newlabel) 138105828Srwatson{ 139105828Srwatson 140105828Srwatson if (SLOT(newlabel) != 0) 141166533Srwatson SLOT_SET(cred->cr_label, SLOT(newlabel)); 142105828Srwatson} 143105828Srwatson 144105828Srwatsonstatic int 145105828Srwatsonlabel_on_label(struct label *subject, struct label *object) 146105828Srwatson{ 147105828Srwatson 148105828Srwatson if (mac_partition_enabled == 0) 149105828Srwatson return (0); 150105828Srwatson 151105828Srwatson if (SLOT(subject) == 0) 152105828Srwatson return (0); 153105828Srwatson 154105828Srwatson if (SLOT(subject) == SLOT(object)) 155105828Srwatson return (0); 156105828Srwatson 157105828Srwatson return (EPERM); 158105828Srwatson} 159105828Srwatson 160105828Srwatsonstatic int 161172955Srwatsonpartition_cred_check_relabel(struct ucred *cred, struct label *newlabel) 162105828Srwatson{ 163105828Srwatson int error; 164105828Srwatson 165105828Srwatson error = 0; 166105828Srwatson 167105828Srwatson /* Treat "0" as a no-op request. */ 168105828Srwatson if (SLOT(newlabel) != 0) { 169105828Srwatson /* 170106367Srwatson * Require BSD privilege in order to change the partition. 171172955Srwatson * Originally we also required that the process not be in a 172172955Srwatson * partition in the first place, but this didn't interact 173172955Srwatson * well with sendmail. 174105828Srwatson */ 175164033Srwatson error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0); 176105828Srwatson } 177105828Srwatson 178105828Srwatson return (error); 179105828Srwatson} 180105828Srwatson 181105828Srwatsonstatic int 182172955Srwatsonpartition_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 183105828Srwatson{ 184105828Srwatson int error; 185105828Srwatson 186168976Srwatson error = label_on_label(cr1->cr_label, cr2->cr_label); 187105828Srwatson 188105828Srwatson return (error == 0 ? 0 : ESRCH); 189105828Srwatson} 190105828Srwatson 191105828Srwatsonstatic int 192172955Srwatsonpartition_proc_check_debug(struct ucred *cred, struct proc *p) 193105828Srwatson{ 194105828Srwatson int error; 195105828Srwatson 196168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 197105828Srwatson 198105828Srwatson return (error ? ESRCH : 0); 199105828Srwatson} 200105828Srwatson 201105828Srwatsonstatic int 202172955Srwatsonpartition_proc_check_sched(struct ucred *cred, struct proc *p) 203105828Srwatson{ 204105828Srwatson int error; 205105828Srwatson 206168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 207105828Srwatson 208105828Srwatson return (error ? ESRCH : 0); 209105828Srwatson} 210105828Srwatson 211105828Srwatsonstatic int 212172955Srwatsonpartition_proc_check_signal(struct ucred *cred, struct proc *p, 213105828Srwatson int signum) 214105828Srwatson{ 215105828Srwatson int error; 216105828Srwatson 217168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 218105828Srwatson 219105828Srwatson return (error ? ESRCH : 0); 220105828Srwatson} 221105828Srwatson 222105828Srwatsonstatic int 223172955Srwatsonpartition_socket_check_visible(struct ucred *cred, struct socket *so, 224168976Srwatson struct label *solabel) 225105828Srwatson{ 226105828Srwatson int error; 227105828Srwatson 228168976Srwatson error = label_on_label(cred->cr_label, solabel); 229105828Srwatson 230105828Srwatson return (error ? ENOENT : 0); 231105828Srwatson} 232105828Srwatson 233106648Srwatsonstatic int 234172955Srwatsonpartition_vnode_check_exec(struct ucred *cred, struct vnode *vp, 235168976Srwatson struct label *vplabel, struct image_params *imgp, 236168976Srwatson struct label *execlabel) 237106648Srwatson{ 238106648Srwatson 239106648Srwatson if (execlabel != NULL) { 240106648Srwatson /* 241106648Srwatson * We currently don't permit labels to be changed at 242106648Srwatson * exec-time as part of the partition model, so disallow 243106648Srwatson * non-NULL partition label changes in execlabel. 244106648Srwatson */ 245106648Srwatson if (SLOT(execlabel) != 0) 246106648Srwatson return (EINVAL); 247106648Srwatson } 248106648Srwatson 249106648Srwatson return (0); 250106648Srwatson} 251106648Srwatson 252172955Srwatsonstatic struct mac_policy_ops partition_ops = 253105828Srwatson{ 254172955Srwatson .mpo_cred_init_label = partition_init_label, 255172955Srwatson .mpo_cred_destroy_label = partition_destroy_label, 256172955Srwatson .mpo_cred_copy_label = partition_copy_label, 257172955Srwatson .mpo_cred_externalize_label = partition_externalize_label, 258172955Srwatson .mpo_cred_internalize_label = partition_internalize_label, 259172955Srwatson .mpo_proc_create_swapper = partition_proc_create_swapper, 260172955Srwatson .mpo_proc_create_init = partition_proc_create_init, 261172955Srwatson .mpo_cred_relabel = partition_cred_relabel, 262172955Srwatson .mpo_cred_check_relabel = partition_cred_check_relabel, 263172955Srwatson .mpo_cred_check_visible = partition_cred_check_visible, 264172955Srwatson .mpo_proc_check_debug = partition_proc_check_debug, 265172955Srwatson .mpo_proc_check_sched = partition_proc_check_sched, 266172955Srwatson .mpo_proc_check_signal = partition_proc_check_signal, 267172955Srwatson .mpo_socket_check_visible = partition_socket_check_visible, 268172955Srwatson .mpo_vnode_check_exec = partition_vnode_check_exec, 269105828Srwatson}; 270105828Srwatson 271172955SrwatsonMAC_POLICY_SET(&partition_ops, mac_partition, "TrustedBSD MAC/Partition", 272112717Srwatson MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot); 273