17bc82500SRobert Watson /*- 226ae2b86SRobert Watson * Copyright (c) 2002-2003 Networks Associates Technology, Inc. 330d239bcSRobert Watson * Copyright (c) 2006 SPARTA, Inc. 42087a58cSRobert Watson * Copyright (c) 2009 Robert N. M. Watson 57bc82500SRobert Watson * All rights reserved. 67bc82500SRobert Watson * 76201265bSRobert Watson * This software was developed for the FreeBSD Project in part by Network 86201265bSRobert Watson * Associates Laboratories, the Security Research Division of Network 96201265bSRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 106201265bSRobert Watson * as part of the DARPA CHATS research program. 117bc82500SRobert Watson * 1230d239bcSRobert Watson * This software was enhanced by SPARTA ISSO under SPAWAR contract 1330d239bcSRobert Watson * N66001-04-C-6019 ("SEFOS"). 1430d239bcSRobert Watson * 152087a58cSRobert Watson * This software was developed at the University of Cambridge Computer 162087a58cSRobert Watson * Laboratory with support from a grant from Google, Inc. 172087a58cSRobert Watson * 187bc82500SRobert Watson * Redistribution and use in source and binary forms, with or without 197bc82500SRobert Watson * modification, are permitted provided that the following conditions 207bc82500SRobert Watson * are met: 217bc82500SRobert Watson * 1. Redistributions of source code must retain the above copyright 227bc82500SRobert Watson * notice, this list of conditions and the following disclaimer. 237bc82500SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 247bc82500SRobert Watson * notice, this list of conditions and the following disclaimer in the 257bc82500SRobert Watson * documentation and/or other materials provided with the distribution. 267bc82500SRobert Watson * 277bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 287bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 297bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 307bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 317bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 327bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 337bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 347bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 357bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 367bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 377bc82500SRobert Watson * SUCH DAMAGE. 387bc82500SRobert Watson */ 39677b542eSDavid E. O'Brien 40677b542eSDavid E. O'Brien #include <sys/cdefs.h> 41677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 42677b542eSDavid E. O'Brien 432087a58cSRobert Watson #include "opt_kdtrace.h" 447bc82500SRobert Watson #include "opt_mac.h" 45f9d0d524SRobert Watson 467bc82500SRobert Watson #include <sys/param.h> 4795fab37eSRobert Watson #include <sys/kernel.h> 4895fab37eSRobert Watson #include <sys/lock.h> 49b656366bSBruce Evans #include <sys/malloc.h> 505dba30f1SPoul-Henning Kamp #include <sys/module.h> 5195fab37eSRobert Watson #include <sys/mutex.h> 52f51e5803SRobert Watson #include <sys/sbuf.h> 532087a58cSRobert Watson #include <sys/sdt.h> 5495fab37eSRobert Watson #include <sys/systm.h> 5595fab37eSRobert Watson #include <sys/vnode.h> 5695fab37eSRobert Watson #include <sys/pipe.h> 5795fab37eSRobert Watson #include <sys/sysctl.h> 5895fab37eSRobert Watson 59aed55708SRobert Watson #include <security/mac/mac_framework.h> 6073275908SRobert Watson #include <security/mac/mac_internal.h> 610efd6615SRobert Watson #include <security/mac/mac_policy.h> 6295fab37eSRobert Watson 63eca8a663SRobert Watson struct label * 64eca8a663SRobert Watson mac_pipe_label_alloc(void) 65f7b951a8SRobert Watson { 66eca8a663SRobert Watson struct label *label; 67f7b951a8SRobert Watson 68eca8a663SRobert Watson label = mac_labelzone_alloc(M_WAITOK); 69fa765671SRobert Watson MAC_POLICY_PERFORM(pipe_init_label, label); 70eca8a663SRobert Watson return (label); 71f7b951a8SRobert Watson } 72f7b951a8SRobert Watson 7308bcdc58SRobert Watson void 7430d239bcSRobert Watson mac_pipe_init(struct pipepair *pp) 7508bcdc58SRobert Watson { 7608bcdc58SRobert Watson 776356dba0SRobert Watson if (mac_labeled & MPC_OBJECT_PIPE) 784795b82cSRobert Watson pp->pp_label = mac_pipe_label_alloc(); 796356dba0SRobert Watson else 806356dba0SRobert Watson pp->pp_label = NULL; 8108bcdc58SRobert Watson } 8208bcdc58SRobert Watson 832555374cSRobert Watson void 84eca8a663SRobert Watson mac_pipe_label_free(struct label *label) 85f7b951a8SRobert Watson { 86f7b951a8SRobert Watson 87fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_destroy_label, label); 88eca8a663SRobert Watson mac_labelzone_free(label); 89f7b951a8SRobert Watson } 90f7b951a8SRobert Watson 9187807196SRobert Watson void 9230d239bcSRobert Watson mac_pipe_destroy(struct pipepair *pp) 9308bcdc58SRobert Watson { 9408bcdc58SRobert Watson 956356dba0SRobert Watson if (pp->pp_label != NULL) { 964795b82cSRobert Watson mac_pipe_label_free(pp->pp_label); 974795b82cSRobert Watson pp->pp_label = NULL; 9887807196SRobert Watson } 996356dba0SRobert Watson } 10087807196SRobert Watson 1012555374cSRobert Watson void 10230d239bcSRobert Watson mac_pipe_copy_label(struct label *src, struct label *dest) 103f7b951a8SRobert Watson { 104f7b951a8SRobert Watson 105fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_copy_label, src, dest); 106f7b951a8SRobert Watson } 107f7b951a8SRobert Watson 10873275908SRobert Watson int 10930d239bcSRobert Watson mac_pipe_externalize_label(struct label *label, char *elements, 11083b7b0edSRobert Watson char *outbuf, size_t outbuflen) 111f7b951a8SRobert Watson { 112f7b951a8SRobert Watson int error; 113f7b951a8SRobert Watson 114fa765671SRobert Watson MAC_POLICY_EXTERNALIZE(pipe, label, elements, outbuf, outbuflen); 115f7b951a8SRobert Watson 116f7b951a8SRobert Watson return (error); 117f7b951a8SRobert Watson } 118f7b951a8SRobert Watson 11973275908SRobert Watson int 12030d239bcSRobert Watson mac_pipe_internalize_label(struct label *label, char *string) 121f7b951a8SRobert Watson { 122f7b951a8SRobert Watson int error; 123f7b951a8SRobert Watson 124fa765671SRobert Watson MAC_POLICY_INTERNALIZE(pipe, label, string); 125f7b951a8SRobert Watson 126f7b951a8SRobert Watson return (error); 127f7b951a8SRobert Watson } 128f7b951a8SRobert Watson 12995fab37eSRobert Watson void 13030d239bcSRobert Watson mac_pipe_create(struct ucred *cred, struct pipepair *pp) 13195fab37eSRobert Watson { 13295fab37eSRobert Watson 133fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_create, cred, pp, pp->pp_label); 13495fab37eSRobert Watson } 13595fab37eSRobert Watson 13695fab37eSRobert Watson static void 13730d239bcSRobert Watson mac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1384795b82cSRobert Watson struct label *newlabel) 13995fab37eSRobert Watson { 14095fab37eSRobert Watson 141fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_relabel, cred, pp, pp->pp_label, 142fa765671SRobert Watson newlabel); 14395fab37eSRobert Watson } 14495fab37eSRobert Watson 1452087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE4(pipe_check_ioctl, "struct ucred *", 1462087a58cSRobert Watson "struct pipepair *", "unsigned long", "void *"); 1472087a58cSRobert Watson 14895fab37eSRobert Watson int 14930d239bcSRobert Watson mac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1504795b82cSRobert Watson unsigned long cmd, void *data) 15195fab37eSRobert Watson { 15295fab37eSRobert Watson int error; 15395fab37eSRobert Watson 1544795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1551aa37f53SRobert Watson 156fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_ioctl, cred, pp, pp->pp_label, 157fa765671SRobert Watson cmd, data); 1582087a58cSRobert Watson MAC_CHECK_PROBE4(pipe_check_ioctl, error, cred, pp, cmd, data); 15995fab37eSRobert Watson 16095fab37eSRobert Watson return (error); 16195fab37eSRobert Watson } 16295fab37eSRobert Watson 1632087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_poll, "struct ucred *", 1642087a58cSRobert Watson "struct pipepair *"); 1652087a58cSRobert Watson 16695fab37eSRobert Watson int 16730d239bcSRobert Watson mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp) 16895fab37eSRobert Watson { 16995fab37eSRobert Watson int error; 17095fab37eSRobert Watson 1714795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1721aa37f53SRobert Watson 173fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_poll, cred, pp, pp->pp_label); 1742087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_poll, error, cred, pp); 175c024c3eeSRobert Watson 176c024c3eeSRobert Watson return (error); 177c024c3eeSRobert Watson } 178c024c3eeSRobert Watson 1792087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_read, "struct ucred *", 1802087a58cSRobert Watson "struct pipepair *"); 1812087a58cSRobert Watson 182c024c3eeSRobert Watson int 18330d239bcSRobert Watson mac_pipe_check_read(struct ucred *cred, struct pipepair *pp) 184c024c3eeSRobert Watson { 185c024c3eeSRobert Watson int error; 186c024c3eeSRobert Watson 1874795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1881aa37f53SRobert Watson 189fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_read, cred, pp, pp->pp_label); 1902087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_read, error, cred, pp); 19195fab37eSRobert Watson 19295fab37eSRobert Watson return (error); 19395fab37eSRobert Watson } 19495fab37eSRobert Watson 1952087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(pipe_check_relabel, "struct ucred *", 1962087a58cSRobert Watson "struct pipepair *", "struct label *"); 1972087a58cSRobert Watson 19895fab37eSRobert Watson static int 19930d239bcSRobert Watson mac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 20095fab37eSRobert Watson struct label *newlabel) 20195fab37eSRobert Watson { 20295fab37eSRobert Watson int error; 20395fab37eSRobert Watson 2044795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2051aa37f53SRobert Watson 206fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_relabel, cred, pp, pp->pp_label, 20740202729SRobert Watson newlabel); 2082087a58cSRobert Watson MAC_CHECK_PROBE3(pipe_check_relabel, error, cred, pp, newlabel); 20995fab37eSRobert Watson 21095fab37eSRobert Watson return (error); 21195fab37eSRobert Watson } 21295fab37eSRobert Watson 2132087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_stat, "struct ucred *", 2142087a58cSRobert Watson "struct pipepair *"); 2152087a58cSRobert Watson 21695fab37eSRobert Watson int 21730d239bcSRobert Watson mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp) 218c024c3eeSRobert Watson { 219c024c3eeSRobert Watson int error; 220c024c3eeSRobert Watson 2214795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2221aa37f53SRobert Watson 223fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_stat, cred, pp, pp->pp_label); 2242087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_stat, error, cred, pp); 225c024c3eeSRobert Watson 226c024c3eeSRobert Watson return (error); 227c024c3eeSRobert Watson } 228c024c3eeSRobert Watson 2292087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_write, "struct ucred *", 2302087a58cSRobert Watson "struct pipepair *"); 2312087a58cSRobert Watson 232c024c3eeSRobert Watson int 23330d239bcSRobert Watson mac_pipe_check_write(struct ucred *cred, struct pipepair *pp) 234c024c3eeSRobert Watson { 235c024c3eeSRobert Watson int error; 236c024c3eeSRobert Watson 2374795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2381aa37f53SRobert Watson 239fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_write, cred, pp, pp->pp_label); 2402087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_write, error, cred, pp); 241c024c3eeSRobert Watson 242c024c3eeSRobert Watson return (error); 243c024c3eeSRobert Watson } 244c024c3eeSRobert Watson 245c024c3eeSRobert Watson int 2464795b82cSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipepair *pp, 2474795b82cSRobert Watson struct label *label) 24895fab37eSRobert Watson { 24995fab37eSRobert Watson int error; 25095fab37eSRobert Watson 2514795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2521aa37f53SRobert Watson 25330d239bcSRobert Watson error = mac_pipe_check_relabel(cred, pp, label); 25495fab37eSRobert Watson if (error) 25595fab37eSRobert Watson return (error); 25695fab37eSRobert Watson 25730d239bcSRobert Watson mac_pipe_relabel(cred, pp, label); 25895fab37eSRobert Watson 25995fab37eSRobert Watson return (0); 26095fab37eSRobert Watson } 261