selinux: make better use of the nf_hook_state passed to the NF hooks
This patch builds on a previous SELinux/netfilter patch by Florian Westphal and makes better use of the nf_hook_state variable passed into the SELinux/netfilter hooks as well as a number of other small cleanups in the related code. Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
parent
cbfcd13be5
commit
1d1e1ded13
|
@ -5692,38 +5692,38 @@ static int selinux_tun_dev_open(void *security)
|
||||||
static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
|
static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state)
|
const struct nf_hook_state *state)
|
||||||
{
|
{
|
||||||
const struct net_device *indev = state->in;
|
int ifindex;
|
||||||
u16 family = state->pf;
|
u16 family;
|
||||||
int err;
|
|
||||||
char *addrp;
|
char *addrp;
|
||||||
u32 peer_sid;
|
u32 peer_sid;
|
||||||
struct common_audit_data ad;
|
struct common_audit_data ad;
|
||||||
struct lsm_network_audit net = {0,};
|
struct lsm_network_audit net = {0,};
|
||||||
u8 secmark_active;
|
int secmark_active, peerlbl_active;
|
||||||
u8 netlbl_active;
|
|
||||||
u8 peerlbl_active;
|
|
||||||
|
|
||||||
if (!selinux_policycap_netpeer())
|
if (!selinux_policycap_netpeer())
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
secmark_active = selinux_secmark_enabled();
|
secmark_active = selinux_secmark_enabled();
|
||||||
netlbl_active = netlbl_enabled();
|
|
||||||
peerlbl_active = selinux_peerlbl_enabled();
|
peerlbl_active = selinux_peerlbl_enabled();
|
||||||
if (!secmark_active && !peerlbl_active)
|
if (!secmark_active && !peerlbl_active)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
family = state->pf;
|
||||||
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
|
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
|
ifindex = state->in->ifindex;
|
||||||
ad.type = LSM_AUDIT_DATA_NET;
|
ad.type = LSM_AUDIT_DATA_NET;
|
||||||
ad.u.net = &net;
|
ad.u.net = &net;
|
||||||
ad.u.net->netif = indev->ifindex;
|
ad.u.net->netif = ifindex;
|
||||||
ad.u.net->family = family;
|
ad.u.net->family = family;
|
||||||
if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
|
if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
if (peerlbl_active) {
|
if (peerlbl_active) {
|
||||||
err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
|
int err;
|
||||||
|
|
||||||
|
err = selinux_inet_sys_rcv_skb(state->net, ifindex,
|
||||||
addrp, family, peer_sid, &ad);
|
addrp, family, peer_sid, &ad);
|
||||||
if (err) {
|
if (err) {
|
||||||
selinux_netlbl_err(skb, family, err, 1);
|
selinux_netlbl_err(skb, family, err, 1);
|
||||||
|
@ -5737,7 +5737,7 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
|
||||||
SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
|
SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
if (netlbl_active)
|
if (netlbl_enabled())
|
||||||
/* we do this in the FORWARD path and not the POST_ROUTING
|
/* we do this in the FORWARD path and not the POST_ROUTING
|
||||||
* path because we want to make sure we apply the necessary
|
* path because we want to make sure we apply the necessary
|
||||||
* labeling before IPsec is applied so we can leverage AH
|
* labeling before IPsec is applied so we can leverage AH
|
||||||
|
@ -5751,7 +5751,6 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
|
||||||
static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
|
static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state)
|
const struct nf_hook_state *state)
|
||||||
{
|
{
|
||||||
u16 family = state->pf;
|
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
u32 sid;
|
u32 sid;
|
||||||
|
|
||||||
|
@ -5785,7 +5784,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
|
||||||
sid = sksec->sid;
|
sid = sksec->sid;
|
||||||
} else
|
} else
|
||||||
sid = SECINITSID_KERNEL;
|
sid = SECINITSID_KERNEL;
|
||||||
if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
|
if (selinux_netlbl_skbuff_setsid(skb, state->pf, sid) != 0)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
@ -5793,25 +5792,24 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
|
||||||
|
|
||||||
|
|
||||||
static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
||||||
int ifindex,
|
const struct nf_hook_state *state)
|
||||||
u16 family)
|
|
||||||
{
|
{
|
||||||
struct sock *sk = skb_to_full_sk(skb);
|
struct sock *sk;
|
||||||
struct sk_security_struct *sksec;
|
struct sk_security_struct *sksec;
|
||||||
struct common_audit_data ad;
|
struct common_audit_data ad;
|
||||||
struct lsm_network_audit net = {0,};
|
struct lsm_network_audit net = {0,};
|
||||||
char *addrp;
|
|
||||||
u8 proto;
|
u8 proto;
|
||||||
|
|
||||||
if (sk == NULL)
|
if (state->sk == NULL)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
sk = skb_to_full_sk(skb);
|
||||||
sksec = sk->sk_security;
|
sksec = sk->sk_security;
|
||||||
|
|
||||||
ad.type = LSM_AUDIT_DATA_NET;
|
ad.type = LSM_AUDIT_DATA_NET;
|
||||||
ad.u.net = &net;
|
ad.u.net = &net;
|
||||||
ad.u.net->netif = ifindex;
|
ad.u.net->netif = state->out->ifindex;
|
||||||
ad.u.net->family = family;
|
ad.u.net->family = state->pf;
|
||||||
if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
|
if (selinux_parse_skb(skb, &ad, NULL, 0, &proto))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
if (selinux_secmark_enabled())
|
if (selinux_secmark_enabled())
|
||||||
|
@ -5830,24 +5828,22 @@ static unsigned int selinux_ip_postroute(void *priv,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
const struct nf_hook_state *state)
|
const struct nf_hook_state *state)
|
||||||
{
|
{
|
||||||
const struct net_device *outdev = state->out;
|
u16 family;
|
||||||
u16 family = state->pf;
|
|
||||||
u32 secmark_perm;
|
u32 secmark_perm;
|
||||||
u32 peer_sid;
|
u32 peer_sid;
|
||||||
int ifindex = outdev->ifindex;
|
int ifindex;
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct common_audit_data ad;
|
struct common_audit_data ad;
|
||||||
struct lsm_network_audit net = {0,};
|
struct lsm_network_audit net = {0,};
|
||||||
char *addrp;
|
char *addrp;
|
||||||
u8 secmark_active;
|
int secmark_active, peerlbl_active;
|
||||||
u8 peerlbl_active;
|
|
||||||
|
|
||||||
/* If any sort of compatibility mode is enabled then handoff processing
|
/* If any sort of compatibility mode is enabled then handoff processing
|
||||||
* to the selinux_ip_postroute_compat() function to deal with the
|
* to the selinux_ip_postroute_compat() function to deal with the
|
||||||
* special handling. We do this in an attempt to keep this function
|
* special handling. We do this in an attempt to keep this function
|
||||||
* as fast and as clean as possible. */
|
* as fast and as clean as possible. */
|
||||||
if (!selinux_policycap_netpeer())
|
if (!selinux_policycap_netpeer())
|
||||||
return selinux_ip_postroute_compat(skb, ifindex, family);
|
return selinux_ip_postroute_compat(skb, state);
|
||||||
|
|
||||||
secmark_active = selinux_secmark_enabled();
|
secmark_active = selinux_secmark_enabled();
|
||||||
peerlbl_active = selinux_peerlbl_enabled();
|
peerlbl_active = selinux_peerlbl_enabled();
|
||||||
|
@ -5873,6 +5869,7 @@ static unsigned int selinux_ip_postroute(void *priv,
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
family = state->pf;
|
||||||
if (sk == NULL) {
|
if (sk == NULL) {
|
||||||
/* Without an associated socket the packet is either coming
|
/* Without an associated socket the packet is either coming
|
||||||
* from the kernel or it is being forwarded; check the packet
|
* from the kernel or it is being forwarded; check the packet
|
||||||
|
@ -5933,6 +5930,7 @@ static unsigned int selinux_ip_postroute(void *priv,
|
||||||
secmark_perm = PACKET__SEND;
|
secmark_perm = PACKET__SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifindex = state->out->ifindex;
|
||||||
ad.type = LSM_AUDIT_DATA_NET;
|
ad.type = LSM_AUDIT_DATA_NET;
|
||||||
ad.u.net = &net;
|
ad.u.net = &net;
|
||||||
ad.u.net->netif = ifindex;
|
ad.u.net->netif = ifindex;
|
||||||
|
@ -5950,7 +5948,7 @@ static unsigned int selinux_ip_postroute(void *priv,
|
||||||
u32 if_sid;
|
u32 if_sid;
|
||||||
u32 node_sid;
|
u32 node_sid;
|
||||||
|
|
||||||
if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
|
if (sel_netif_sid(state->net, ifindex, &if_sid))
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
if (avc_has_perm(&selinux_state,
|
if (avc_has_perm(&selinux_state,
|
||||||
peer_sid, if_sid,
|
peer_sid, if_sid,
|
||||||
|
|
Loading…
Reference in New Issue