summaryrefslogtreecommitdiff
path: root/security/selinux/xfrm.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2013-12-19 19:18:53 +0400
committerFelipe Balbi <balbi@ti.com>2013-12-19 19:18:53 +0400
commitc139e1425ff7bec7ac22ed90acbadb1b7aa091a9 (patch)
treec6b091d2dfce26ce80238ef278f2bc7b3b473cad /security/selinux/xfrm.c
parent4a5ee77caad2a99b86d6bdd5f0064a60224a0760 (diff)
parent319e2e3f63c348a9b66db4667efa73178e18b17d (diff)
downloadlinux-c139e1425ff7bec7ac22ed90acbadb1b7aa091a9.tar.xz
Merge tag 'v3.13-rc4' into next
Linux 3.13-rc4 * tag 'v3.13-rc4': (1001 commits) Linux 3.13-rc4 null_blk: mem garbage on NUMA systems during init radeon_pm: fix oops in hwmon_attributes_visible() and radeon_hwmon_show_temp_thresh() Revert "selinux: consider filesystem subtype in policies" igb: Fix for issue where values could be too high for udelay function. i40e: fix null dereference ARM: fix asm/memory.h build error dm array: fix a reference counting bug in shadow_ablock dm space map: disallow decrementing a reference count below zero mm: memcg: do not allow task about to OOM kill to bypass the limit mm: memcg: fix race condition between memcg teardown and swapin thp: move preallocated PTE page table on move_huge_pmd() mfd/rtc: s5m: fix register updating by adding regmap for RTC rtc: s5m: enable IRQ wake during suspend rtc: s5m: limit endless loop waiting for register update rtc: s5m: fix unsuccesful IRQ request during probe drivers/rtc/rtc-s5m.c: fix info->rtc assignment include/linux/kernel.h: make might_fault() a nop for !MMU drivers/rtc/rtc-at91rm9200.c: correct alarm over day/month wrap procfs: also fix proc_reg_get_unmapped_area() for !MMU case ... Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'security/selinux/xfrm.c')
-rw-r--r--security/selinux/xfrm.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index a91d205ec0c6..0462cb3ff0a7 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -209,19 +209,26 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
NULL) ? 0 : 1);
}
-/*
- * 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 u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
{
- u32 sid_session = SECSID_NULL;
- struct sec_path *sp;
+ struct dst_entry *dst = skb_dst(skb);
+ struct xfrm_state *x;
- if (skb == NULL)
- goto out;
+ if (dst == NULL)
+ return SECSID_NULL;
+ x = dst->xfrm;
+ if (x == NULL || !selinux_authorizable_xfrm(x))
+ return SECSID_NULL;
+
+ return x->security->ctx_sid;
+}
+
+static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
+ u32 *sid, int ckall)
+{
+ u32 sid_session = SECSID_NULL;
+ struct sec_path *sp = skb->sp;
- sp = skb->sp;
if (sp) {
int i;
@@ -248,6 +255,30 @@ out:
}
/*
+ * 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;
+}
+
+/*
* LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
*/
int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
@@ -327,19 +358,22 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
return rc;
ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
- if (!ctx)
- return -ENOMEM;
+ if (!ctx) {
+ rc = -ENOMEM;
+ goto out;
+ }
ctx->ctx_doi = XFRM_SC_DOI_LSM;
ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
ctx->ctx_sid = secid;
ctx->ctx_len = str_len;
memcpy(ctx->ctx_str, ctx_str, str_len);
- kfree(ctx_str);
x->security = ctx;
atomic_inc(&selinux_xfrm_refcount);
- return 0;
+out:
+ kfree(ctx_str);
+ return rc;
}
/*