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); 6930d239bcSRobert Watson MAC_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 8740202729SRobert Watson MAC_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 10540202729SRobert Watson MAC_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 114da77b2faSRobert Watson MAC_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 124da77b2faSRobert Watson MAC_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 13340202729SRobert Watson MAC_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 14140202729SRobert Watson MAC_PERFORM_NOSLEEP(pipe_relabel, cred, pp, pp->pp_label, newlabel); 14295fab37eSRobert Watson } 14395fab37eSRobert Watson 1442087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE4(pipe_check_ioctl, "struct ucred *", 1452087a58cSRobert Watson "struct pipepair *", "unsigned long", "void *"); 1462087a58cSRobert Watson 14795fab37eSRobert Watson int 14830d239bcSRobert Watson mac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1494795b82cSRobert Watson unsigned long cmd, void *data) 15095fab37eSRobert Watson { 15195fab37eSRobert Watson int error; 15295fab37eSRobert Watson 1534795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1541aa37f53SRobert Watson 15540202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_ioctl, cred, pp, pp->pp_label, cmd, 15640202729SRobert Watson data); 1572087a58cSRobert Watson MAC_CHECK_PROBE4(pipe_check_ioctl, error, cred, pp, cmd, data); 15895fab37eSRobert Watson 15995fab37eSRobert Watson return (error); 16095fab37eSRobert Watson } 16195fab37eSRobert Watson 1622087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_poll, "struct ucred *", 1632087a58cSRobert Watson "struct pipepair *"); 1642087a58cSRobert Watson 16595fab37eSRobert Watson int 16630d239bcSRobert Watson mac_pipe_check_poll(struct ucred *cred, struct pipepair *pp) 16795fab37eSRobert Watson { 16895fab37eSRobert Watson int error; 16995fab37eSRobert Watson 1704795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1711aa37f53SRobert Watson 17240202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_poll, cred, pp, pp->pp_label); 1732087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_poll, error, cred, pp); 174c024c3eeSRobert Watson 175c024c3eeSRobert Watson return (error); 176c024c3eeSRobert Watson } 177c024c3eeSRobert Watson 1782087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_read, "struct ucred *", 1792087a58cSRobert Watson "struct pipepair *"); 1802087a58cSRobert Watson 181c024c3eeSRobert Watson int 18230d239bcSRobert Watson mac_pipe_check_read(struct ucred *cred, struct pipepair *pp) 183c024c3eeSRobert Watson { 184c024c3eeSRobert Watson int error; 185c024c3eeSRobert Watson 1864795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 1871aa37f53SRobert Watson 18840202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_read, cred, pp, pp->pp_label); 1892087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_read, error, cred, pp); 19095fab37eSRobert Watson 19195fab37eSRobert Watson return (error); 19295fab37eSRobert Watson } 19395fab37eSRobert Watson 1942087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(pipe_check_relabel, "struct ucred *", 1952087a58cSRobert Watson "struct pipepair *", "struct label *"); 1962087a58cSRobert Watson 19795fab37eSRobert Watson static int 19830d239bcSRobert Watson mac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 19995fab37eSRobert Watson struct label *newlabel) 20095fab37eSRobert Watson { 20195fab37eSRobert Watson int error; 20295fab37eSRobert Watson 2034795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2041aa37f53SRobert Watson 20540202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_relabel, cred, pp, pp->pp_label, 20640202729SRobert Watson newlabel); 2072087a58cSRobert Watson MAC_CHECK_PROBE3(pipe_check_relabel, error, cred, pp, newlabel); 20895fab37eSRobert Watson 20995fab37eSRobert Watson return (error); 21095fab37eSRobert Watson } 21195fab37eSRobert Watson 2122087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_stat, "struct ucred *", 2132087a58cSRobert Watson "struct pipepair *"); 2142087a58cSRobert Watson 21595fab37eSRobert Watson int 21630d239bcSRobert Watson mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp) 217c024c3eeSRobert Watson { 218c024c3eeSRobert Watson int error; 219c024c3eeSRobert Watson 2204795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2211aa37f53SRobert Watson 22240202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_stat, cred, pp, pp->pp_label); 2232087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_stat, error, cred, pp); 224c024c3eeSRobert Watson 225c024c3eeSRobert Watson return (error); 226c024c3eeSRobert Watson } 227c024c3eeSRobert Watson 2282087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_write, "struct ucred *", 2292087a58cSRobert Watson "struct pipepair *"); 2302087a58cSRobert Watson 231c024c3eeSRobert Watson int 23230d239bcSRobert Watson mac_pipe_check_write(struct ucred *cred, struct pipepair *pp) 233c024c3eeSRobert Watson { 234c024c3eeSRobert Watson int error; 235c024c3eeSRobert Watson 2364795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2371aa37f53SRobert Watson 23840202729SRobert Watson MAC_CHECK_NOSLEEP(pipe_check_write, cred, pp, pp->pp_label); 2392087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_write, error, cred, pp); 240c024c3eeSRobert Watson 241c024c3eeSRobert Watson return (error); 242c024c3eeSRobert Watson } 243c024c3eeSRobert Watson 244c024c3eeSRobert Watson int 2454795b82cSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipepair *pp, 2464795b82cSRobert Watson struct label *label) 24795fab37eSRobert Watson { 24895fab37eSRobert Watson int error; 24995fab37eSRobert Watson 2504795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED); 2511aa37f53SRobert Watson 25230d239bcSRobert Watson error = mac_pipe_check_relabel(cred, pp, label); 25395fab37eSRobert Watson if (error) 25495fab37eSRobert Watson return (error); 25595fab37eSRobert Watson 25630d239bcSRobert Watson mac_pipe_relabel(cred, pp, label); 25795fab37eSRobert Watson 25895fab37eSRobert Watson return (0); 25995fab37eSRobert Watson } 260