From 9c969b771a32651104f16586408deb67d7039014 Mon Sep 17 00:00:00 2001 From: rwatson Date: Tue, 18 Nov 2003 00:39:07 +0000 Subject: Introduce a MAC label reference in 'struct inpcb', which caches the MAC label referenced from 'struct socket' in the IPv4 and IPv6-based protocols. This permits MAC labels to be checked during network delivery operations without dereferencing inp->inp_socket to get to so->so_label, which will eventually avoid our having to grab the socket lock during delivery at the network layer. This change introduces 'struct inpcb' as a labeled object to the MAC Framework, along with the normal circus of entry points: initialization, creation from socket, destruction, as well as a delivery access control check. For most policies, the inpcb label will simply be a cache of the socket label, so a new protocol switch method is introduced, pr_sosetlabel() to notify protocols that the socket layer label has been updated so that the cache can be updated while holding appropriate locks. Most protocols implement this using pru_sosetlabel_null(), but IPv4/IPv6 protocols using inpcbs use the the worker function in_pcbsosetlabel(), which calls into the MAC Framework to perform a cache update. Biba, LOMAC, and MLS implement these entry points, as do the stub policy, and test policy. Reviewed by: sam, bms Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories --- sys/kern/uipc_sockbuf.c | 10 +++ sys/kern/uipc_socket2.c | 10 +++ sys/kern/uipc_usrreq.c | 2 +- sys/modules/null/Makefile | 1 + sys/net/raw_usrreq.c | 2 +- sys/net/rtsock.c | 2 +- sys/netatalk/ddp_pcb.c | 3 +- sys/netatalk/ddp_usrreq.c | 3 +- sys/netatm/atm_aal5.c | 3 +- sys/netatm/atm_usrreq.c | 4 ++ sys/netgraph/bluetooth/socket/ng_btsocket.c | 12 ++-- sys/netgraph/ng_socket.c | 6 +- sys/netinet/in_pcb.c | 47 +++++++++++--- sys/netinet/in_pcb.h | 3 + sys/netinet/ip_divert.c | 2 +- sys/netinet/raw_ip.c | 4 +- sys/netinet/tcp_input.c | 4 +- sys/netinet/tcp_reass.c | 4 +- sys/netinet/tcp_usrreq.c | 4 +- sys/netinet/udp_usrreq.c | 4 +- sys/netinet6/raw_ip6.c | 2 +- sys/netinet6/udp6_usrreq.c | 2 +- sys/netipsec/keysock.c | 3 +- sys/netipx/ipx_usrreq.c | 4 +- sys/netipx/spx_usrreq.c | 4 +- sys/netkey/keysock.c | 3 +- sys/netnatm/natm.c | 2 +- sys/security/mac/mac_framework.h | 7 +++ sys/security/mac/mac_net.c | 97 ++++++++++++++++++++++++++++- sys/security/mac/mac_policy.h | 12 ++++ sys/security/mac_biba/mac_biba.c | 45 +++++++++++++ sys/security/mac_ifoff/mac_ifoff.c | 13 ++++ sys/security/mac_lomac/mac_lomac.c | 45 +++++++++++++ sys/security/mac_mls/mac_mls.c | 45 +++++++++++++ sys/security/mac_stub/mac_stub.c | 28 +++++++++ sys/security/mac_test/mac_test.c | 71 +++++++++++++++++++++ sys/sys/mac.h | 7 +++ sys/sys/mac_policy.h | 12 ++++ sys/sys/protosw.h | 2 + 39 files changed, 494 insertions(+), 40 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index c4a4c09..64199fc 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -1042,6 +1042,16 @@ pru_sense_null(struct socket *so, struct stat *sb) } /* + * For protocol types that don't keep cached copies of labels in their + * pcbs, provide a null sosetlabel that does a NOOP. + */ +void +pru_sosetlabel_null(struct socket *so) +{ + +} + +/* * Make a copy of a sockaddr in a malloced buffer of type M_SONAME. */ struct sockaddr * diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index c4a4c09..64199fc 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1042,6 +1042,16 @@ pru_sense_null(struct socket *so, struct stat *sb) } /* + * For protocol types that don't keep cached copies of labels in their + * pcbs, provide a null sosetlabel that does a NOOP. + */ +void +pru_sosetlabel_null(struct socket *so) +{ + +} + +/* * Make a copy of a sockaddr in a malloced buffer of type M_SONAME. */ struct sockaddr * diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index fec4050..1075709 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -450,7 +450,7 @@ struct pr_usrreqs uipc_usrreqs = { uipc_connect2, pru_control_notsupp, uipc_detach, uipc_disconnect, uipc_listen, uipc_peeraddr, uipc_rcvd, pru_rcvoob_notsupp, uipc_send, uipc_sense, uipc_shutdown, uipc_sockaddr, - sosend, soreceive, sopoll + sosend, soreceive, sopoll, pru_sosetlabel_null }; int diff --git a/sys/modules/null/Makefile b/sys/modules/null/Makefile index 5c80fa6..cdcaf21 100644 --- a/sys/modules/null/Makefile +++ b/sys/modules/null/Makefile @@ -5,5 +5,6 @@ KMOD= null SRCS= null.c SRCS+= bus_if.h device_if.h vnode_if.h +SRCS+= #opt_ddb.h .include diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c index 4cb90ba..1f49959 100644 --- a/sys/net/raw_usrreq.c +++ b/sys/net/raw_usrreq.c @@ -295,5 +295,5 @@ struct pr_usrreqs raw_usrreqs = { pru_connect2_notsupp, pru_control_notsupp, raw_udetach, raw_udisconnect, pru_listen_notsupp, raw_upeeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, raw_usend, pru_sense_null, raw_ushutdown, - raw_usockaddr, sosend, soreceive, sopoll + raw_usockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 7a6c6e3..4fba1a2 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -271,7 +271,7 @@ static struct pr_usrreqs route_usrreqs = { pru_connect2_notsupp, pru_control_notsupp, rts_detach, rts_disconnect, pru_listen_notsupp, rts_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, rts_send, pru_sense_null, rts_shutdown, rts_sockaddr, - sosend, soreceive, sopoll + sosend, soreceive, sopoll, pru_sosetlabel_null }; /*ARGSUSED*/ diff --git a/sys/netatalk/ddp_pcb.c b/sys/netatalk/ddp_pcb.c index 69b8958..1b91a05 100644 --- a/sys/netatalk/ddp_pcb.c +++ b/sys/netatalk/ddp_pcb.c @@ -590,5 +590,6 @@ struct pr_usrreqs ddp_usrreqs = { at_setsockaddr, sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; diff --git a/sys/netatalk/ddp_usrreq.c b/sys/netatalk/ddp_usrreq.c index 69b8958..1b91a05 100644 --- a/sys/netatalk/ddp_usrreq.c +++ b/sys/netatalk/ddp_usrreq.c @@ -590,5 +590,6 @@ struct pr_usrreqs ddp_usrreqs = { at_setsockaddr, sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; diff --git a/sys/netatm/atm_aal5.c b/sys/netatm/atm_aal5.c index 9c11b93..81fcce8 100644 --- a/sys/netatm/atm_aal5.c +++ b/sys/netatm/atm_aal5.c @@ -112,7 +112,8 @@ struct pr_usrreqs atm_aal5_usrreqs = { atm_aal5_sockaddr, /* pru_sockaddr */ sosend, /* pru_sosend */ soreceive, /* pru_soreceive */ - sopoll /* pru_sopoll */ + sopoll, /* pru_sopoll */ + pru_sosetlabel_null /* pru_sosetlabel */ }; /* diff --git a/sys/netatm/atm_usrreq.c b/sys/netatm/atm_usrreq.c index 4cc78b7..9b58741 100644 --- a/sys/netatm/atm_usrreq.c +++ b/sys/netatm/atm_usrreq.c @@ -83,6 +83,10 @@ struct pr_usrreqs atm_dgram_usrreqs = { pru_sense_null, /* pru_sense */ atm_proto_notsupp1, /* pru_shutdown */ atm_proto_notsupp3, /* pru_sockaddr */ + NULL, /* pru_sosend */ + NULL, /* pru_soreceive */ + NULL, /* pru_sooll */ + pru_sosetlabel_null /* pru_sosetlabel */ }; diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket.c b/sys/netgraph/bluetooth/socket/ng_btsocket.c index e8ad4ad..383a063 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket.c @@ -79,7 +79,8 @@ static struct pr_usrreqs ng_btsocket_hci_raw_usrreqs = { ng_btsocket_hci_raw_sockaddr, /* sockaddr */ sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; /* @@ -106,7 +107,8 @@ static struct pr_usrreqs ng_btsocket_l2cap_raw_usrreqs = { ng_btsocket_l2cap_raw_sockaddr, /* sockaddr */ sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; /* @@ -133,7 +135,8 @@ static struct pr_usrreqs ng_btsocket_l2cap_usrreqs = { ng_btsocket_l2cap_sockaddr, /* sockaddr */ sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; /* @@ -160,7 +163,8 @@ static struct pr_usrreqs ng_btsocket_rfcomm_usrreqs = { ng_btsocket_rfcomm_sockaddr, /* sockaddr */ sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; /* diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index f841a0e..e3be7d1 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -978,7 +978,8 @@ static struct pr_usrreqs ngc_usrreqs = { ng_setsockaddr, sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; static struct pr_usrreqs ngd_usrreqs = { @@ -1001,7 +1002,8 @@ static struct pr_usrreqs ngd_usrreqs = { ng_setsockaddr, sosend, soreceive, - sopoll + sopoll, + pru_sosetlabel_null }; /* diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 480c50e..11735ec 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -36,10 +36,12 @@ #include "opt_ipsec.h" #include "opt_inet6.h" +#include "opt_mac.h" #include #include #include +#include #include #include #include @@ -161,26 +163,30 @@ in_pcballoc(so, pcbinfo, td) struct thread *td; { register struct inpcb *inp; -#if defined(IPSEC) || defined(FAST_IPSEC) int error; -#endif + INP_INFO_WLOCK_ASSERT(pcbinfo); + error = 0; inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT | M_ZERO); if (inp == NULL) return (ENOBUFS); inp->inp_gencnt = ++pcbinfo->ipi_gencnt; inp->inp_pcbinfo = pcbinfo; inp->inp_socket = so; +#ifdef MAC + error = mac_init_inpcb(inp, M_NOWAIT); + if (error != 0) + goto out; + mac_create_inpcb_from_socket(so, inp); +#endif #if defined(IPSEC) || defined(FAST_IPSEC) #ifdef FAST_IPSEC error = ipsec_init_policy(so, &inp->inp_sp); #else error = ipsec_init_pcbpolicy(so, &inp->inp_sp); #endif - if (error != 0) { - uma_zfree(pcbinfo->ipi_zone, inp); - return error; - } + if (error != 0) + goto out; #endif /*IPSEC*/ #if defined(INET6) if (INP_SOCKAF(so) == AF_INET6) { @@ -197,7 +203,12 @@ in_pcballoc(so, pcbinfo, td) if (ip6_auto_flowlabel) inp->inp_flags |= IN6P_AUTOFLOWLABEL; #endif - return (0); +#if defined(IPSEC) || defined(FAST_IPSEC) || defined(MAC) +out: + if (error != 0) + uma_zfree(pcbinfo->ipi_zone, inp); +#endif + return (error); } int @@ -700,6 +711,9 @@ in_pcbdetach(inp) ip_freemoptions(inp->inp_moptions); inp->inp_vflag = 0; INP_LOCK_DESTROY(inp); +#ifdef MAC + mac_destroy_inpcb(inp); +#endif uma_zfree(ipi->ipi_zone, inp); } @@ -1218,6 +1232,25 @@ in_pcbremlists(inp) pcbinfo->ipi_count--; } +/* + * A set label operation has occurred at the socket layer, propagate the + * label change into the in_pcb for the socket. + */ +void +in_pcbsosetlabel(so) + struct socket *so; +{ +#ifdef MAC + struct inpcb *inp; + + /* XXX: Will assert socket lock when we have them. */ + inp = (struct inpcb *)so->so_pcb; + INP_LOCK(inp); + mac_inpcb_sosetlabel(so, inp); + INP_UNLOCK(inp); +#endif +} + int prison_xinpcb(struct thread *td, struct inpcb *inp) { diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 19786b59..8a6717c 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -134,6 +134,7 @@ struct inpcb { struct inpcbinfo *inp_pcbinfo; /* PCB list info */ struct socket *inp_socket; /* back pointer to socket */ /* list for this PCB's local port */ + struct label *inp_label; /* MAC label */ int inp_flags; /* generic IP/datagram flags */ struct inpcbpolicy *inp_sp; /* for IPSEC */ @@ -369,10 +370,12 @@ struct inpcb * void in_pcbnotifyall(struct inpcbinfo *pcbinfo, struct in_addr, int, struct inpcb *(*)(struct inpcb *, int)); void in_pcbrehash(struct inpcb *); +void in_pcbsetsolabel(struct socket *so); int in_setpeeraddr(struct socket *so, struct sockaddr **nam, struct inpcbinfo *pcbinfo); int in_setsockaddr(struct socket *so, struct sockaddr **nam, struct inpcbinfo *pcbinfo);; struct sockaddr * in_sockaddr(in_port_t port, struct in_addr *addr); +void in_pcbsosetlabel(struct socket *so); void in_pcbremlists(struct inpcb *inp); int prison_xinpcb(struct thread *td, struct inpcb *inp); #endif /* _KERNEL */ diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 7e939e3..172021b 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -652,5 +652,5 @@ struct pr_usrreqs div_usrreqs = { pru_connect_notsupp, pru_connect2_notsupp, in_control, div_detach, div_disconnect, pru_listen_notsupp, div_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, div_send, pru_sense_null, div_shutdown, - div_sockaddr, sosend, soreceive, sopoll + div_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index 8e02e41..632e00a 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -161,7 +161,7 @@ raw_append(struct inpcb *last, struct ip *ip, struct mbuf *n) } #endif /*FAST_IPSEC*/ #ifdef MAC - if (!policyfail && mac_check_socket_deliver(last->inp_socket, n) != 0) + if (!policyfail && mac_check_inpcb_deliver(last, n) != 0) policyfail = 1; #endif if (!policyfail) { @@ -840,5 +840,5 @@ struct pr_usrreqs rip_usrreqs = { pru_connect2_notsupp, in_control, rip_detach, rip_disconnect, pru_listen_notsupp, rip_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, rip_send, pru_sense_null, rip_shutdown, - rip_sockaddr, sosend, soreceive, sopoll + rip_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 4df4a99..a247138 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -683,11 +683,11 @@ findpcb: else tiwin = th->th_win; - so = inp->inp_socket; #ifdef MAC - if (mac_check_socket_deliver(so, m)) + if (mac_check_inpcb_deliver(inp, m)) goto drop; #endif + so = inp->inp_socket; #ifdef TCPDEBUG if (so->so_options & SO_DEBUG) { ostate = tp->t_state; diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 4df4a99..a247138 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -683,11 +683,11 @@ findpcb: else tiwin = th->th_win; - so = inp->inp_socket; #ifdef MAC - if (mac_check_socket_deliver(so, m)) + if (mac_check_inpcb_deliver(inp, m)) goto drop; #endif + so = inp->inp_socket; #ifdef TCPDEBUG if (so->so_options & SO_DEBUG) { ostate = tp->t_state; diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 805a4fb..7035227 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -816,7 +816,7 @@ struct pr_usrreqs tcp_usrreqs = { tcp_usr_connect, pru_connect2_notsupp, in_control, tcp_usr_detach, tcp_usr_disconnect, tcp_usr_listen, tcp_peeraddr, tcp_usr_rcvd, tcp_usr_rcvoob, tcp_usr_send, pru_sense_null, tcp_usr_shutdown, - tcp_sockaddr, sosend, soreceive, sopoll + tcp_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; #ifdef INET6 @@ -825,7 +825,7 @@ struct pr_usrreqs tcp6_usrreqs = { tcp6_usr_connect, pru_connect2_notsupp, in6_control, tcp_usr_detach, tcp_usr_disconnect, tcp6_usr_listen, in6_mapped_peeraddr, tcp_usr_rcvd, tcp_usr_rcvoob, tcp_usr_send, pru_sense_null, tcp_usr_shutdown, - in6_mapped_sockaddr, sosend, soreceive, sopoll + in6_mapped_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; #endif /* INET6 */ diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 4b755af..60ec82b 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -469,7 +469,7 @@ udp_append(last, ip, n, off) } #endif /*FAST_IPSEC*/ #ifdef MAC - if (mac_check_socket_deliver(last->inp_socket, n) != 0) { + if (mac_check_inpcb_deliver(last, n) != 0) { m_freem(n); return; } @@ -1119,5 +1119,5 @@ struct pr_usrreqs udp_usrreqs = { pru_connect2_notsupp, in_control, udp_detach, udp_disconnect, pru_listen_notsupp, udp_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, udp_send, pru_sense_null, udp_shutdown, - udp_sockaddr, sosend, soreceive, sopoll + udp_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index b714a2b..8aca0a0 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -750,5 +750,5 @@ struct pr_usrreqs rip6_usrreqs = { pru_connect2_notsupp, in6_control, rip6_detach, rip6_disconnect, pru_listen_notsupp, in6_setpeeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, rip6_send, pru_sense_null, rip6_shutdown, - in6_setsockaddr, sosend, soreceive, sopoll + in6_setsockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index eb6bbac..407d98b 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -767,5 +767,5 @@ struct pr_usrreqs udp6_usrreqs = { pru_connect2_notsupp, in6_control, udp6_detach, udp6_disconnect, pru_listen_notsupp, in6_mapped_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, udp6_send, pru_sense_null, udp_shutdown, - in6_mapped_sockaddr, sosend, soreceive, sopoll + in6_mapped_sockaddr, sosend, soreceive, sopoll, in_pcbsosetlabel }; diff --git a/sys/netipsec/keysock.c b/sys/netipsec/keysock.c index b78a307..a563e9a 100644 --- a/sys/netipsec/keysock.c +++ b/sys/netipsec/keysock.c @@ -567,7 +567,8 @@ struct pr_usrreqs key_usrreqs = { key_disconnect, pru_listen_notsupp, key_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, key_send, pru_sense_null, key_shutdown, - key_sockaddr, sosend, soreceive, sopoll + key_sockaddr, sosend, soreceive, sopoll, + pru_sosetlabel_null }; /* sysctl */ diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c index 376d8fb..383d2af 100644 --- a/sys/netipx/ipx_usrreq.c +++ b/sys/netipx/ipx_usrreq.c @@ -92,7 +92,7 @@ struct pr_usrreqs ipx_usrreqs = { ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach, ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown, - ipx_sockaddr, sosend, soreceive, sopoll + ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; struct pr_usrreqs ripx_usrreqs = { @@ -100,7 +100,7 @@ struct pr_usrreqs ripx_usrreqs = { ipx_connect, pru_connect2_notsupp, ipx_control, ipx_detach, ipx_disconnect, pru_listen_notsupp, ipx_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, ipx_send, pru_sense_null, ipx_shutdown, - ipx_sockaddr, sosend, soreceive, sopoll + ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; /* diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 371e85e..1424754 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -112,7 +112,7 @@ struct pr_usrreqs spx_usrreqs = { spx_connect, pru_connect2_notsupp, ipx_control, spx_detach, spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd, spx_rcvoob, spx_send, pru_sense_null, spx_shutdown, - ipx_sockaddr, sosend, soreceive, sopoll + ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; struct pr_usrreqs spx_usrreq_sps = { @@ -120,7 +120,7 @@ struct pr_usrreqs spx_usrreq_sps = { spx_connect, pru_connect2_notsupp, ipx_control, spx_detach, spx_usr_disconnect, spx_listen, ipx_peeraddr, spx_rcvd, spx_rcvoob, spx_send, pru_sense_null, spx_shutdown, - ipx_sockaddr, sosend, soreceive, sopoll + ipx_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; void diff --git a/sys/netkey/keysock.c b/sys/netkey/keysock.c index 376841d..233fb28 100644 --- a/sys/netkey/keysock.c +++ b/sys/netkey/keysock.c @@ -477,7 +477,8 @@ struct pr_usrreqs key_usrreqs = { key_disconnect, pru_listen_notsupp, key_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, key_send, pru_sense_null, key_shutdown, - key_sockaddr, sosend, soreceive, sopoll + key_sockaddr, sosend, soreceive, sopoll, + pru_sosetlabel_null }; /* sysctl */ diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c index b9beb03c..c1f9850 100644 --- a/sys/netnatm/natm.c +++ b/sys/netnatm/natm.c @@ -396,7 +396,7 @@ struct pr_usrreqs natm_usrreqs = { natm_usr_detach, natm_usr_disconnect, pru_listen_notsupp, natm_usr_peeraddr, pru_rcvd_notsupp, pru_rcvoob_notsupp, natm_usr_send, pru_sense_null, natm_usr_shutdown, - natm_usr_sockaddr, sosend, soreceive, sopoll + natm_usr_sockaddr, sosend, soreceive, sopoll, pru_sosetlabel_null }; #else /* !FREEBSD_USRREQS */ diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 8cb20ad..81dad5a 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -110,7 +110,9 @@ struct componentname; struct devfs_dirent; struct ifnet; struct ifreq; +struct inpcb; struct image_params; +struct inpcb; struct ipq; struct m_tag; struct mbuf; @@ -137,6 +139,7 @@ void mac_init_bpfdesc(struct bpf_d *); void mac_init_cred(struct ucred *); void mac_init_devfsdirent(struct devfs_dirent *); void mac_init_ifnet(struct ifnet *); +int mac_init_inpcb(struct inpcb *, int flag); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipe *); @@ -151,6 +154,7 @@ void mac_destroy_bpfdesc(struct bpf_d *); void mac_destroy_cred(struct ucred *); void mac_destroy_devfsdirent(struct devfs_dirent *); void mac_destroy_ifnet(struct ifnet *); +void mac_destroy_inpcb(struct inpcb *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipe *); @@ -205,6 +209,7 @@ void mac_create_pipe(struct ucred *cred, struct pipe *pipe); */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); void mac_create_ifnet(struct ifnet *ifp); +void mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp); void mac_create_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram); void mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment); @@ -219,6 +224,7 @@ int mac_fragment_match(struct mbuf *fragment, struct ipq *ipq); void mac_reflect_mbuf_icmp(struct mbuf *m); void mac_reflect_mbuf_tcp(struct mbuf *m); void mac_update_ipq(struct mbuf *fragment, struct ipq *ipq); +void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp); /* * Labeling event operations: processes. @@ -239,6 +245,7 @@ void mac_thread_userret(struct thread *td); int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet); int mac_check_cred_visible(struct ucred *u1, struct ucred *u2); int mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m); +int mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m); int mac_check_kenv_dump(struct ucred *cred); int mac_check_kenv_get(struct ucred *cred, char *name); int mac_check_kenv_set(struct ucred *cred, char *name, char *value); diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index 7ff0d28..8337a19 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -77,12 +79,14 @@ TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); #ifdef MAC_DEBUG static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets, - nmacipqs; + nmacinpcbs, nmacipqs; SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, &nmacmbufs, 0, "number of mbufs in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, &nmacifnets, 0, "number of ifnets in use"); +SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, inpcbs, CTLFLAG_RD, + &nmacinpcbs, 0, "number of inpcbs in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, &nmacipqs, 0, "number of ipqs in use"); SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, @@ -140,6 +144,35 @@ mac_init_ifnet(struct ifnet *ifp) } static struct label * +mac_inpcb_label_alloc(int flag) +{ + struct label *label; + int error; + + label = mac_labelzone_alloc(flag); + if (label == NULL) + return (NULL); + MAC_CHECK(init_inpcb_label, label, flag); + if (error) { + MAC_PERFORM(destroy_inpcb_label, label); + mac_labelzone_free(label); + return (NULL); + } + MAC_DEBUG_COUNTER_INC(&nmacinpcbs); + return (label); +} + +int +mac_init_inpcb(struct inpcb *inp, int flag) +{ + + inp->inp_label = mac_inpcb_label_alloc(flag); + if (inp->inp_label == NULL) + return (ENOMEM); + return (0); +} + +static struct label * mac_ipq_label_alloc(int flag) { struct label *label; @@ -308,6 +341,23 @@ mac_destroy_ifnet(struct ifnet *ifp) } static void +mac_inpcb_label_free(struct label *label) +{ + + MAC_PERFORM(destroy_inpcb_label, label); + mac_labelzone_free(label); + MAC_DEBUG_COUNTER_DEC(&nmacinpcbs); +} + +void +mac_destroy_inpcb(struct inpcb *inp) +{ + + mac_inpcb_label_free(inp->inp_label); + inp->inp_label = NULL; +} + +static void mac_ipq_label_free(struct label *label) { @@ -447,6 +497,14 @@ mac_create_ifnet(struct ifnet *ifnet) } void +mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp) +{ + + MAC_PERFORM(create_inpcb_from_socket, so, so->so_label, inp, + inp->inp_label); +} + +void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) { @@ -689,6 +747,24 @@ mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) } int +mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m) +{ + struct label *label; + int error; + + M_ASSERTPKTHDR(m); + + if (!mac_enforce_socket) + return (0); + + label = mbuf_to_label(m); + + MAC_CHECK(check_inpcb_deliver, inp, inp->inp_label, m, label); + + return (error); +} + +int mac_check_socket_bind(struct ucred *ucred, struct socket *socket, struct sockaddr *sockaddr) { @@ -889,6 +965,15 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, return (0); } +void +mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp) +{ + + /* XXX: assert socket lock. */ + INP_LOCK_ASSERT(inp); + MAC_PERFORM(inpcb_sosetlabel, so, so->so_label, inp, inp->inp_label); +} + int mac_socket_label_set(struct ucred *cred, struct socket *so, struct label *label) @@ -900,6 +985,16 @@ mac_socket_label_set(struct ucred *cred, struct socket *so, return (error); mac_relabel_socket(cred, so, label); + + /* + * If the protocol has expressed interest in socket layer changes, + * such as if it needs to propagate changes to a cached pcb + * label from the socket, notify it of the label change while + * holding the socket lock. + */ + if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL) + (so->so_proto->pr_usrreqs->pru_sosetlabel)(so); + return (0); } diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 3c72d09..518f883 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -54,6 +54,7 @@ struct acl; struct componentname; struct devfs_dirent; +struct inpcb; struct ipq; struct label; struct mac_policy_conf; @@ -86,6 +87,7 @@ struct mac_policy_ops { void (*mpo_init_cred_label)(struct label *label); void (*mpo_init_devfsdirent_label)(struct label *label); void (*mpo_init_ifnet_label)(struct label *label); + int (*mpo_init_inpcb_label)(struct label *label, int flag); int (*mpo_init_ipq_label)(struct label *label, int flag); int (*mpo_init_mbuf_label)(struct label *label, int flag); void (*mpo_init_mount_label)(struct label *label); @@ -99,6 +101,7 @@ struct mac_policy_ops { void (*mpo_destroy_cred_label)(struct label *label); void (*mpo_destroy_devfsdirent_label)(struct label *label); void (*mpo_destroy_ifnet_label)(struct label *label); + void (*mpo_destroy_inpcb_label)(struct label *label); void (*mpo_destroy_ipq_label)(struct label *label); void (*mpo_destroy_mbuf_label)(struct label *label); void (*mpo_destroy_mount_label)(struct label *label); @@ -212,6 +215,9 @@ struct mac_policy_ops { struct label *bpflabel); void (*mpo_create_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel); + void (*mpo_create_inpcb_from_socket)(struct socket *so, + struct label *solabel, struct inpcb *inp, + struct label *inplabel); void (*mpo_create_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); @@ -251,6 +257,9 @@ struct mac_policy_ops { void (*mpo_update_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); + void (*mpo_inpcb_sosetlabel)(struct socket *so, + struct label *label, struct inpcb *inp, + struct label *inplabel); /* * Labeling event operations: processes. @@ -286,6 +295,9 @@ struct mac_policy_ops { int (*mpo_check_ifnet_transmit)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel); + int (*mpo_check_inpcb_deliver)(struct inpcb *inp, + struct label *inplabel, struct mbuf *m, + struct label *mlabel); int (*mpo_check_kenv_dump)(struct ucred *cred); int (*mpo_check_kenv_get)(struct ucred *cred, char *name); int (*mpo_check_kenv_set)(struct ucred *cred, char *name, diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c index 778532c..365c397 100644 --- a/sys/security/mac_biba/mac_biba.c +++ b/sys/security/mac_biba/mac_biba.c @@ -69,6 +69,7 @@ #include #include +#include #include #include @@ -980,6 +981,18 @@ mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, * Labeling event operations: IPC object. */ static void +mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_biba *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_biba_copy_single(source, dest); +} + +static void mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { @@ -1299,6 +1312,18 @@ mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, /* NOOP: we only accept matching labels, so no need to update */ } +static void +mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_biba *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_biba_copy(source, dest); +} + /* * Labeling event operations: processes. */ @@ -1493,6 +1518,21 @@ mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + struct mac_biba *p, *i; + + if (!mac_biba_enabled) + return (0); + + p = SLOT(mlabel); + i = SLOT(inplabel); + + return (mac_biba_equal_single(p, i) ? 0 : EACCES); +} + +static int mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, struct label *label) { @@ -2606,6 +2646,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_init_cred_label = mac_biba_init_label, .mpo_init_devfsdirent_label = mac_biba_init_label, .mpo_init_ifnet_label = mac_biba_init_label, + .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, .mpo_init_ipq_label = mac_biba_init_label_waitcheck, .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, .mpo_init_mount_label = mac_biba_init_label, @@ -2618,6 +2659,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_destroy_cred_label = mac_biba_destroy_label, .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, .mpo_destroy_ifnet_label = mac_biba_destroy_label, + .mpo_destroy_inpcb_label = mac_biba_destroy_label, .mpo_destroy_ipq_label = mac_biba_destroy_label, .mpo_destroy_mbuf_label = mac_biba_destroy_label, .mpo_destroy_mount_label = mac_biba_destroy_label, @@ -2665,6 +2707,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, .mpo_create_fragment = mac_biba_create_fragment, .mpo_create_ifnet = mac_biba_create_ifnet, + .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, .mpo_create_ipq = mac_biba_create_ipq, .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, @@ -2675,6 +2718,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_fragment_match = mac_biba_fragment_match, .mpo_relabel_ifnet = mac_biba_relabel_ifnet, .mpo_update_ipq = mac_biba_update_ipq, + .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, .mpo_create_cred = mac_biba_create_cred, .mpo_create_proc0 = mac_biba_create_proc0, .mpo_create_proc1 = mac_biba_create_proc1, @@ -2684,6 +2728,7 @@ static struct mac_policy_ops mac_biba_ops = .mpo_check_cred_visible = mac_biba_check_cred_visible, .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, + .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, .mpo_check_kld_load = mac_biba_check_kld_load, .mpo_check_kld_unload = mac_biba_check_kld_unload, .mpo_check_mount_stat = mac_biba_check_mount_stat, diff --git a/sys/security/mac_ifoff/mac_ifoff.c b/sys/security/mac_ifoff/mac_ifoff.c index 19bbc79..c3337d4 100644 --- a/sys/security/mac_ifoff/mac_ifoff.c +++ b/sys/security/mac_ifoff/mac_ifoff.c @@ -143,6 +143,18 @@ mac_ifoff_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +mac_ifoff_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + + M_ASSERTPKTHDR(m); + if (m->m_pkthdr.rcvif != NULL) + return (check_ifnet_incoming(m->m_pkthdr.rcvif, 0)); + + return (0); +} + +static int mac_ifoff_check_socket_deliver(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { @@ -158,6 +170,7 @@ static struct mac_policy_ops mac_ifoff_ops = { .mpo_check_bpfdesc_receive = mac_ifoff_check_bpfdesc_receive, .mpo_check_ifnet_transmit = mac_ifoff_check_ifnet_transmit, + .mpo_check_inpcb_deliver = mac_ifoff_check_inpcb_deliver, .mpo_check_socket_deliver = mac_ifoff_check_socket_deliver, }; diff --git a/sys/security/mac_lomac/mac_lomac.c b/sys/security/mac_lomac/mac_lomac.c index c3ec772..52eeaa6 100644 --- a/sys/security/mac_lomac/mac_lomac.c +++ b/sys/security/mac_lomac/mac_lomac.c @@ -70,6 +70,7 @@ #include #include +#include #include #include @@ -1119,6 +1120,18 @@ mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, * Labeling event operations: IPC object. */ static void +mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_lomac *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_lomac_copy_single(source, dest); +} + +static void mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { @@ -1439,6 +1452,18 @@ mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, /* NOOP: we only accept matching labels, so no need to update */ } +static void +mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_lomac *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_lomac_copy_single(source, dest); +} + /* * Labeling event operations: processes. */ @@ -1721,6 +1746,21 @@ mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + struct mac_lomac *p, *i; + + if (!mac_lomac_enabled) + return (0); + + p = SLOT(mlabel); + i = SLOT(inplabel); + + return (mac_lomac_equal_single(p, i) ? 0 : EACCES); +} + +static int mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp, struct label *label) { @@ -2584,6 +2624,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_init_cred_label = mac_lomac_init_label, .mpo_init_devfsdirent_label = mac_lomac_init_label, .mpo_init_ifnet_label = mac_lomac_init_label, + .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, .mpo_init_mount_label = mac_lomac_init_label, @@ -2597,6 +2638,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_destroy_cred_label = mac_lomac_destroy_label, .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, .mpo_destroy_ifnet_label = mac_lomac_destroy_label, + .mpo_destroy_inpcb_label = mac_lomac_destroy_label, .mpo_destroy_ipq_label = mac_lomac_destroy_label, .mpo_destroy_mbuf_label = mac_lomac_destroy_label, .mpo_destroy_mount_label = mac_lomac_destroy_label, @@ -2647,6 +2689,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, .mpo_create_fragment = mac_lomac_create_fragment, .mpo_create_ifnet = mac_lomac_create_ifnet, + .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, .mpo_create_ipq = mac_lomac_create_ipq, .mpo_create_mbuf_from_mbuf = mac_lomac_create_mbuf_from_mbuf, .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, @@ -2658,6 +2701,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_fragment_match = mac_lomac_fragment_match, .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, .mpo_update_ipq = mac_lomac_update_ipq, + .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, .mpo_create_cred = mac_lomac_create_cred, .mpo_execve_transition = mac_lomac_execve_transition, .mpo_execve_will_transition = mac_lomac_execve_will_transition, @@ -2669,6 +2713,7 @@ static struct mac_policy_ops mac_lomac_ops = .mpo_check_cred_visible = mac_lomac_check_cred_visible, .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, + .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, .mpo_check_kld_load = mac_lomac_check_kld_load, .mpo_check_kld_unload = mac_lomac_check_kld_unload, .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c index cdf92be..d4e7634 100644 --- a/sys/security/mac_mls/mac_mls.c +++ b/sys/security/mac_mls/mac_mls.c @@ -69,6 +69,7 @@ #include #include +#include #include #include @@ -950,6 +951,18 @@ mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, * Labeling event operations: IPC object. */ static void +mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_mls *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_mls_copy_single(source, dest); +} + +static void mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, struct mbuf *m, struct label *mbuflabel) { @@ -1229,6 +1242,18 @@ mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, /* NOOP: we only accept matching labels, so no need to update */ } +static void +mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + struct mac_mls *source, *dest; + + source = SLOT(solabel); + dest = SLOT(inplabel); + + mac_mls_copy(source, dest); +} + /* * Labeling event operations: processes. */ @@ -1421,6 +1446,21 @@ mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + struct mac_mls *p, *i; + + if (!mac_mls_enabled) + return (0); + + p = SLOT(mlabel); + i = SLOT(inplabel); + + return (mac_mls_equal_single(p, i) ? 0 : EACCES); +} + +static int mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, struct label *mntlabel) { @@ -2378,6 +2418,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_init_cred_label = mac_mls_init_label, .mpo_init_devfsdirent_label = mac_mls_init_label, .mpo_init_ifnet_label = mac_mls_init_label, + .mpo_init_inpcb_label = mac_mls_init_label_waitcheck, .mpo_init_ipq_label = mac_mls_init_label_waitcheck, .mpo_init_mbuf_label = mac_mls_init_label_waitcheck, .mpo_init_mount_label = mac_mls_init_label, @@ -2390,6 +2431,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_destroy_cred_label = mac_mls_destroy_label, .mpo_destroy_devfsdirent_label = mac_mls_destroy_label, .mpo_destroy_ifnet_label = mac_mls_destroy_label, + .mpo_destroy_inpcb_label = mac_mls_destroy_label, .mpo_destroy_ipq_label = mac_mls_destroy_label, .mpo_destroy_mbuf_label = mac_mls_destroy_label, .mpo_destroy_mount_label = mac_mls_destroy_label, @@ -2437,6 +2479,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq, .mpo_create_fragment = mac_mls_create_fragment, .mpo_create_ifnet = mac_mls_create_ifnet, + .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket, .mpo_create_ipq = mac_mls_create_ipq, .mpo_create_mbuf_from_mbuf = mac_mls_create_mbuf_from_mbuf, .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer, @@ -2447,6 +2490,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_fragment_match = mac_mls_fragment_match, .mpo_relabel_ifnet = mac_mls_relabel_ifnet, .mpo_update_ipq = mac_mls_update_ipq, + .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel, .mpo_create_cred = mac_mls_create_cred, .mpo_create_proc0 = mac_mls_create_proc0, .mpo_create_proc1 = mac_mls_create_proc1, @@ -2456,6 +2500,7 @@ static struct mac_policy_ops mac_mls_ops = .mpo_check_cred_visible = mac_mls_check_cred_visible, .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel, .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit, + .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver, .mpo_check_mount_stat = mac_mls_check_mount_stat, .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl, .mpo_check_pipe_poll = mac_mls_check_pipe_poll, diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c index 1d48210..1b6ad02 100644 --- a/sys/security/mac_stub/mac_stub.c +++ b/sys/security/mac_stub/mac_stub.c @@ -68,6 +68,7 @@ #include #include +#include #include #include @@ -336,6 +337,13 @@ stub_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) } static void +stub_create_inpcb_from_socket(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + +} + +static void stub_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { @@ -420,6 +428,13 @@ stub_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, } +static void +stub_inpcb_sosetlabel(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + +} + /* * Labeling event operations: processes. */ @@ -513,6 +528,14 @@ stub_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +stub_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + + return (0); +} + +static int stub_check_kenv_dump(struct ucred *cred) { @@ -1010,6 +1033,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_init_cred_label = stub_init_label, .mpo_init_devfsdirent_label = stub_init_label, .mpo_init_ifnet_label = stub_init_label, + .mpo_init_inpcb_label = stub_init_label_waitcheck, .mpo_init_ipq_label = stub_init_label_waitcheck, .mpo_init_mbuf_label = stub_init_label_waitcheck, .mpo_init_mount_label = stub_init_label, @@ -1022,6 +1046,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_destroy_cred_label = stub_destroy_label, .mpo_destroy_devfsdirent_label = stub_destroy_label, .mpo_destroy_ifnet_label = stub_destroy_label, + .mpo_destroy_inpcb_label = stub_destroy_label, .mpo_destroy_ipq_label = stub_destroy_label, .mpo_destroy_mbuf_label = stub_destroy_label, .mpo_destroy_mount_label = stub_destroy_label, @@ -1067,6 +1092,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_set_socket_peer_from_socket = stub_set_socket_peer_from_socket, .mpo_create_bpfdesc = stub_create_bpfdesc, .mpo_create_ifnet = stub_create_ifnet, + .mpo_create_inpcb_from_socket = stub_create_inpcb_from_socket, .mpo_create_ipq = stub_create_ipq, .mpo_create_datagram_from_ipq = stub_create_datagram_from_ipq, .mpo_create_fragment = stub_create_fragment, @@ -1082,6 +1108,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_reflect_mbuf_tcp = stub_reflect_mbuf_tcp, .mpo_relabel_ifnet = stub_relabel_ifnet, .mpo_update_ipq = stub_update_ipq, + .mpo_inpcb_sosetlabel = stub_inpcb_sosetlabel, .mpo_create_cred = stub_create_cred, .mpo_execve_transition = stub_execve_transition, .mpo_execve_will_transition = stub_execve_will_transition, @@ -1094,6 +1121,7 @@ static struct mac_policy_ops mac_stub_ops = .mpo_check_cred_visible = stub_check_cred_visible, .mpo_check_ifnet_relabel = stub_check_ifnet_relabel, .mpo_check_ifnet_transmit = stub_check_ifnet_transmit, + .mpo_check_inpcb_deliver = stub_check_inpcb_deliver, .mpo_check_kenv_dump = stub_check_kenv_dump, .mpo_check_kenv_get = stub_check_kenv_get, .mpo_check_kenv_set = stub_check_kenv_set, diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c index 8b591902..847c9e9 100644 --- a/sys/security/mac_test/mac_test.c +++ b/sys/security/mac_test/mac_test.c @@ -81,6 +81,7 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, enabled, CTLFLAG_RW, #define BPFMAGIC 0xfe1ad1b6 #define DEVFSMAGIC 0x9ee79c32 #define IFNETMAGIC 0xc218b120 +#define INPCBMAGIC 0x4440f7bb #define IPQMAGIC 0x206188ef #define MBUFMAGIC 0xbbefa5bb #define MOUNTMAGIC 0xc7c46e47 @@ -99,6 +100,8 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, enabled, CTLFLAG_RW, SLOT(x) == 0, ("%s: Bad DEVFS label", __func__ )) #define ASSERT_IFNET_LABEL(x) KASSERT(SLOT(x) == IFNETMAGIC || \ SLOT(x) == 0, ("%s: Bad IFNET label", __func__ )) +#define ASSERT_INPCB_LABEL(x) KASSERT(SLOT(x) == INPCBMAGIC || \ + SLOT(x) == 0, ("%s: Bad INPCB label", __func__ )) #define ASSERT_IPQ_LABEL(x) KASSERT(SLOT(x) == IPQMAGIC || \ SLOT(x) == 0, ("%s: Bad IPQ label", __func__ )) #define ASSERT_MBUF_LABEL(x) KASSERT(SLOT(x) == MBUFMAGIC || \ @@ -132,6 +135,9 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_devfsdirent, CTLFLAG_RD, static int init_count_ifnet; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ifnet, CTLFLAG_RD, &init_count_ifnet, 0, "ifnet init calls"); +static int init_count_inpcb; +SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_inpcb, CTLFLAG_RD, + &init_count_inpcb, 0, "inpcb init calls"); static int init_count_ipq; SYSCTL_INT(_security_mac_test, OID_AUTO, init_count_ipq, CTLFLAG_RD, &init_count_ipq, 0, "ipq init calls"); @@ -173,6 +179,9 @@ SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_devfsdirent, CTLFLAG_RD, static int destroy_count_ifnet; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ifnet, CTLFLAG_RD, &destroy_count_ifnet, 0, "ifnet destroy calls"); +static int destroy_count_inpcb; +SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_inpcb, CTLFLAG_RD, + &destroy_count_inpcb, 0, "inpcb destroy calls"); static int destroy_count_ipq; SYSCTL_INT(_security_mac_test, OID_AUTO, destroy_count_ipq, CTLFLAG_RD, &destroy_count_ipq, 0, "ipq destroy calls"); @@ -268,6 +277,20 @@ mac_test_init_ifnet_label(struct label *label) } static int +mac_test_init_inpcb_label(struct label *label, int flag) +{ + + if (flag & M_WAITOK) + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, + "mac_test_init_inpcb_label() at %s:%d", __FILE__, + __LINE__); + + SLOT(label) = INPCBMAGIC; + atomic_add_int(&init_count_inpcb, 1); + return (0); +} + +static int mac_test_init_ipq_label(struct label *label, int flag) { @@ -420,6 +443,20 @@ mac_test_destroy_ifnet_label(struct label *label) } static void +mac_test_destroy_inpcb_label(struct label *label) +{ + + if (SLOT(label) == INPCBMAGIC || SLOT(label) == 0) { + atomic_add_int(&destroy_count_inpcb, 1); + SLOT(label) = EXMAGIC; + } else if (SLOT(label) == EXMAGIC) { + Debugger("mac_test_destroy_inpcb: dup destroy"); + } else { + Debugger("mac_test_destroy_inpcb: corrupted label"); + } +} + +static void mac_test_destroy_ipq_label(struct label *label) { @@ -852,6 +889,15 @@ mac_test_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) } static void +mac_test_create_inpcb_from_socket(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + + ASSERT_SOCKET_LABEL(solabel); + ASSERT_INPCB_LABEL(inplabel); +} + +static void mac_test_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel) { @@ -962,6 +1008,15 @@ mac_test_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, ASSERT_IPQ_LABEL(ipqlabel); } +static void +mac_test_inpcb_sosetlabel(struct socket *so, struct label *solabel, + struct inpcb *inp, struct label *inplabel) +{ + + ASSERT_SOCKET_LABEL(solabel); + ASSERT_INPCB_LABEL(inplabel); +} + /* * Labeling event operations: processes. */ @@ -1094,6 +1149,17 @@ mac_test_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, } static int +mac_test_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, + struct mbuf *m, struct label *mlabel) +{ + + ASSERT_INPCB_LABEL(inplabel); + ASSERT_MBUF_LABEL(mlabel); + + return (0); +} + +static int mac_test_check_kenv_dump(struct ucred *cred) { @@ -1789,6 +1855,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_init_cred_label = mac_test_init_cred_label, .mpo_init_devfsdirent_label = mac_test_init_devfsdirent_label, .mpo_init_ifnet_label = mac_test_init_ifnet_label, + .mpo_init_inpcb_label = mac_test_init_inpcb_label, .mpo_init_ipq_label = mac_test_init_ipq_label, .mpo_init_mbuf_label = mac_test_init_mbuf_label, .mpo_init_mount_label = mac_test_init_mount_label, @@ -1802,6 +1869,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_destroy_cred_label = mac_test_destroy_cred_label, .mpo_destroy_devfsdirent_label = mac_test_destroy_devfsdirent_label, .mpo_destroy_ifnet_label = mac_test_destroy_ifnet_label, + .mpo_destroy_inpcb_label = mac_test_destroy_inpcb_label, .mpo_destroy_ipq_label = mac_test_destroy_ipq_label, .mpo_destroy_mbuf_label = mac_test_destroy_mbuf_label, .mpo_destroy_mount_label = mac_test_destroy_mount_label, @@ -1848,6 +1916,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_set_socket_peer_from_socket = mac_test_set_socket_peer_from_socket, .mpo_create_bpfdesc = mac_test_create_bpfdesc, .mpo_create_ifnet = mac_test_create_ifnet, + .mpo_create_inpcb_from_socket = mac_test_create_inpcb_from_socket, .mpo_create_datagram_from_ipq = mac_test_create_datagram_from_ipq, .mpo_create_fragment = mac_test_create_fragment, .mpo_create_ipq = mac_test_create_ipq, @@ -1862,6 +1931,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_reflect_mbuf_tcp = mac_test_reflect_mbuf_tcp, .mpo_relabel_ifnet = mac_test_relabel_ifnet, .mpo_update_ipq = mac_test_update_ipq, + .mpo_inpcb_sosetlabel = mac_test_inpcb_sosetlabel, .mpo_create_cred = mac_test_create_cred, .mpo_execve_transition = mac_test_execve_transition, .mpo_execve_will_transition = mac_test_execve_will_transition, @@ -1874,6 +1944,7 @@ static struct mac_policy_ops mac_test_ops = .mpo_check_cred_visible = mac_test_check_cred_visible, .mpo_check_ifnet_relabel = mac_test_check_ifnet_relabel, .mpo_check_ifnet_transmit = mac_test_check_ifnet_transmit, + .mpo_check_inpcb_deliver = mac_test_check_inpcb_deliver, .mpo_check_kenv_dump = mac_test_check_kenv_dump, .mpo_check_kenv_get = mac_test_check_kenv_get, .mpo_check_kenv_set = mac_test_check_kenv_set, diff --git a/sys/sys/mac.h b/sys/sys/mac.h index 8cb20ad..81dad5a 100644 --- a/sys/sys/mac.h +++ b/sys/sys/mac.h @@ -110,7 +110,9 @@ struct componentname; struct devfs_dirent; struct ifnet; struct ifreq; +struct inpcb; struct image_params; +struct inpcb; struct ipq; struct m_tag; struct mbuf; @@ -137,6 +139,7 @@ void mac_init_bpfdesc(struct bpf_d *); void mac_init_cred(struct ucred *); void mac_init_devfsdirent(struct devfs_dirent *); void mac_init_ifnet(struct ifnet *); +int mac_init_inpcb(struct inpcb *, int flag); int mac_init_ipq(struct ipq *, int flag); int mac_init_socket(struct socket *, int flag); void mac_init_pipe(struct pipe *); @@ -151,6 +154,7 @@ void mac_destroy_bpfdesc(struct bpf_d *); void mac_destroy_cred(struct ucred *); void mac_destroy_devfsdirent(struct devfs_dirent *); void mac_destroy_ifnet(struct ifnet *); +void mac_destroy_inpcb(struct inpcb *); void mac_destroy_ipq(struct ipq *); void mac_destroy_socket(struct socket *); void mac_destroy_pipe(struct pipe *); @@ -205,6 +209,7 @@ void mac_create_pipe(struct ucred *cred, struct pipe *pipe); */ void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); void mac_create_ifnet(struct ifnet *ifp); +void mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp); void mac_create_ipq(struct mbuf *fragment, struct ipq *ipq); void mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram); void mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment); @@ -219,6 +224,7 @@ int mac_fragment_match(struct mbuf *fragment, struct ipq *ipq); void mac_reflect_mbuf_icmp(struct mbuf *m); void mac_reflect_mbuf_tcp(struct mbuf *m); void mac_update_ipq(struct mbuf *fragment, struct ipq *ipq); +void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp); /* * Labeling event operations: processes. @@ -239,6 +245,7 @@ void mac_thread_userret(struct thread *td); int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet); int mac_check_cred_visible(struct ucred *u1, struct ucred *u2); int mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m); +int mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m); int mac_check_kenv_dump(struct ucred *cred); int mac_check_kenv_get(struct ucred *cred, char *name); int mac_check_kenv_set(struct ucred *cred, char *name, char *value); diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 3c72d09..518f883 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -54,6 +54,7 @@ struct acl; struct componentname; struct devfs_dirent; +struct inpcb; struct ipq; struct label; struct mac_policy_conf; @@ -86,6 +87,7 @@ struct mac_policy_ops { void (*mpo_init_cred_label)(struct label *label); void (*mpo_init_devfsdirent_label)(struct label *label); void (*mpo_init_ifnet_label)(struct label *label); + int (*mpo_init_inpcb_label)(struct label *label, int flag); int (*mpo_init_ipq_label)(struct label *label, int flag); int (*mpo_init_mbuf_label)(struct label *label, int flag); void (*mpo_init_mount_label)(struct label *label); @@ -99,6 +101,7 @@ struct mac_policy_ops { void (*mpo_destroy_cred_label)(struct label *label); void (*mpo_destroy_devfsdirent_label)(struct label *label); void (*mpo_destroy_ifnet_label)(struct label *label); + void (*mpo_destroy_inpcb_label)(struct label *label); void (*mpo_destroy_ipq_label)(struct label *label); void (*mpo_destroy_mbuf_label)(struct label *label); void (*mpo_destroy_mount_label)(struct label *label); @@ -212,6 +215,9 @@ struct mac_policy_ops { struct label *bpflabel); void (*mpo_create_ifnet)(struct ifnet *ifnet, struct label *ifnetlabel); + void (*mpo_create_inpcb_from_socket)(struct socket *so, + struct label *solabel, struct inpcb *inp, + struct label *inplabel); void (*mpo_create_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); @@ -251,6 +257,9 @@ struct mac_policy_ops { void (*mpo_update_ipq)(struct mbuf *fragment, struct label *fragmentlabel, struct ipq *ipq, struct label *ipqlabel); + void (*mpo_inpcb_sosetlabel)(struct socket *so, + struct label *label, struct inpcb *inp, + struct label *inplabel); /* * Labeling event operations: processes. @@ -286,6 +295,9 @@ struct mac_policy_ops { int (*mpo_check_ifnet_transmit)(struct ifnet *ifnet, struct label *ifnetlabel, struct mbuf *m, struct label *mbuflabel); + int (*mpo_check_inpcb_deliver)(struct inpcb *inp, + struct label *inplabel, struct mbuf *m, + struct label *mlabel); int (*mpo_check_kenv_dump)(struct ucred *cred); int (*mpo_check_kenv_get)(struct ucred *cred, char *name); int (*mpo_check_kenv_set)(struct ucred *cred, char *name, diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index e065c77..2a91a5c 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -232,6 +232,7 @@ struct pr_usrreqs { int *flagsp); int (*pru_sopoll)(struct socket *so, int events, struct ucred *cred, struct thread *td); + void (*pru_sosetlabel)(struct socket *so); }; int pru_accept_notsupp(struct socket *so, struct sockaddr **nam); @@ -244,6 +245,7 @@ int pru_listen_notsupp(struct socket *so, struct thread *td); int pru_rcvd_notsupp(struct socket *so, int flags); int pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags); int pru_sense_null(struct socket *so, struct stat *sb); +void pru_sosetlabel_null(struct socket *so); #endif /* _KERNEL */ -- cgit v1.1