Updated from Linux LTS 3.10.25 to 3.10.26
This commit is contained in:
@@ -3723,7 +3723,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
|
||||
u32 nlbl_sid;
|
||||
u32 nlbl_type;
|
||||
|
||||
selinux_skb_xfrm_sid(skb, &xfrm_sid);
|
||||
selinux_xfrm_skb_sid(skb, &xfrm_sid);
|
||||
selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
|
||||
|
||||
err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
|
||||
@@ -4228,8 +4228,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
|
||||
PEER__RECV, &ad);
|
||||
if (err)
|
||||
if (err) {
|
||||
selinux_netlbl_err(skb, err, 0);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (secmark_active) {
|
||||
@@ -4740,22 +4742,32 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
|
||||
* as fast and as clean as possible. */
|
||||
if (!selinux_policycap_netpeer)
|
||||
return selinux_ip_postroute_compat(skb, ifindex, family);
|
||||
#ifdef CONFIG_XFRM
|
||||
/* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
|
||||
* packet transformation so allow the packet to pass without any checks
|
||||
* since we'll have another chance to perform access control checks
|
||||
* when the packet is on it's final way out.
|
||||
* NOTE: there appear to be some IPv6 multicast cases where skb->dst
|
||||
* is NULL, in this case go ahead and apply access control. */
|
||||
if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
|
||||
return NF_ACCEPT;
|
||||
#endif
|
||||
|
||||
secmark_active = selinux_secmark_enabled();
|
||||
peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
|
||||
if (!secmark_active && !peerlbl_active)
|
||||
return NF_ACCEPT;
|
||||
|
||||
sk = skb->sk;
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
/* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
|
||||
* packet transformation so allow the packet to pass without any checks
|
||||
* since we'll have another chance to perform access control checks
|
||||
* when the packet is on it's final way out.
|
||||
* NOTE: there appear to be some IPv6 multicast cases where skb->dst
|
||||
* is NULL, in this case go ahead and apply access control.
|
||||
* is NULL, in this case go ahead and apply access control.
|
||||
* NOTE: if this is a local socket (skb->sk != NULL) that is in the
|
||||
* TCP listening state we cannot wait until the XFRM processing
|
||||
* is done as we will miss out on the SA label if we do;
|
||||
* unfortunately, this means more work, but it is only once per
|
||||
* connection. */
|
||||
if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
|
||||
!(sk != NULL && sk->sk_state == TCP_LISTEN))
|
||||
return NF_ACCEPT;
|
||||
#endif
|
||||
|
||||
if (sk == NULL) {
|
||||
/* Without an associated socket the packet is either coming
|
||||
* from the kernel or it is being forwarded; check the packet
|
||||
@@ -4783,6 +4795,25 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
|
||||
struct sk_security_struct *sksec = sk->sk_security;
|
||||
if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
|
||||
return NF_DROP;
|
||||
/* At this point, if the returned skb peerlbl is SECSID_NULL
|
||||
* and the packet has been through at least one XFRM
|
||||
* transformation then we must be dealing with the "final"
|
||||
* form of labeled IPsec packet; since we've already applied
|
||||
* all of our access controls on this packet we can safely
|
||||
* pass the packet. */
|
||||
if (skb_sid == SECSID_NULL) {
|
||||
switch (family) {
|
||||
case PF_INET:
|
||||
if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
|
||||
return NF_ACCEPT;
|
||||
break;
|
||||
case PF_INET6:
|
||||
if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
|
||||
return NF_ACCEPT;
|
||||
default:
|
||||
return NF_DROP_ERR(-ECONNREFUSED);
|
||||
}
|
||||
}
|
||||
if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
|
||||
return NF_DROP;
|
||||
secmark_perm = PACKET__SEND;
|
||||
@@ -5452,11 +5483,11 @@ static int selinux_setprocattr(struct task_struct *p,
|
||||
/* Check for ptracing, and update the task SID if ok.
|
||||
Otherwise, leave SID unchanged and fail. */
|
||||
ptsid = 0;
|
||||
task_lock(p);
|
||||
rcu_read_lock();
|
||||
tracer = ptrace_parent(p);
|
||||
if (tracer)
|
||||
ptsid = task_sid(tracer);
|
||||
task_unlock(p);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (tracer) {
|
||||
error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS,
|
||||
|
||||
@@ -47,6 +47,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb,
|
||||
int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
|
||||
struct common_audit_data *ad, u8 proto);
|
||||
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
|
||||
int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
|
||||
|
||||
static inline void selinux_xfrm_notify_policyload(void)
|
||||
{
|
||||
@@ -80,12 +81,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int
|
||||
static inline void selinux_xfrm_notify_policyload(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
|
||||
{
|
||||
*sid = SECSID_NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
|
||||
{
|
||||
int err = selinux_xfrm_decode_session(skb, sid, 0);
|
||||
BUG_ON(err);
|
||||
}
|
||||
|
||||
#endif /* _SELINUX_XFRM_H_ */
|
||||
|
||||
@@ -152,21 +152,13 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* LSM hook implementation that checks and/or returns the xfrm sid for the
|
||||
* incoming packet.
|
||||
*/
|
||||
|
||||
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
|
||||
static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
|
||||
u32 *sid, int ckall)
|
||||
{
|
||||
struct sec_path *sp;
|
||||
struct sec_path *sp = skb->sp;
|
||||
|
||||
*sid = SECSID_NULL;
|
||||
|
||||
if (skb == NULL)
|
||||
return 0;
|
||||
|
||||
sp = skb->sp;
|
||||
if (sp) {
|
||||
int i, sid_set = 0;
|
||||
|
||||
@@ -190,6 +182,45 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
|
||||
{
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct xfrm_state *x;
|
||||
|
||||
if (dst == NULL)
|
||||
return SECSID_NULL;
|
||||
x = dst->xfrm;
|
||||
if (x == NULL || !selinux_authorizable_xfrm(x))
|
||||
return SECSID_NULL;
|
||||
|
||||
return x->security->ctx_sid;
|
||||
}
|
||||
|
||||
/*
|
||||
* LSM hook implementation that checks and/or returns the xfrm sid for the
|
||||
* incoming packet.
|
||||
*/
|
||||
|
||||
int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
|
||||
{
|
||||
if (skb == NULL) {
|
||||
*sid = SECSID_NULL;
|
||||
return 0;
|
||||
}
|
||||
return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
|
||||
}
|
||||
|
||||
int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
|
||||
if (rc == 0 && *sid == SECSID_NULL)
|
||||
*sid = selinux_xfrm_skb_sid_egress(skb);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Security blob allocation for xfrm_policy and xfrm_state
|
||||
* CTX does not have a meaningful value on input
|
||||
|
||||
Reference in New Issue
Block a user