hooks.c (4342f70538b929b188c6e370fe24a155e6532eb2) hooks.c (1d1e1ded13568be81a0e19d228e310a48997bec8)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * NSA Security-Enhanced Linux (SELinux) security module
4 *
5 * This file contains the SELinux hook function implementations.
6 *
7 * Authors: Stephen Smalley, <sds@tycho.nsa.gov>
8 * Chris Vance, <cvance@nai.com>

--- 5678 unchanged lines hidden (view full) ---

5687 return 0;
5688}
5689
5690#ifdef CONFIG_NETFILTER
5691
5692static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
5693 const struct nf_hook_state *state)
5694{
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * NSA Security-Enhanced Linux (SELinux) security module
4 *
5 * This file contains the SELinux hook function implementations.
6 *
7 * Authors: Stephen Smalley, <sds@tycho.nsa.gov>
8 * Chris Vance, <cvance@nai.com>

--- 5678 unchanged lines hidden (view full) ---

5687 return 0;
5688}
5689
5690#ifdef CONFIG_NETFILTER
5691
5692static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
5693 const struct nf_hook_state *state)
5694{
5695 const struct net_device *indev = state->in;
5696 u16 family = state->pf;
5697 int err;
5695 int ifindex;
5696 u16 family;
5698 char *addrp;
5699 u32 peer_sid;
5700 struct common_audit_data ad;
5701 struct lsm_network_audit net = {0,};
5697 char *addrp;
5698 u32 peer_sid;
5699 struct common_audit_data ad;
5700 struct lsm_network_audit net = {0,};
5702 u8 secmark_active;
5703 u8 netlbl_active;
5704 u8 peerlbl_active;
5701 int secmark_active, peerlbl_active;
5705
5706 if (!selinux_policycap_netpeer())
5707 return NF_ACCEPT;
5708
5709 secmark_active = selinux_secmark_enabled();
5702
5703 if (!selinux_policycap_netpeer())
5704 return NF_ACCEPT;
5705
5706 secmark_active = selinux_secmark_enabled();
5710 netlbl_active = netlbl_enabled();
5711 peerlbl_active = selinux_peerlbl_enabled();
5712 if (!secmark_active && !peerlbl_active)
5713 return NF_ACCEPT;
5714
5707 peerlbl_active = selinux_peerlbl_enabled();
5708 if (!secmark_active && !peerlbl_active)
5709 return NF_ACCEPT;
5710
5711 family = state->pf;
5715 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5716 return NF_DROP;
5717
5712 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
5713 return NF_DROP;
5714
5715 ifindex = state->in->ifindex;
5718 ad.type = LSM_AUDIT_DATA_NET;
5719 ad.u.net = &net;
5716 ad.type = LSM_AUDIT_DATA_NET;
5717 ad.u.net = &net;
5720 ad.u.net->netif = indev->ifindex;
5718 ad.u.net->netif = ifindex;
5721 ad.u.net->family = family;
5722 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5723 return NF_DROP;
5724
5725 if (peerlbl_active) {
5719 ad.u.net->family = family;
5720 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
5721 return NF_DROP;
5722
5723 if (peerlbl_active) {
5726 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
5724 int err;
5725
5726 err = selinux_inet_sys_rcv_skb(state->net, ifindex,
5727 addrp, family, peer_sid, &ad);
5728 if (err) {
5729 selinux_netlbl_err(skb, family, err, 1);
5730 return NF_DROP;
5731 }
5732 }
5733
5734 if (secmark_active)
5735 if (avc_has_perm(&selinux_state,
5736 peer_sid, skb->secmark,
5737 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5738 return NF_DROP;
5739
5727 addrp, family, peer_sid, &ad);
5728 if (err) {
5729 selinux_netlbl_err(skb, family, err, 1);
5730 return NF_DROP;
5731 }
5732 }
5733
5734 if (secmark_active)
5735 if (avc_has_perm(&selinux_state,
5736 peer_sid, skb->secmark,
5737 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
5738 return NF_DROP;
5739
5740 if (netlbl_active)
5740 if (netlbl_enabled())
5741 /* we do this in the FORWARD path and not the POST_ROUTING
5742 * path because we want to make sure we apply the necessary
5743 * labeling before IPsec is applied so we can leverage AH
5744 * protection */
5745 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5746 return NF_DROP;
5747
5748 return NF_ACCEPT;
5749}
5750
5751static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
5752 const struct nf_hook_state *state)
5753{
5741 /* we do this in the FORWARD path and not the POST_ROUTING
5742 * path because we want to make sure we apply the necessary
5743 * labeling before IPsec is applied so we can leverage AH
5744 * protection */
5745 if (selinux_netlbl_skbuff_setsid(skb, family, peer_sid) != 0)
5746 return NF_DROP;
5747
5748 return NF_ACCEPT;
5749}
5750
5751static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
5752 const struct nf_hook_state *state)
5753{
5754 u16 family = state->pf;
5755 struct sock *sk;
5756 u32 sid;
5757
5758 if (!netlbl_enabled())
5759 return NF_ACCEPT;
5760
5761 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5762 * because we want to make sure we apply the necessary labeling

--- 17 unchanged lines hidden (view full) ---

5780 * best we can do. */
5781 return NF_ACCEPT;
5782
5783 /* standard practice, label using the parent socket */
5784 sksec = sk->sk_security;
5785 sid = sksec->sid;
5786 } else
5787 sid = SECINITSID_KERNEL;
5754 struct sock *sk;
5755 u32 sid;
5756
5757 if (!netlbl_enabled())
5758 return NF_ACCEPT;
5759
5760 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
5761 * because we want to make sure we apply the necessary labeling

--- 17 unchanged lines hidden (view full) ---

5779 * best we can do. */
5780 return NF_ACCEPT;
5781
5782 /* standard practice, label using the parent socket */
5783 sksec = sk->sk_security;
5784 sid = sksec->sid;
5785 } else
5786 sid = SECINITSID_KERNEL;
5788 if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
5787 if (selinux_netlbl_skbuff_setsid(skb, state->pf, sid) != 0)
5789 return NF_DROP;
5790
5791 return NF_ACCEPT;
5792}
5793
5794
5795static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5788 return NF_DROP;
5789
5790 return NF_ACCEPT;
5791}
5792
5793
5794static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
5796 int ifindex,
5797 u16 family)
5795 const struct nf_hook_state *state)
5798{
5796{
5799 struct sock *sk = skb_to_full_sk(skb);
5797 struct sock *sk;
5800 struct sk_security_struct *sksec;
5801 struct common_audit_data ad;
5802 struct lsm_network_audit net = {0,};
5798 struct sk_security_struct *sksec;
5799 struct common_audit_data ad;
5800 struct lsm_network_audit net = {0,};
5803 char *addrp;
5804 u8 proto;
5805
5801 u8 proto;
5802
5806 if (sk == NULL)
5803 if (state->sk == NULL)
5807 return NF_ACCEPT;
5804 return NF_ACCEPT;
5805 sk = skb_to_full_sk(skb);
5808 sksec = sk->sk_security;
5809
5810 ad.type = LSM_AUDIT_DATA_NET;
5811 ad.u.net = &net;
5806 sksec = sk->sk_security;
5807
5808 ad.type = LSM_AUDIT_DATA_NET;
5809 ad.u.net = &net;
5812 ad.u.net->netif = ifindex;
5813 ad.u.net->family = family;
5814 if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
5810 ad.u.net->netif = state->out->ifindex;
5811 ad.u.net->family = state->pf;
5812 if (selinux_parse_skb(skb, &ad, NULL, 0, &proto))
5815 return NF_DROP;
5816
5817 if (selinux_secmark_enabled())
5818 if (avc_has_perm(&selinux_state,
5819 sksec->sid, skb->secmark,
5820 SECCLASS_PACKET, PACKET__SEND, &ad))
5821 return NF_DROP_ERR(-ECONNREFUSED);
5822
5823 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5824 return NF_DROP_ERR(-ECONNREFUSED);
5825
5826 return NF_ACCEPT;
5827}
5828
5829static unsigned int selinux_ip_postroute(void *priv,
5830 struct sk_buff *skb,
5831 const struct nf_hook_state *state)
5832{
5813 return NF_DROP;
5814
5815 if (selinux_secmark_enabled())
5816 if (avc_has_perm(&selinux_state,
5817 sksec->sid, skb->secmark,
5818 SECCLASS_PACKET, PACKET__SEND, &ad))
5819 return NF_DROP_ERR(-ECONNREFUSED);
5820
5821 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
5822 return NF_DROP_ERR(-ECONNREFUSED);
5823
5824 return NF_ACCEPT;
5825}
5826
5827static unsigned int selinux_ip_postroute(void *priv,
5828 struct sk_buff *skb,
5829 const struct nf_hook_state *state)
5830{
5833 const struct net_device *outdev = state->out;
5834 u16 family = state->pf;
5831 u16 family;
5835 u32 secmark_perm;
5836 u32 peer_sid;
5832 u32 secmark_perm;
5833 u32 peer_sid;
5837 int ifindex = outdev->ifindex;
5834 int ifindex;
5838 struct sock *sk;
5839 struct common_audit_data ad;
5840 struct lsm_network_audit net = {0,};
5841 char *addrp;
5835 struct sock *sk;
5836 struct common_audit_data ad;
5837 struct lsm_network_audit net = {0,};
5838 char *addrp;
5842 u8 secmark_active;
5843 u8 peerlbl_active;
5839 int secmark_active, peerlbl_active;
5844
5845 /* If any sort of compatibility mode is enabled then handoff processing
5846 * to the selinux_ip_postroute_compat() function to deal with the
5847 * special handling. We do this in an attempt to keep this function
5848 * as fast and as clean as possible. */
5849 if (!selinux_policycap_netpeer())
5840
5841 /* If any sort of compatibility mode is enabled then handoff processing
5842 * to the selinux_ip_postroute_compat() function to deal with the
5843 * special handling. We do this in an attempt to keep this function
5844 * as fast and as clean as possible. */
5845 if (!selinux_policycap_netpeer())
5850 return selinux_ip_postroute_compat(skb, ifindex, family);
5846 return selinux_ip_postroute_compat(skb, state);
5851
5852 secmark_active = selinux_secmark_enabled();
5853 peerlbl_active = selinux_peerlbl_enabled();
5854 if (!secmark_active && !peerlbl_active)
5855 return NF_ACCEPT;
5856
5857 sk = skb_to_full_sk(skb);
5858

--- 9 unchanged lines hidden (view full) ---

5868 * is done as we will miss out on the SA label if we do;
5869 * unfortunately, this means more work, but it is only once per
5870 * connection. */
5871 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
5872 !(sk && sk_listener(sk)))
5873 return NF_ACCEPT;
5874#endif
5875
5847
5848 secmark_active = selinux_secmark_enabled();
5849 peerlbl_active = selinux_peerlbl_enabled();
5850 if (!secmark_active && !peerlbl_active)
5851 return NF_ACCEPT;
5852
5853 sk = skb_to_full_sk(skb);
5854

--- 9 unchanged lines hidden (view full) ---

5864 * is done as we will miss out on the SA label if we do;
5865 * unfortunately, this means more work, but it is only once per
5866 * connection. */
5867 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
5868 !(sk && sk_listener(sk)))
5869 return NF_ACCEPT;
5870#endif
5871
5872 family = state->pf;
5876 if (sk == NULL) {
5877 /* Without an associated socket the packet is either coming
5878 * from the kernel or it is being forwarded; check the packet
5879 * to determine which and if the packet is being forwarded
5880 * query the packet directly to determine the security label. */
5881 if (skb->skb_iif) {
5882 secmark_perm = PACKET__FORWARD_OUT;
5883 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))

--- 44 unchanged lines hidden (view full) ---

5928 } else {
5929 /* Locally generated packet, fetch the security label from the
5930 * associated socket. */
5931 struct sk_security_struct *sksec = sk->sk_security;
5932 peer_sid = sksec->sid;
5933 secmark_perm = PACKET__SEND;
5934 }
5935
5873 if (sk == NULL) {
5874 /* Without an associated socket the packet is either coming
5875 * from the kernel or it is being forwarded; check the packet
5876 * to determine which and if the packet is being forwarded
5877 * query the packet directly to determine the security label. */
5878 if (skb->skb_iif) {
5879 secmark_perm = PACKET__FORWARD_OUT;
5880 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))

--- 44 unchanged lines hidden (view full) ---

5925 } else {
5926 /* Locally generated packet, fetch the security label from the
5927 * associated socket. */
5928 struct sk_security_struct *sksec = sk->sk_security;
5929 peer_sid = sksec->sid;
5930 secmark_perm = PACKET__SEND;
5931 }
5932
5933 ifindex = state->out->ifindex;
5936 ad.type = LSM_AUDIT_DATA_NET;
5937 ad.u.net = &net;
5938 ad.u.net->netif = ifindex;
5939 ad.u.net->family = family;
5940 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
5941 return NF_DROP;
5942
5943 if (secmark_active)
5944 if (avc_has_perm(&selinux_state,
5945 peer_sid, skb->secmark,
5946 SECCLASS_PACKET, secmark_perm, &ad))
5947 return NF_DROP_ERR(-ECONNREFUSED);
5948
5949 if (peerlbl_active) {
5950 u32 if_sid;
5951 u32 node_sid;
5952
5934 ad.type = LSM_AUDIT_DATA_NET;
5935 ad.u.net = &net;
5936 ad.u.net->netif = ifindex;
5937 ad.u.net->family = family;
5938 if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
5939 return NF_DROP;
5940
5941 if (secmark_active)
5942 if (avc_has_perm(&selinux_state,
5943 peer_sid, skb->secmark,
5944 SECCLASS_PACKET, secmark_perm, &ad))
5945 return NF_DROP_ERR(-ECONNREFUSED);
5946
5947 if (peerlbl_active) {
5948 u32 if_sid;
5949 u32 node_sid;
5950
5953 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
5951 if (sel_netif_sid(state->net, ifindex, &if_sid))
5954 return NF_DROP;
5955 if (avc_has_perm(&selinux_state,
5956 peer_sid, if_sid,
5957 SECCLASS_NETIF, NETIF__EGRESS, &ad))
5958 return NF_DROP_ERR(-ECONNREFUSED);
5959
5960 if (sel_netnode_sid(addrp, family, &node_sid))
5961 return NF_DROP;

--- 1597 unchanged lines hidden ---
5952 return NF_DROP;
5953 if (avc_has_perm(&selinux_state,
5954 peer_sid, if_sid,
5955 SECCLASS_NETIF, NETIF__EGRESS, &ad))
5956 return NF_DROP_ERR(-ECONNREFUSED);
5957
5958 if (sel_netnode_sid(addrp, family, &node_sid))
5959 return NF_DROP;

--- 1597 unchanged lines hidden ---