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