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