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 --- |