Skip to content

Commit

Permalink
selinux: look for IPsec labels on both inbound and outbound packets
Browse files Browse the repository at this point in the history
commit 817eff7 upstream.

Previously selinux_skb_peerlbl_sid() would only check for labeled
IPsec security labels on inbound packets, this patch enables it to
check both inbound and outbound traffic for labeled IPsec security
labels.

Reported-by: Janak Desai <Janak.Desai@gtri.gatech.edu>
Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Paul Moore authored and Greg Kroah-Hartman committed Jan 9, 2014
1 parent 2a1f1a8 commit 3577781
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
2 changes: 1 addition & 1 deletion security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3792,7 +3792,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);
Expand Down
9 changes: 5 additions & 4 deletions security/selinux/include/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -85,12 +86,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int
static inline void selinux_xfrm_notify_policyload(void)
{
}
#endif

static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
{
int err = selinux_xfrm_decode_session(skb, sid, 0);
BUG_ON(err);
*sid = SECSID_NULL;
return 0;
}
#endif

#endif /* _SELINUX_XFRM_H_ */
53 changes: 42 additions & 11 deletions security/selinux/xfrm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Down

0 comments on commit 3577781

Please sign in to comment.