xref: /freebsd/sys/security/mac_ifoff/mac_ifoff.c (revision db33c6f3ae9d1231087710068ee4ea5398aacca7)
1d8a7b7a3SRobert Watson /*-
27405fcc3SRobert Watson  * Copyright (c) 1999-2002, 2007 Robert N. M. Watson
3f6a41092SRobert Watson  * Copyright (c) 2001-2002 Networks Associates Technology, Inc.
430d239bcSRobert Watson  * Copyright (c) 2006 SPARTA, Inc.
5d8a7b7a3SRobert Watson  * All rights reserved.
6d8a7b7a3SRobert Watson  *
7d8a7b7a3SRobert Watson  * This software was developed by Robert Watson for the TrustedBSD Project.
8d8a7b7a3SRobert Watson  *
9dc858fcaSRobert Watson  * This software was developed for the FreeBSD Project in part by Network
10dc858fcaSRobert Watson  * Associates Laboratories, the Security Research Division of Network
11dc858fcaSRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
12dc858fcaSRobert Watson  * as part of the DARPA CHATS research program.
13d8a7b7a3SRobert Watson  *
1430d239bcSRobert Watson  * This software was enhanced by SPARTA ISSO under SPAWAR contract
1530d239bcSRobert Watson  * N66001-04-C-6019 ("SEFOS").
1630d239bcSRobert Watson  *
17d8a7b7a3SRobert Watson  * Redistribution and use in source and binary forms, with or without
18d8a7b7a3SRobert Watson  * modification, are permitted provided that the following conditions
19d8a7b7a3SRobert Watson  * are met:
20d8a7b7a3SRobert Watson  * 1. Redistributions of source code must retain the above copyright
21d8a7b7a3SRobert Watson  *    notice, this list of conditions and the following disclaimer.
22d8a7b7a3SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
23d8a7b7a3SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
24d8a7b7a3SRobert Watson  *    documentation and/or other materials provided with the distribution.
25d8a7b7a3SRobert Watson  *
26d8a7b7a3SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
27d8a7b7a3SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28d8a7b7a3SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29d8a7b7a3SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30d8a7b7a3SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31d8a7b7a3SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32d8a7b7a3SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33d8a7b7a3SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34d8a7b7a3SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35d8a7b7a3SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36d8a7b7a3SRobert Watson  * SUCH DAMAGE.
37d8a7b7a3SRobert Watson  */
38d8a7b7a3SRobert Watson 
39d8a7b7a3SRobert Watson /*
40d8a7b7a3SRobert Watson  * Developed by the TrustedBSD Project.
413f1a7a90SRobert Watson  *
42d8a7b7a3SRobert Watson  * Limit access to interfaces until they are specifically administratively
43d8a7b7a3SRobert Watson  * enabled.  Prevents protocol stack-driven packet leakage in unsafe
44d8a7b7a3SRobert Watson  * environments.
45d8a7b7a3SRobert Watson  */
46d8a7b7a3SRobert Watson 
47d8a7b7a3SRobert Watson #include <sys/param.h>
48d8a7b7a3SRobert Watson #include <sys/kernel.h>
497405fcc3SRobert Watson #include <sys/module.h>
5076039bc8SGleb Smirnoff #include <sys/mbuf.h>
51d8a7b7a3SRobert Watson #include <sys/socket.h>
52d8a7b7a3SRobert Watson #include <sys/sysctl.h>
53d8a7b7a3SRobert Watson 
5476039bc8SGleb Smirnoff #include <net/if.h>
5576039bc8SGleb Smirnoff #include <net/if_var.h>
56d8a7b7a3SRobert Watson #include <net/if_types.h>
5776039bc8SGleb Smirnoff #include <net/bpfdesc.h>
58d8a7b7a3SRobert Watson 
590efd6615SRobert Watson #include <security/mac/mac_policy.h>
60d8a7b7a3SRobert Watson 
617029da5cSPawel Biernacki static SYSCTL_NODE(_security_mac, OID_AUTO, ifoff,
627029da5cSPawel Biernacki     CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
63d8a7b7a3SRobert Watson     "TrustedBSD mac_ifoff policy controls");
64d8a7b7a3SRobert Watson 
653f1a7a90SRobert Watson static int	ifoff_enabled = 1;
66af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_ifoff, OID_AUTO, enabled, CTLFLAG_RWTUN,
673f1a7a90SRobert Watson     &ifoff_enabled, 0, "Enforce ifoff policy");
68d8a7b7a3SRobert Watson 
693f1a7a90SRobert Watson static int	ifoff_lo_enabled = 1;
70af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_ifoff, OID_AUTO, lo_enabled, CTLFLAG_RWTUN,
713f1a7a90SRobert Watson     &ifoff_lo_enabled, 0, "Enable loopback interfaces");
72d8a7b7a3SRobert Watson 
733f1a7a90SRobert Watson static int	ifoff_other_enabled = 0;
74af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_ifoff, OID_AUTO, other_enabled, CTLFLAG_RWTUN,
753f1a7a90SRobert Watson     &ifoff_other_enabled, 0, "Enable other interfaces");
76d8a7b7a3SRobert Watson 
773f1a7a90SRobert Watson static int	ifoff_bpfrecv_enabled = 0;
78af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_ifoff, OID_AUTO, bpfrecv_enabled, CTLFLAG_RWTUN,
793f1a7a90SRobert Watson     &ifoff_bpfrecv_enabled, 0, "Enable BPF reception even when interface "
80d8a7b7a3SRobert Watson     "is disabled");
81d8a7b7a3SRobert Watson 
82d8a7b7a3SRobert Watson static int
ifnet_check_outgoing(struct ifnet * ifp)8330d239bcSRobert Watson ifnet_check_outgoing(struct ifnet *ifp)
84d8a7b7a3SRobert Watson {
85d8a7b7a3SRobert Watson 
863f1a7a90SRobert Watson 	if (!ifoff_enabled)
87d8a7b7a3SRobert Watson 		return (0);
88d8a7b7a3SRobert Watson 
89*30af2c13SJustin Hibbits 	if (ifoff_lo_enabled && if_gettype(ifp) == IFT_LOOP)
90d8a7b7a3SRobert Watson 		return (0);
91d8a7b7a3SRobert Watson 
92*30af2c13SJustin Hibbits 	if (ifoff_other_enabled && if_gettype(ifp) != IFT_LOOP)
93d8a7b7a3SRobert Watson 		return (0);
94d8a7b7a3SRobert Watson 
95d8a7b7a3SRobert Watson 	return (EPERM);
96d8a7b7a3SRobert Watson }
97d8a7b7a3SRobert Watson 
98d8a7b7a3SRobert Watson static int
ifnet_check_incoming(struct ifnet * ifp,int viabpf)9930d239bcSRobert Watson ifnet_check_incoming(struct ifnet *ifp, int viabpf)
100d8a7b7a3SRobert Watson {
1013f1a7a90SRobert Watson 	if (!ifoff_enabled)
102d8a7b7a3SRobert Watson 		return (0);
103d8a7b7a3SRobert Watson 
104*30af2c13SJustin Hibbits 	if (ifoff_lo_enabled && if_gettype(ifp) == IFT_LOOP)
105d8a7b7a3SRobert Watson 		return (0);
106d8a7b7a3SRobert Watson 
107*30af2c13SJustin Hibbits 	if (ifoff_other_enabled && if_gettype(ifp) != IFT_LOOP)
108d8a7b7a3SRobert Watson 		return (0);
109d8a7b7a3SRobert Watson 
1103f1a7a90SRobert Watson 	if (viabpf && ifoff_bpfrecv_enabled)
111d8a7b7a3SRobert Watson 		return (0);
112d8a7b7a3SRobert Watson 
113d8a7b7a3SRobert Watson 	return (EPERM);
114d8a7b7a3SRobert Watson }
115d8a7b7a3SRobert Watson 
116eb320b0eSRobert Watson /*
117eb320b0eSRobert Watson  * Object-specific entry point implementations are sorted alphabetically by
118eb320b0eSRobert Watson  * object type and then by operation.
119eb320b0eSRobert Watson  */
120d8a7b7a3SRobert Watson static int
ifoff_bpfdesc_check_receive(struct bpf_d * d,struct label * dlabel,struct ifnet * ifp,struct label * ifplabel)1213f1a7a90SRobert Watson ifoff_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel,
12278007886SRobert Watson     struct ifnet *ifp, struct label *ifplabel)
123d8a7b7a3SRobert Watson {
124d8a7b7a3SRobert Watson 
12530d239bcSRobert Watson 	return (ifnet_check_incoming(ifp, 1));
126d8a7b7a3SRobert Watson }
127d8a7b7a3SRobert Watson 
128d8a7b7a3SRobert Watson static int
ifoff_ifnet_check_transmit(struct ifnet * ifp,struct label * ifplabel,struct mbuf * m,struct label * mlabel)1293f1a7a90SRobert Watson ifoff_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel,
13078007886SRobert Watson     struct mbuf *m, struct label *mlabel)
131d8a7b7a3SRobert Watson {
132d8a7b7a3SRobert Watson 
13330d239bcSRobert Watson 	return (ifnet_check_outgoing(ifp));
134d8a7b7a3SRobert Watson }
135d8a7b7a3SRobert Watson 
136d8a7b7a3SRobert Watson static int
ifoff_inpcb_check_deliver(struct inpcb * inp,struct label * inplabel,struct mbuf * m,struct label * mlabel)1373f1a7a90SRobert Watson ifoff_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel,
138a557af22SRobert Watson     struct mbuf *m, struct label *mlabel)
139a557af22SRobert Watson {
140a557af22SRobert Watson 
141a557af22SRobert Watson 	M_ASSERTPKTHDR(m);
142a557af22SRobert Watson 	if (m->m_pkthdr.rcvif != NULL)
14330d239bcSRobert Watson 		return (ifnet_check_incoming(m->m_pkthdr.rcvif, 0));
144a557af22SRobert Watson 
145a557af22SRobert Watson 	return (0);
146a557af22SRobert Watson }
147a557af22SRobert Watson 
148a557af22SRobert Watson static int
ifoff_socket_check_deliver(struct socket * so,struct label * solabel,struct mbuf * m,struct label * mlabel)1493f1a7a90SRobert Watson ifoff_socket_check_deliver(struct socket *so, struct label *solabel,
15078007886SRobert Watson     struct mbuf *m, struct label *mlabel)
151d8a7b7a3SRobert Watson {
152d8a7b7a3SRobert Watson 
153535cf733SRobert Watson 	M_ASSERTPKTHDR(m);
154d8a7b7a3SRobert Watson 	if (m->m_pkthdr.rcvif != NULL)
15530d239bcSRobert Watson 		return (ifnet_check_incoming(m->m_pkthdr.rcvif, 0));
156d8a7b7a3SRobert Watson 
157d8a7b7a3SRobert Watson 	return (0);
158d8a7b7a3SRobert Watson }
159d8a7b7a3SRobert Watson 
1603f1a7a90SRobert Watson static struct mac_policy_ops ifoff_ops =
161d8a7b7a3SRobert Watson {
1623f1a7a90SRobert Watson 	.mpo_bpfdesc_check_receive = ifoff_bpfdesc_check_receive,
1633f1a7a90SRobert Watson 	.mpo_ifnet_check_transmit = ifoff_ifnet_check_transmit,
1643f1a7a90SRobert Watson 	.mpo_inpcb_check_deliver = ifoff_inpcb_check_deliver,
1653f1a7a90SRobert Watson 	.mpo_socket_check_deliver = ifoff_socket_check_deliver,
166d8a7b7a3SRobert Watson };
167d8a7b7a3SRobert Watson 
1683f1a7a90SRobert Watson MAC_POLICY_SET(&ifoff_ops, mac_ifoff, "TrustedBSD MAC/ifoff",
1699162f64bSRobert Watson     MPC_LOADTIME_FLAG_UNLOADOK, NULL);
170