Commit dfaebe98 authored by Paul Moore's avatar Paul Moore

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: default avatarPaul Moore <paul.moore@hp.com>
Acked-by: default avatarJames Morris <jmorris@namei.org>
parent 99d854d2
...@@ -382,7 +382,7 @@ int netlbl_sock_getattr(struct sock *sk, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) ...@@ -4396,6 +4402,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
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, ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment