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>
417bc82500SRobert Watson #include "opt_mac.h"
42f9d0d524SRobert Watson
437bc82500SRobert Watson #include <sys/param.h>
4495fab37eSRobert Watson #include <sys/kernel.h>
4595fab37eSRobert Watson #include <sys/lock.h>
46b656366bSBruce Evans #include <sys/malloc.h>
475dba30f1SPoul-Henning Kamp #include <sys/module.h>
4895fab37eSRobert Watson #include <sys/mutex.h>
49f51e5803SRobert Watson #include <sys/sbuf.h>
502087a58cSRobert Watson #include <sys/sdt.h>
5195fab37eSRobert Watson #include <sys/systm.h>
5295fab37eSRobert Watson #include <sys/vnode.h>
5395fab37eSRobert Watson #include <sys/pipe.h>
5495fab37eSRobert Watson #include <sys/sysctl.h>
5595fab37eSRobert Watson
56aed55708SRobert Watson #include <security/mac/mac_framework.h>
5773275908SRobert Watson #include <security/mac/mac_internal.h>
580efd6615SRobert Watson #include <security/mac/mac_policy.h>
5995fab37eSRobert Watson
60eca8a663SRobert Watson struct label *
mac_pipe_label_alloc(void)61eca8a663SRobert Watson mac_pipe_label_alloc(void)
62f7b951a8SRobert Watson {
63eca8a663SRobert Watson struct label *label;
64f7b951a8SRobert Watson
65eca8a663SRobert Watson label = mac_labelzone_alloc(M_WAITOK);
66fa765671SRobert Watson MAC_POLICY_PERFORM(pipe_init_label, label);
67eca8a663SRobert Watson return (label);
68f7b951a8SRobert Watson }
69f7b951a8SRobert Watson
7008bcdc58SRobert Watson void
mac_pipe_init(struct pipepair * pp)7130d239bcSRobert Watson mac_pipe_init(struct pipepair *pp)
7208bcdc58SRobert Watson {
7308bcdc58SRobert Watson
746356dba0SRobert Watson if (mac_labeled & MPC_OBJECT_PIPE)
754795b82cSRobert Watson pp->pp_label = mac_pipe_label_alloc();
766356dba0SRobert Watson else
776356dba0SRobert Watson pp->pp_label = NULL;
7808bcdc58SRobert Watson }
7908bcdc58SRobert Watson
802555374cSRobert Watson void
mac_pipe_label_free(struct label * label)81eca8a663SRobert Watson mac_pipe_label_free(struct label *label)
82f7b951a8SRobert Watson {
83f7b951a8SRobert Watson
84fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_destroy_label, label);
85eca8a663SRobert Watson mac_labelzone_free(label);
86f7b951a8SRobert Watson }
87f7b951a8SRobert Watson
8887807196SRobert Watson void
mac_pipe_destroy(struct pipepair * pp)8930d239bcSRobert Watson mac_pipe_destroy(struct pipepair *pp)
9008bcdc58SRobert Watson {
9108bcdc58SRobert Watson
926356dba0SRobert Watson if (pp->pp_label != NULL) {
934795b82cSRobert Watson mac_pipe_label_free(pp->pp_label);
944795b82cSRobert Watson pp->pp_label = NULL;
9587807196SRobert Watson }
966356dba0SRobert Watson }
9787807196SRobert Watson
982555374cSRobert Watson void
mac_pipe_copy_label(struct label * src,struct label * dest)9930d239bcSRobert Watson mac_pipe_copy_label(struct label *src, struct label *dest)
100f7b951a8SRobert Watson {
101f7b951a8SRobert Watson
102fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_copy_label, src, dest);
103f7b951a8SRobert Watson }
104f7b951a8SRobert Watson
10573275908SRobert Watson int
mac_pipe_externalize_label(struct label * label,char * elements,char * outbuf,size_t outbuflen)10630d239bcSRobert Watson mac_pipe_externalize_label(struct label *label, char *elements,
10783b7b0edSRobert Watson char *outbuf, size_t outbuflen)
108f7b951a8SRobert Watson {
109f7b951a8SRobert Watson int error;
110f7b951a8SRobert Watson
111fa765671SRobert Watson MAC_POLICY_EXTERNALIZE(pipe, label, elements, outbuf, outbuflen);
112f7b951a8SRobert Watson
113f7b951a8SRobert Watson return (error);
114f7b951a8SRobert Watson }
115f7b951a8SRobert Watson
11673275908SRobert Watson int
mac_pipe_internalize_label(struct label * label,char * string)11730d239bcSRobert Watson mac_pipe_internalize_label(struct label *label, char *string)
118f7b951a8SRobert Watson {
119f7b951a8SRobert Watson int error;
120f7b951a8SRobert Watson
121fa765671SRobert Watson MAC_POLICY_INTERNALIZE(pipe, label, string);
122f7b951a8SRobert Watson
123f7b951a8SRobert Watson return (error);
124f7b951a8SRobert Watson }
125f7b951a8SRobert Watson
12695fab37eSRobert Watson void
mac_pipe_create(struct ucred * cred,struct pipepair * pp)12730d239bcSRobert Watson mac_pipe_create(struct ucred *cred, struct pipepair *pp)
12895fab37eSRobert Watson {
12995fab37eSRobert Watson
130fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_create, cred, pp, pp->pp_label);
13195fab37eSRobert Watson }
13295fab37eSRobert Watson
13395fab37eSRobert Watson static void
mac_pipe_relabel(struct ucred * cred,struct pipepair * pp,struct label * newlabel)13430d239bcSRobert Watson mac_pipe_relabel(struct ucred *cred, struct pipepair *pp,
1354795b82cSRobert Watson struct label *newlabel)
13695fab37eSRobert Watson {
13795fab37eSRobert Watson
138fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(pipe_relabel, cred, pp, pp->pp_label,
139fa765671SRobert Watson newlabel);
14095fab37eSRobert Watson }
14195fab37eSRobert Watson
1422087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE4(pipe_check_ioctl, "struct ucred *",
1432087a58cSRobert Watson "struct pipepair *", "unsigned long", "void *");
1442087a58cSRobert Watson
14595fab37eSRobert Watson int
mac_pipe_check_ioctl(struct ucred * cred,struct pipepair * pp,unsigned long cmd,void * data)14630d239bcSRobert Watson mac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp,
1474795b82cSRobert Watson unsigned long cmd, void *data)
14895fab37eSRobert Watson {
14995fab37eSRobert Watson int error;
15095fab37eSRobert Watson
1514795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
1521aa37f53SRobert Watson
153fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_ioctl, cred, pp, pp->pp_label,
154fa765671SRobert Watson cmd, data);
1552087a58cSRobert Watson MAC_CHECK_PROBE4(pipe_check_ioctl, error, cred, pp, cmd, data);
15695fab37eSRobert Watson
15795fab37eSRobert Watson return (error);
15895fab37eSRobert Watson }
15995fab37eSRobert Watson
1602087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_poll, "struct ucred *",
1612087a58cSRobert Watson "struct pipepair *");
1622087a58cSRobert Watson
16395fab37eSRobert Watson int
mac_pipe_check_poll_impl(struct ucred * cred,struct pipepair * pp)16489744405SMateusz Guzik mac_pipe_check_poll_impl(struct ucred *cred, struct pipepair *pp)
16595fab37eSRobert Watson {
16695fab37eSRobert Watson int error;
16795fab37eSRobert Watson
1684795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
1691aa37f53SRobert Watson
170fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_poll, cred, pp, pp->pp_label);
1712087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_poll, error, cred, pp);
172c024c3eeSRobert Watson
173c024c3eeSRobert Watson return (error);
174c024c3eeSRobert Watson }
175c024c3eeSRobert Watson
1762087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_read, "struct ucred *",
1772087a58cSRobert Watson "struct pipepair *");
1782087a58cSRobert Watson
179c024c3eeSRobert Watson int
mac_pipe_check_read_impl(struct ucred * cred,struct pipepair * pp)180*60dae3b8SMateusz Guzik mac_pipe_check_read_impl(struct ucred *cred, struct pipepair *pp)
181c024c3eeSRobert Watson {
182c024c3eeSRobert Watson int error;
183c024c3eeSRobert Watson
1844795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
1851aa37f53SRobert Watson
186fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_read, cred, pp, pp->pp_label);
1872087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_read, error, cred, pp);
18895fab37eSRobert Watson
18995fab37eSRobert Watson return (error);
19095fab37eSRobert Watson }
19195fab37eSRobert Watson
1922087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE3(pipe_check_relabel, "struct ucred *",
1932087a58cSRobert Watson "struct pipepair *", "struct label *");
1942087a58cSRobert Watson
19595fab37eSRobert Watson static int
mac_pipe_check_relabel(struct ucred * cred,struct pipepair * pp,struct label * newlabel)19630d239bcSRobert Watson mac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp,
19795fab37eSRobert Watson struct label *newlabel)
19895fab37eSRobert Watson {
19995fab37eSRobert Watson int error;
20095fab37eSRobert Watson
2014795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
2021aa37f53SRobert Watson
203fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_relabel, cred, pp, pp->pp_label,
20440202729SRobert Watson newlabel);
2052087a58cSRobert Watson MAC_CHECK_PROBE3(pipe_check_relabel, error, cred, pp, newlabel);
20695fab37eSRobert Watson
20795fab37eSRobert Watson return (error);
20895fab37eSRobert Watson }
20995fab37eSRobert Watson
2102087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_stat, "struct ucred *",
2112087a58cSRobert Watson "struct pipepair *");
2122087a58cSRobert Watson
21395fab37eSRobert Watson int
mac_pipe_check_stat(struct ucred * cred,struct pipepair * pp)21430d239bcSRobert Watson mac_pipe_check_stat(struct ucred *cred, struct pipepair *pp)
215c024c3eeSRobert Watson {
216c024c3eeSRobert Watson int error;
217c024c3eeSRobert Watson
2184795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
2191aa37f53SRobert Watson
220fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_stat, cred, pp, pp->pp_label);
2212087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_stat, error, cred, pp);
222c024c3eeSRobert Watson
223c024c3eeSRobert Watson return (error);
224c024c3eeSRobert Watson }
225c024c3eeSRobert Watson
2262087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(pipe_check_write, "struct ucred *",
2272087a58cSRobert Watson "struct pipepair *");
2282087a58cSRobert Watson
229c024c3eeSRobert Watson int
mac_pipe_check_write(struct ucred * cred,struct pipepair * pp)23030d239bcSRobert Watson mac_pipe_check_write(struct ucred *cred, struct pipepair *pp)
231c024c3eeSRobert Watson {
232c024c3eeSRobert Watson int error;
233c024c3eeSRobert Watson
2344795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
2351aa37f53SRobert Watson
236fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(pipe_check_write, cred, pp, pp->pp_label);
2372087a58cSRobert Watson MAC_CHECK_PROBE2(pipe_check_write, error, cred, pp);
238c024c3eeSRobert Watson
239c024c3eeSRobert Watson return (error);
240c024c3eeSRobert Watson }
241c024c3eeSRobert Watson
242c024c3eeSRobert Watson int
mac_pipe_label_set(struct ucred * cred,struct pipepair * pp,struct label * label)2434795b82cSRobert Watson mac_pipe_label_set(struct ucred *cred, struct pipepair *pp,
2444795b82cSRobert Watson struct label *label)
24595fab37eSRobert Watson {
24695fab37eSRobert Watson int error;
24795fab37eSRobert Watson
2484795b82cSRobert Watson mtx_assert(&pp->pp_mtx, MA_OWNED);
2491aa37f53SRobert Watson
25030d239bcSRobert Watson error = mac_pipe_check_relabel(cred, pp, label);
25195fab37eSRobert Watson if (error)
25295fab37eSRobert Watson return (error);
25395fab37eSRobert Watson
25430d239bcSRobert Watson mac_pipe_relabel(cred, pp, label);
25595fab37eSRobert Watson
25695fab37eSRobert Watson return (0);
25795fab37eSRobert Watson }
258