// SPDX-License-Identifier: GPL-2.0-only /* * Security-Enhanced Linux (SELinux) security module * * This file contains the SELinux XFRM hook function implementations. * * Authors: Serge Hallyn <[email protected]> * Trent Jaeger <[email protected]> * * Updated: Venkat Yekkirala <[email protected]> * * Granular IPSec Associations for use in MLS environments. * * Copyright (C) 2005 International Business Machines Corporation * Copyright (C) 2006 Trusted Computer Solutions, Inc. */ /* * USAGE: * NOTES: * 1. Make sure to enable the following options in your kernel config: * CONFIG_SECURITY=y * CONFIG_SECURITY_NETWORK=y * CONFIG_SECURITY_NETWORK_XFRM=y * CONFIG_SECURITY_SELINUX=m/y * ISSUES: * 1. Caching packets, so they are not dropped during negotiation * 2. Emulating a reasonable SO_PEERSEC across machines * 3. Testing addition of sk_policy's with security context via setsockopt */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/security.h> #include <linux/types.h> #include <linux/slab.h> #include <linux/ip.h> #include <linux/tcp.h> #include <linux/skbuff.h> #include <linux/xfrm.h> #include <net/xfrm.h> #include <net/checksum.h> #include <net/udp.h> #include <linux/atomic.h> #include "avc.h" #include "objsec.h" #include "xfrm.h" /* Labeled XFRM instance counter */ atomic_t selinux_xfrm_refcount __read_mostly = …; /* * Returns true if the context is an LSM/SELinux context. */ static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx) { … } /* * Returns true if the xfrm contains a security blob for SELinux. */ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) { … } /* * Allocates a xfrm_sec_state and populates it using the supplied security * xfrm_user_sec_ctx context. */ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx, gfp_t gfp) { … } /* * Free the xfrm_sec_ctx structure. */ static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx) { … } /* * Authorize the deletion of a labeled SA or policy rule. */ static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx) { … } /* * LSM hook implementation that authorizes that a flow can use a xfrm policy * rule. */ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid) { … } /* * LSM hook implementation that authorizes that a state matches * the given policy, flow combo. */ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, const struct flowi_common *flic) { … } static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb) { … } static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb, u32 *sid, int ckall) { … } /* * 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) { … } int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) { … } /* * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. */ int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx, gfp_t gfp) { … } /* * LSM hook implementation that copies security data structure from old to new * for policy cloning. */ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp) { … } /* * LSM hook implementation that frees xfrm_sec_ctx security information. */ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) { … } /* * LSM hook implementation that authorizes deletion of labeled policies. */ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) { … } /* * LSM hook implementation that allocates a xfrm_sec_state, populates it using * the supplied security context, and assigns it to the xfrm_state. */ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx) { … } /* * LSM hook implementation that allocates a xfrm_sec_state and populates based * on a secid. */ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid) { … } /* * LSM hook implementation that frees xfrm_state security information. */ void selinux_xfrm_state_free(struct xfrm_state *x) { … } /* * LSM hook implementation that authorizes deletion of labeled SAs. */ int selinux_xfrm_state_delete(struct xfrm_state *x) { … } /* * LSM hook that controls access to unlabelled packets. If * a xfrm_state is authorizable (defined by macro) then it was * already authorized by the IPSec process. If not, then * we need to check for unlabelled access since this may not have * gone thru the IPSec process. */ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb, struct common_audit_data *ad) { … } /* * POSTROUTE_LAST hook's XFRM processing: * If we have no security association, then we need to determine * whether the socket is allowed to send to an unlabelled destination. * If we do have a authorizable security association, then it has already been * checked in the selinux_xfrm_state_pol_flow_match hook above. */ int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, struct common_audit_data *ad, u8 proto) { … }