Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dfaebe98 authored by Paul Moore's avatar Paul Moore
Browse files

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
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -382,7 +382,7 @@ int netlbl_sock_getattr(struct sock *sk,
int netlbl_skbuff_getattr(const struct sk_buff *skb,
			  u16 family,
			  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
@@ -454,7 +454,9 @@ static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
{
	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;
}
+3 −2
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
 * netlbl_skbuff_err - Handle a LSM error on a sk_buff
 * @skb: the packet
 * @error: the error code
 * @gateway: true if host is acting as a gateway, false otherwise
 *
 * Description:
 * 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.
 *
 */
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))
		cipso_v4_error(skb, error, 0);
		cipso_v4_error(skb, error, gateway);
}

/**
+15 −4
Original line number Diff line number Diff line
@@ -4101,6 +4101,8 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
			return err;
		err = avc_has_perm(sk_sid, peer_sid,
				   SECCLASS_PEER, PEER__RECV, &ad);
		if (err)
			selinux_netlbl_err(skb, err, 0);
	} else {
		err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
		if (err)
@@ -4156,10 +4158,14 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
			return err;
		err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
					       peer_sid, &ad);
		if (err)
		if (err) {
			selinux_netlbl_err(skb, err, 0);
			return err;
		}
		err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
				   PEER__RECV, &ad);
		if (err)
			selinux_netlbl_err(skb, err, 0);
	}

	if (secmark_active) {
@@ -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,
				       u16 family)
{
	int err;
	char *addrp;
	u32 peer_sid;
	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)
		return NF_DROP;

	if (peerlbl_active)
		if (selinux_inet_sys_rcv_skb(ifindex, addrp, family,
					     peer_sid, &ad) != 0)
	if (peerlbl_active) {
		err = selinux_inet_sys_rcv_skb(ifindex, addrp, family,
					       peer_sid, &ad);
		if (err) {
			selinux_netlbl_err(skb, err, 1);
			return NF_DROP;
		}
	}

	if (secmark_active)
		if (avc_has_perm(peer_sid, skb->secmark,
+9 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@
#ifdef CONFIG_NETLABEL
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,
				      int family);

@@ -63,6 +65,13 @@ static inline void selinux_netlbl_cache_invalidate(void)
	return;
}

static inline void selinux_netlbl_err(struct sk_buff *skb,
				      int error,
				      int gateway)
{
	return;
}

static inline void selinux_netlbl_sk_security_reset(
					       struct sk_security_struct *ssec,
					       int family)
+19 −1
Original line number Diff line number Diff line
@@ -107,6 +107,24 @@ void selinux_netlbl_cache_invalidate(void)
	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
 * @ssec: the sk_security_struct
@@ -289,7 +307,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
		return 0;

	if (nlbl_sid != SECINITSID_UNLABELED)
		netlbl_skbuff_err(skb, rc);
		netlbl_skbuff_err(skb, rc, 0);
	return rc;
}