selinux: Fix missing calls to netlbl_skbuff_err()
At some point I think I messed up and dropped the calls to netlbl_skbuff_err() which are necessary for CIPSO to send error notifications to remote systems. This patch re-introduces the error handling calls into the SELinux code. Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
99d854d231
commit
dfaebe9825
|
@ -382,7 +382,7 @@ int netlbl_sock_getattr(struct sock *sk,
|
||||||
int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||||
u16 family,
|
u16 family,
|
||||||
struct netlbl_lsm_secattr *secattr);
|
struct netlbl_lsm_secattr *secattr);
|
||||||
void netlbl_skbuff_err(struct sk_buff *skb, int error);
|
void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LSM label mapping cache operations
|
* LSM label mapping cache operations
|
||||||
|
@ -454,7 +454,9 @@ static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
static inline void netlbl_skbuff_err(struct sk_buff *skb, int error)
|
static inline void netlbl_skbuff_err(struct sk_buff *skb,
|
||||||
|
int error,
|
||||||
|
int gateway)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -490,6 +490,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||||
* netlbl_skbuff_err - Handle a LSM error on a sk_buff
|
* netlbl_skbuff_err - Handle a LSM error on a sk_buff
|
||||||
* @skb: the packet
|
* @skb: the packet
|
||||||
* @error: the error code
|
* @error: the error code
|
||||||
|
* @gateway: true if host is acting as a gateway, false otherwise
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Deal with a LSM problem when handling the packet in @skb, typically this is
|
* Deal with a LSM problem when handling the packet in @skb, typically this is
|
||||||
|
@ -497,10 +498,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
|
||||||
* according to the packet's labeling protocol.
|
* according to the packet's labeling protocol.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void netlbl_skbuff_err(struct sk_buff *skb, int error)
|
void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
|
||||||
{
|
{
|
||||||
if (CIPSO_V4_OPTEXIST(skb))
|
if (CIPSO_V4_OPTEXIST(skb))
|
||||||
cipso_v4_error(skb, error, 0);
|
cipso_v4_error(skb, error, gateway);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4101,6 +4101,8 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
|
||||||
return err;
|
return err;
|
||||||
err = avc_has_perm(sk_sid, peer_sid,
|
err = avc_has_perm(sk_sid, peer_sid,
|
||||||
SECCLASS_PEER, PEER__RECV, &ad);
|
SECCLASS_PEER, PEER__RECV, &ad);
|
||||||
|
if (err)
|
||||||
|
selinux_netlbl_err(skb, err, 0);
|
||||||
} else {
|
} else {
|
||||||
err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
|
err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -4156,10 +4158,14 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
||||||
return err;
|
return err;
|
||||||
err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
|
err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
|
||||||
peer_sid, &ad);
|
peer_sid, &ad);
|
||||||
if (err)
|
if (err) {
|
||||||
|
selinux_netlbl_err(skb, err, 0);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
|
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
|
||||||
PEER__RECV, &ad);
|
PEER__RECV, &ad);
|
||||||
|
if (err)
|
||||||
|
selinux_netlbl_err(skb, err, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secmark_active) {
|
if (secmark_active) {
|
||||||
|
@ -4396,6 +4402,7 @@ out:
|
||||||
static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
|
static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
|
||||||
u16 family)
|
u16 family)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
char *addrp;
|
char *addrp;
|
||||||
u32 peer_sid;
|
u32 peer_sid;
|
||||||
struct avc_audit_data ad;
|
struct avc_audit_data ad;
|
||||||
|
@ -4419,10 +4426,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
|
||||||
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) {
|
||||||
if (selinux_inet_sys_rcv_skb(ifindex, addrp, family,
|
err = selinux_inet_sys_rcv_skb(ifindex, addrp, family,
|
||||||
peer_sid, &ad) != 0)
|
peer_sid, &ad);
|
||||||
|
if (err) {
|
||||||
|
selinux_netlbl_err(skb, err, 1);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (secmark_active)
|
if (secmark_active)
|
||||||
if (avc_has_perm(peer_sid, skb->secmark,
|
if (avc_has_perm(peer_sid, skb->secmark,
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#ifdef CONFIG_NETLABEL
|
#ifdef CONFIG_NETLABEL
|
||||||
void selinux_netlbl_cache_invalidate(void);
|
void selinux_netlbl_cache_invalidate(void);
|
||||||
|
|
||||||
|
void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
|
||||||
|
|
||||||
void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
|
void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,
|
||||||
int family);
|
int family);
|
||||||
|
|
||||||
|
@ -63,6 +65,13 @@ static inline void selinux_netlbl_cache_invalidate(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void selinux_netlbl_err(struct sk_buff *skb,
|
||||||
|
int error,
|
||||||
|
int gateway)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void selinux_netlbl_sk_security_reset(
|
static inline void selinux_netlbl_sk_security_reset(
|
||||||
struct sk_security_struct *ssec,
|
struct sk_security_struct *ssec,
|
||||||
int family)
|
int family)
|
||||||
|
|
|
@ -107,6 +107,24 @@ void selinux_netlbl_cache_invalidate(void)
|
||||||
netlbl_cache_invalidate();
|
netlbl_cache_invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* selinux_netlbl_err - Handle a NetLabel packet error
|
||||||
|
* @skb: the packet
|
||||||
|
* @error: the error code
|
||||||
|
* @gateway: true if host is acting as a gateway, false otherwise
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* When a packet is dropped due to a call to avc_has_perm() pass the error
|
||||||
|
* code to the NetLabel subsystem so any protocol specific processing can be
|
||||||
|
* done. This is safe to call even if you are unsure if NetLabel labeling is
|
||||||
|
* present on the packet, NetLabel is smart enough to only act when it should.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
|
||||||
|
{
|
||||||
|
netlbl_skbuff_err(skb, error, gateway);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* selinux_netlbl_sk_security_reset - Reset the NetLabel fields
|
* selinux_netlbl_sk_security_reset - Reset the NetLabel fields
|
||||||
* @ssec: the sk_security_struct
|
* @ssec: the sk_security_struct
|
||||||
|
@ -289,7 +307,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (nlbl_sid != SECINITSID_UNLABELED)
|
if (nlbl_sid != SECINITSID_UNLABELED)
|
||||||
netlbl_skbuff_err(skb, rc);
|
netlbl_skbuff_err(skb, rc, 0);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue