mac_partition.c revision 181213
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 181213 2008-08-02 20:53:59Z 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 64181213Srwatsonstatic int partition_enabled = 1; 65105828SrwatsonSYSCTL_INT(_security_mac_partition, OID_AUTO, enabled, CTLFLAG_RW, 66181213Srwatson &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 72173138Srwatsonstatic int 73173138Srwatsonlabel_on_label(struct label *subject, struct label *object) 74105828Srwatson{ 75105828Srwatson 76181213Srwatson if (partition_enabled == 0) 77173138Srwatson return (0); 78105828Srwatson 79173138Srwatson if (SLOT(subject) == 0) 80173138Srwatson return (0); 81105828Srwatson 82173138Srwatson if (SLOT(subject) == SLOT(object)) 83173138Srwatson return (0); 84105828Srwatson 85173138Srwatson return (EPERM); 86123173Srwatson} 87123173Srwatson 88173138Srwatson/* 89173138Srwatson * Object-specific entry points are sorted alphabetically by object type name 90173138Srwatson * and then by operation. 91173138Srwatson */ 92105828Srwatsonstatic int 93173138Srwatsonpartition_cred_check_relabel(struct ucred *cred, struct label *newlabel) 94105828Srwatson{ 95173138Srwatson int error; 96105828Srwatson 97173138Srwatson error = 0; 98105828Srwatson 99173138Srwatson /* Treat "0" as a no-op request. */ 100173138Srwatson if (SLOT(newlabel) != 0) { 101173138Srwatson /* 102173138Srwatson * Require BSD privilege in order to change the partition. 103173138Srwatson * Originally we also required that the process not be in a 104173138Srwatson * partition in the first place, but this didn't interact 105173138Srwatson * well with sendmail. 106173138Srwatson */ 107173138Srwatson error = priv_check_cred(cred, PRIV_MAC_PARTITION, 0); 108173138Srwatson } 109116701Srwatson 110173138Srwatson return (error); 111105828Srwatson} 112105828Srwatson 113105828Srwatsonstatic int 114173138Srwatsonpartition_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 115105828Srwatson{ 116173138Srwatson int error; 117105828Srwatson 118173138Srwatson error = label_on_label(cr1->cr_label, cr2->cr_label); 119105828Srwatson 120173138Srwatson return (error == 0 ? 0 : ESRCH); 121105828Srwatson} 122105828Srwatson 123105828Srwatsonstatic void 124173138Srwatsonpartition_cred_copy_label(struct label *src, struct label *dest) 125105828Srwatson{ 126105828Srwatson 127173138Srwatson SLOT_SET(dest, SLOT(src)); 128105828Srwatson} 129105828Srwatson 130105828Srwatsonstatic void 131173138Srwatsonpartition_cred_destroy_label(struct label *label) 132105828Srwatson{ 133105828Srwatson 134173138Srwatson SLOT_SET(label, 0); 135105828Srwatson} 136105828Srwatson 137105828Srwatsonstatic int 138173138Srwatsonpartition_cred_externalize_label(struct label *label, char *element_name, 139173138Srwatson struct sbuf *sb, int *claimed) 140105828Srwatson{ 141105828Srwatson 142173138Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 143105828Srwatson return (0); 144105828Srwatson 145173138Srwatson (*claimed)++; 146105828Srwatson 147173138Srwatson if (sbuf_printf(sb, "%jd", (intmax_t)SLOT(label)) == -1) 148173138Srwatson return (EINVAL); 149173138Srwatson else 150105828Srwatson return (0); 151173138Srwatson} 152105828Srwatson 153173138Srwatsonstatic void 154173138Srwatsonpartition_cred_init_label(struct label *label) 155173138Srwatson{ 156173138Srwatson 157173138Srwatson SLOT_SET(label, 0); 158105828Srwatson} 159105828Srwatson 160105828Srwatsonstatic int 161173138Srwatsonpartition_cred_internalize_label(struct label *label, char *element_name, 162173138Srwatson char *element_data, int *claimed) 163105828Srwatson{ 164105828Srwatson 165173138Srwatson if (strcmp(MAC_PARTITION_LABEL_NAME, element_name) != 0) 166173138Srwatson return (0); 167105828Srwatson 168173138Srwatson (*claimed)++; 169173138Srwatson SLOT_SET(label, strtol(element_data, NULL, 10)); 170173138Srwatson return (0); 171105828Srwatson} 172105828Srwatson 173173138Srwatsonstatic void 174173138Srwatsonpartition_cred_relabel(struct ucred *cred, struct label *newlabel) 175105828Srwatson{ 176105828Srwatson 177173138Srwatson if (SLOT(newlabel) != 0) 178173138Srwatson SLOT_SET(cred->cr_label, SLOT(newlabel)); 179105828Srwatson} 180105828Srwatson 181105828Srwatsonstatic int 182172955Srwatsonpartition_proc_check_debug(struct ucred *cred, struct proc *p) 183105828Srwatson{ 184105828Srwatson int error; 185105828Srwatson 186168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 187105828Srwatson 188105828Srwatson return (error ? ESRCH : 0); 189105828Srwatson} 190105828Srwatson 191105828Srwatsonstatic int 192172955Srwatsonpartition_proc_check_sched(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_signal(struct ucred *cred, struct proc *p, 203105828Srwatson int signum) 204105828Srwatson{ 205105828Srwatson int error; 206105828Srwatson 207168976Srwatson error = label_on_label(cred->cr_label, p->p_ucred->cr_label); 208105828Srwatson 209105828Srwatson return (error ? ESRCH : 0); 210105828Srwatson} 211105828Srwatson 212173138Srwatsonstatic void 213173138Srwatsonpartition_proc_create_init(struct ucred *cred) 214173138Srwatson{ 215173138Srwatson 216173138Srwatson SLOT_SET(cred->cr_label, 0); 217173138Srwatson} 218173138Srwatson 219173138Srwatsonstatic void 220173138Srwatsonpartition_proc_create_swapper(struct ucred *cred) 221173138Srwatson{ 222173138Srwatson 223173138Srwatson SLOT_SET(cred->cr_label, 0); 224173138Srwatson} 225173138Srwatson 226105828Srwatsonstatic int 227172955Srwatsonpartition_socket_check_visible(struct ucred *cred, struct socket *so, 228168976Srwatson struct label *solabel) 229105828Srwatson{ 230105828Srwatson int error; 231105828Srwatson 232168976Srwatson error = label_on_label(cred->cr_label, solabel); 233105828Srwatson 234105828Srwatson return (error ? ENOENT : 0); 235105828Srwatson} 236105828Srwatson 237106648Srwatsonstatic int 238172955Srwatsonpartition_vnode_check_exec(struct ucred *cred, struct vnode *vp, 239168976Srwatson struct label *vplabel, struct image_params *imgp, 240168976Srwatson struct label *execlabel) 241106648Srwatson{ 242106648Srwatson 243106648Srwatson if (execlabel != NULL) { 244106648Srwatson /* 245106648Srwatson * We currently don't permit labels to be changed at 246106648Srwatson * exec-time as part of the partition model, so disallow 247106648Srwatson * non-NULL partition label changes in execlabel. 248106648Srwatson */ 249106648Srwatson if (SLOT(execlabel) != 0) 250106648Srwatson return (EINVAL); 251106648Srwatson } 252106648Srwatson 253106648Srwatson return (0); 254106648Srwatson} 255106648Srwatson 256172955Srwatsonstatic struct mac_policy_ops partition_ops = 257105828Srwatson{ 258172955Srwatson .mpo_cred_check_relabel = partition_cred_check_relabel, 259172955Srwatson .mpo_cred_check_visible = partition_cred_check_visible, 260173138Srwatson .mpo_cred_copy_label = partition_cred_copy_label, 261173138Srwatson .mpo_cred_destroy_label = partition_cred_destroy_label, 262173138Srwatson .mpo_cred_externalize_label = partition_cred_externalize_label, 263173138Srwatson .mpo_cred_init_label = partition_cred_init_label, 264173138Srwatson .mpo_cred_internalize_label = partition_cred_internalize_label, 265173138Srwatson .mpo_cred_relabel = partition_cred_relabel, 266172955Srwatson .mpo_proc_check_debug = partition_proc_check_debug, 267172955Srwatson .mpo_proc_check_sched = partition_proc_check_sched, 268172955Srwatson .mpo_proc_check_signal = partition_proc_check_signal, 269173138Srwatson .mpo_proc_create_init = partition_proc_create_init, 270173138Srwatson .mpo_proc_create_swapper = partition_proc_create_swapper, 271172955Srwatson .mpo_socket_check_visible = partition_socket_check_visible, 272172955Srwatson .mpo_vnode_check_exec = partition_vnode_check_exec, 273105828Srwatson}; 274105828Srwatson 275172955SrwatsonMAC_POLICY_SET(&partition_ops, mac_partition, "TrustedBSD MAC/Partition", 276112717Srwatson MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot); 277