xref: /freebsd/sys/security/mac/mac_pipe.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
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