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