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 437bc82500SRobert Watson #include "opt_mac.h" 44f9d0d524SRobert Watson 457bc82500SRobert Watson #include <sys/param.h> 4695fab37eSRobert Watson #include <sys/kernel.h> 4795fab37eSRobert Watson #include <sys/lock.h> 48b656366bSBruce Evans #include <sys/malloc.h> 495dba30f1SPoul-Henning Kamp #include <sys/module.h> 5095fab37eSRobert Watson #include <sys/mutex.h> 51f51e5803SRobert Watson #include <sys/sbuf.h> 522087a58cSRobert Watson #include <sys/sdt.h> 5395fab37eSRobert Watson #include <sys/systm.h> 5495fab37eSRobert Watson #include <sys/vnode.h> 5595fab37eSRobert Watson #include <sys/pipe.h> 5695fab37eSRobert Watson #include <sys/sysctl.h> 5795fab37eSRobert Watson 58aed55708SRobert Watson #include <security/mac/mac_framework.h> 5973275908SRobert Watson #include <security/mac/mac_internal.h> 600efd6615SRobert Watson #include <security/mac/mac_policy.h> 6195fab37eSRobert Watson 62eca8a663SRobert Watson struct label * 63eca8a663SRobert Watson mac_pipe_label_alloc(void) 64f7b951a8SRobert Watson { 65eca8a663SRobert Watson struct label *label; 66f7b951a8SRobert Watson 67eca8a663SRobert Watson label = mac_labelzone_alloc(M_WAITOK); 68fa765671SRobert Watson MAC_POLICY_PERFORM(pipe_init_label, label); 69eca8a663SRobert Watson return (label); 70f7b951a8SRobert Watson } 71f7b951a8SRobert Watson 7208bcdc58SRobert Watson void 7330d239bcSRobert Watson mac_pipe_init(struct pipepair *pp) 7408bcdc58SRobert Watson { 7508bcdc58SRobert Watson 766356dba0SRobert Watson if (mac_labeled & MPC_OBJECT_PIPE) 774795b82cSRobert Watson pp->pp_label = mac_pipe_label_alloc(); 786356dba0SRobert Watson else 796356dba0SRobert Watson pp->pp_label = NULL; 8008bcdc58SRobert Watson } 8108bcdc58SRobert Watson 822555374cSRobert Watson void 83eca8a663SRobert Watson mac_pipe_label_free(struct label *label) 84f7b951a8SRobert Watson { 85f7b951a8SRobert Watson 86fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_destroy_label, label); 87eca8a663SRobert Watson mac_labelzone_free(label); 88f7b951a8SRobert Watson } 89f7b951a8SRobert Watson 9087807196SRobert Watson void 9130d239bcSRobert Watson mac_pipe_destroy(struct pipepair *pp) 9208bcdc58SRobert Watson { 9308bcdc58SRobert Watson 946356dba0SRobert Watson if (pp->pp_label != NULL) { 954795b82cSRobert Watson mac_pipe_label_free(pp->pp_label); 964795b82cSRobert Watson pp->pp_label = NULL; 9787807196SRobert Watson } 986356dba0SRobert Watson } 9987807196SRobert Watson 1002555374cSRobert Watson void 10130d239bcSRobert Watson mac_pipe_copy_label(struct label *src, struct label *dest) 102f7b951a8SRobert Watson { 103f7b951a8SRobert Watson 104fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_copy_label, src, dest); 105f7b951a8SRobert Watson } 106f7b951a8SRobert Watson 10773275908SRobert Watson int 10830d239bcSRobert Watson mac_pipe_externalize_label(struct label *label, char *elements, 10983b7b0edSRobert Watson char *outbuf, size_t outbuflen) 110f7b951a8SRobert Watson { 111f7b951a8SRobert Watson int error; 112f7b951a8SRobert Watson 113fa765671SRobert Watson MAC_POLICY_EXTERNALIZE(pipe, label, elements, outbuf, outbuflen); 114f7b951a8SRobert Watson 115f7b951a8SRobert Watson return (error); 116f7b951a8SRobert Watson } 117f7b951a8SRobert Watson 11873275908SRobert Watson int 11930d239bcSRobert Watson mac_pipe_internalize_label(struct label *label, char *string) 120f7b951a8SRobert Watson { 121f7b951a8SRobert Watson int error; 122f7b951a8SRobert Watson 123fa765671SRobert Watson MAC_POLICY_INTERNALIZE(pipe, label, string); 124f7b951a8SRobert Watson 125f7b951a8SRobert Watson return (error); 126f7b951a8SRobert Watson } 127f7b951a8SRobert Watson 12895fab37eSRobert Watson void 12930d239bcSRobert Watson mac_pipe_create(struct ucred *cred, struct pipepair *pp) 13095fab37eSRobert Watson { 13195fab37eSRobert Watson 132fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_create, cred, pp, pp->pp_label); 13395fab37eSRobert Watson } 13495fab37eSRobert Watson 13595fab37eSRobert Watson static void 13630d239bcSRobert Watson mac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1374795b82cSRobert Watson struct label *newlabel) 13895fab37eSRobert Watson { 13995fab37eSRobert Watson 140fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_relabel, cred, pp, pp->pp_label, 141fa765671SRobert Watson 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 155fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_ioctl, cred, pp, pp->pp_label, 156fa765671SRobert Watson cmd, 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 166*89744405SMateusz Guzik mac_pipe_check_poll_impl(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 172fa765671SRobert Watson MAC_POLICY_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 188fa765671SRobert Watson MAC_POLICY_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 205fa765671SRobert Watson MAC_POLICY_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 222fa765671SRobert Watson MAC_POLICY_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 238fa765671SRobert Watson MAC_POLICY_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