cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfrm.c (11560B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  NSA Security-Enhanced Linux (SELinux) security module
      4 *
      5 *  This file contains the SELinux XFRM hook function implementations.
      6 *
      7 *  Authors:  Serge Hallyn <sergeh@us.ibm.com>
      8 *	      Trent Jaeger <jaegert@us.ibm.com>
      9 *
     10 *  Updated: Venkat Yekkirala <vyekkirala@TrustedCS.com>
     11 *
     12 *           Granular IPSec Associations for use in MLS environments.
     13 *
     14 *  Copyright (C) 2005 International Business Machines Corporation
     15 *  Copyright (C) 2006 Trusted Computer Solutions, Inc.
     16 */
     17
     18/*
     19 * USAGE:
     20 * NOTES:
     21 *   1. Make sure to enable the following options in your kernel config:
     22 *	CONFIG_SECURITY=y
     23 *	CONFIG_SECURITY_NETWORK=y
     24 *	CONFIG_SECURITY_NETWORK_XFRM=y
     25 *	CONFIG_SECURITY_SELINUX=m/y
     26 * ISSUES:
     27 *   1. Caching packets, so they are not dropped during negotiation
     28 *   2. Emulating a reasonable SO_PEERSEC across machines
     29 *   3. Testing addition of sk_policy's with security context via setsockopt
     30 */
     31#include <linux/kernel.h>
     32#include <linux/init.h>
     33#include <linux/security.h>
     34#include <linux/types.h>
     35#include <linux/slab.h>
     36#include <linux/ip.h>
     37#include <linux/tcp.h>
     38#include <linux/skbuff.h>
     39#include <linux/xfrm.h>
     40#include <net/xfrm.h>
     41#include <net/checksum.h>
     42#include <net/udp.h>
     43#include <linux/atomic.h>
     44
     45#include "avc.h"
     46#include "objsec.h"
     47#include "xfrm.h"
     48
     49/* Labeled XFRM instance counter */
     50atomic_t selinux_xfrm_refcount __read_mostly = ATOMIC_INIT(0);
     51
     52/*
     53 * Returns true if the context is an LSM/SELinux context.
     54 */
     55static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
     56{
     57	return (ctx &&
     58		(ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
     59		(ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
     60}
     61
     62/*
     63 * Returns true if the xfrm contains a security blob for SELinux.
     64 */
     65static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
     66{
     67	return selinux_authorizable_ctx(x->security);
     68}
     69
     70/*
     71 * Allocates a xfrm_sec_state and populates it using the supplied security
     72 * xfrm_user_sec_ctx context.
     73 */
     74static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
     75				   struct xfrm_user_sec_ctx *uctx,
     76				   gfp_t gfp)
     77{
     78	int rc;
     79	const struct task_security_struct *tsec = selinux_cred(current_cred());
     80	struct xfrm_sec_ctx *ctx = NULL;
     81	u32 str_len;
     82
     83	if (ctxp == NULL || uctx == NULL ||
     84	    uctx->ctx_doi != XFRM_SC_DOI_LSM ||
     85	    uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
     86		return -EINVAL;
     87
     88	str_len = uctx->ctx_len;
     89	if (str_len >= PAGE_SIZE)
     90		return -ENOMEM;
     91
     92	ctx = kmalloc(struct_size(ctx, ctx_str, str_len + 1), gfp);
     93	if (!ctx)
     94		return -ENOMEM;
     95
     96	ctx->ctx_doi = XFRM_SC_DOI_LSM;
     97	ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
     98	ctx->ctx_len = str_len;
     99	memcpy(ctx->ctx_str, &uctx[1], str_len);
    100	ctx->ctx_str[str_len] = '\0';
    101	rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len,
    102				     &ctx->ctx_sid, gfp);
    103	if (rc)
    104		goto err;
    105
    106	rc = avc_has_perm(&selinux_state,
    107			  tsec->sid, ctx->ctx_sid,
    108			  SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
    109	if (rc)
    110		goto err;
    111
    112	*ctxp = ctx;
    113	atomic_inc(&selinux_xfrm_refcount);
    114	return 0;
    115
    116err:
    117	kfree(ctx);
    118	return rc;
    119}
    120
    121/*
    122 * Free the xfrm_sec_ctx structure.
    123 */
    124static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
    125{
    126	if (!ctx)
    127		return;
    128
    129	atomic_dec(&selinux_xfrm_refcount);
    130	kfree(ctx);
    131}
    132
    133/*
    134 * Authorize the deletion of a labeled SA or policy rule.
    135 */
    136static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
    137{
    138	const struct task_security_struct *tsec = selinux_cred(current_cred());
    139
    140	if (!ctx)
    141		return 0;
    142
    143	return avc_has_perm(&selinux_state,
    144			    tsec->sid, ctx->ctx_sid,
    145			    SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
    146			    NULL);
    147}
    148
    149/*
    150 * LSM hook implementation that authorizes that a flow can use a xfrm policy
    151 * rule.
    152 */
    153int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid)
    154{
    155	int rc;
    156
    157	/* All flows should be treated as polmatch'ing an otherwise applicable
    158	 * "non-labeled" policy. This would prevent inadvertent "leaks". */
    159	if (!ctx)
    160		return 0;
    161
    162	/* Context sid is either set to label or ANY_ASSOC */
    163	if (!selinux_authorizable_ctx(ctx))
    164		return -EINVAL;
    165
    166	rc = avc_has_perm(&selinux_state,
    167			  fl_secid, ctx->ctx_sid,
    168			  SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
    169	return (rc == -EACCES ? -ESRCH : rc);
    170}
    171
    172/*
    173 * LSM hook implementation that authorizes that a state matches
    174 * the given policy, flow combo.
    175 */
    176int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
    177				      struct xfrm_policy *xp,
    178				      const struct flowi_common *flic)
    179{
    180	u32 state_sid;
    181	u32 flic_sid;
    182
    183	if (!xp->security)
    184		if (x->security)
    185			/* unlabeled policy and labeled SA can't match */
    186			return 0;
    187		else
    188			/* unlabeled policy and unlabeled SA match all flows */
    189			return 1;
    190	else
    191		if (!x->security)
    192			/* unlabeled SA and labeled policy can't match */
    193			return 0;
    194		else
    195			if (!selinux_authorizable_xfrm(x))
    196				/* Not a SELinux-labeled SA */
    197				return 0;
    198
    199	state_sid = x->security->ctx_sid;
    200	flic_sid = flic->flowic_secid;
    201
    202	if (flic_sid != state_sid)
    203		return 0;
    204
    205	/* We don't need a separate SA Vs. policy polmatch check since the SA
    206	 * is now of the same label as the flow and a flow Vs. policy polmatch
    207	 * check had already happened in selinux_xfrm_policy_lookup() above. */
    208	return (avc_has_perm(&selinux_state, flic_sid, state_sid,
    209			     SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
    210			     NULL) ? 0 : 1);
    211}
    212
    213static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
    214{
    215	struct dst_entry *dst = skb_dst(skb);
    216	struct xfrm_state *x;
    217
    218	if (dst == NULL)
    219		return SECSID_NULL;
    220	x = dst->xfrm;
    221	if (x == NULL || !selinux_authorizable_xfrm(x))
    222		return SECSID_NULL;
    223
    224	return x->security->ctx_sid;
    225}
    226
    227static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
    228					u32 *sid, int ckall)
    229{
    230	u32 sid_session = SECSID_NULL;
    231	struct sec_path *sp = skb_sec_path(skb);
    232
    233	if (sp) {
    234		int i;
    235
    236		for (i = sp->len - 1; i >= 0; i--) {
    237			struct xfrm_state *x = sp->xvec[i];
    238			if (selinux_authorizable_xfrm(x)) {
    239				struct xfrm_sec_ctx *ctx = x->security;
    240
    241				if (sid_session == SECSID_NULL) {
    242					sid_session = ctx->ctx_sid;
    243					if (!ckall)
    244						goto out;
    245				} else if (sid_session != ctx->ctx_sid) {
    246					*sid = SECSID_NULL;
    247					return -EINVAL;
    248				}
    249			}
    250		}
    251	}
    252
    253out:
    254	*sid = sid_session;
    255	return 0;
    256}
    257
    258/*
    259 * LSM hook implementation that checks and/or returns the xfrm sid for the
    260 * incoming packet.
    261 */
    262int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
    263{
    264	if (skb == NULL) {
    265		*sid = SECSID_NULL;
    266		return 0;
    267	}
    268	return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
    269}
    270
    271int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
    272{
    273	int rc;
    274
    275	rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
    276	if (rc == 0 && *sid == SECSID_NULL)
    277		*sid = selinux_xfrm_skb_sid_egress(skb);
    278
    279	return rc;
    280}
    281
    282/*
    283 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
    284 */
    285int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
    286			      struct xfrm_user_sec_ctx *uctx,
    287			      gfp_t gfp)
    288{
    289	return selinux_xfrm_alloc_user(ctxp, uctx, gfp);
    290}
    291
    292/*
    293 * LSM hook implementation that copies security data structure from old to new
    294 * for policy cloning.
    295 */
    296int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
    297			      struct xfrm_sec_ctx **new_ctxp)
    298{
    299	struct xfrm_sec_ctx *new_ctx;
    300
    301	if (!old_ctx)
    302		return 0;
    303
    304	new_ctx = kmemdup(old_ctx, sizeof(*old_ctx) + old_ctx->ctx_len,
    305			  GFP_ATOMIC);
    306	if (!new_ctx)
    307		return -ENOMEM;
    308	atomic_inc(&selinux_xfrm_refcount);
    309	*new_ctxp = new_ctx;
    310
    311	return 0;
    312}
    313
    314/*
    315 * LSM hook implementation that frees xfrm_sec_ctx security information.
    316 */
    317void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
    318{
    319	selinux_xfrm_free(ctx);
    320}
    321
    322/*
    323 * LSM hook implementation that authorizes deletion of labeled policies.
    324 */
    325int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
    326{
    327	return selinux_xfrm_delete(ctx);
    328}
    329
    330/*
    331 * LSM hook implementation that allocates a xfrm_sec_state, populates it using
    332 * the supplied security context, and assigns it to the xfrm_state.
    333 */
    334int selinux_xfrm_state_alloc(struct xfrm_state *x,
    335			     struct xfrm_user_sec_ctx *uctx)
    336{
    337	return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL);
    338}
    339
    340/*
    341 * LSM hook implementation that allocates a xfrm_sec_state and populates based
    342 * on a secid.
    343 */
    344int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
    345				     struct xfrm_sec_ctx *polsec, u32 secid)
    346{
    347	int rc;
    348	struct xfrm_sec_ctx *ctx;
    349	char *ctx_str = NULL;
    350	u32 str_len;
    351
    352	if (!polsec)
    353		return 0;
    354
    355	if (secid == 0)
    356		return -EINVAL;
    357
    358	rc = security_sid_to_context(&selinux_state, secid, &ctx_str,
    359				     &str_len);
    360	if (rc)
    361		return rc;
    362
    363	ctx = kmalloc(struct_size(ctx, ctx_str, str_len), GFP_ATOMIC);
    364	if (!ctx) {
    365		rc = -ENOMEM;
    366		goto out;
    367	}
    368
    369	ctx->ctx_doi = XFRM_SC_DOI_LSM;
    370	ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
    371	ctx->ctx_sid = secid;
    372	ctx->ctx_len = str_len;
    373	memcpy(ctx->ctx_str, ctx_str, str_len);
    374
    375	x->security = ctx;
    376	atomic_inc(&selinux_xfrm_refcount);
    377out:
    378	kfree(ctx_str);
    379	return rc;
    380}
    381
    382/*
    383 * LSM hook implementation that frees xfrm_state security information.
    384 */
    385void selinux_xfrm_state_free(struct xfrm_state *x)
    386{
    387	selinux_xfrm_free(x->security);
    388}
    389
    390/*
    391 * LSM hook implementation that authorizes deletion of labeled SAs.
    392 */
    393int selinux_xfrm_state_delete(struct xfrm_state *x)
    394{
    395	return selinux_xfrm_delete(x->security);
    396}
    397
    398/*
    399 * LSM hook that controls access to unlabelled packets.  If
    400 * a xfrm_state is authorizable (defined by macro) then it was
    401 * already authorized by the IPSec process.  If not, then
    402 * we need to check for unlabelled access since this may not have
    403 * gone thru the IPSec process.
    404 */
    405int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
    406			      struct common_audit_data *ad)
    407{
    408	int i;
    409	struct sec_path *sp = skb_sec_path(skb);
    410	u32 peer_sid = SECINITSID_UNLABELED;
    411
    412	if (sp) {
    413		for (i = 0; i < sp->len; i++) {
    414			struct xfrm_state *x = sp->xvec[i];
    415
    416			if (x && selinux_authorizable_xfrm(x)) {
    417				struct xfrm_sec_ctx *ctx = x->security;
    418				peer_sid = ctx->ctx_sid;
    419				break;
    420			}
    421		}
    422	}
    423
    424	/* This check even when there's no association involved is intended,
    425	 * according to Trent Jaeger, to make sure a process can't engage in
    426	 * non-IPsec communication unless explicitly allowed by policy. */
    427	return avc_has_perm(&selinux_state,
    428			    sk_sid, peer_sid,
    429			    SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
    430}
    431
    432/*
    433 * POSTROUTE_LAST hook's XFRM processing:
    434 * If we have no security association, then we need to determine
    435 * whether the socket is allowed to send to an unlabelled destination.
    436 * If we do have a authorizable security association, then it has already been
    437 * checked in the selinux_xfrm_state_pol_flow_match hook above.
    438 */
    439int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
    440				struct common_audit_data *ad, u8 proto)
    441{
    442	struct dst_entry *dst;
    443
    444	switch (proto) {
    445	case IPPROTO_AH:
    446	case IPPROTO_ESP:
    447	case IPPROTO_COMP:
    448		/* We should have already seen this packet once before it
    449		 * underwent xfrm(s). No need to subject it to the unlabeled
    450		 * check. */
    451		return 0;
    452	default:
    453		break;
    454	}
    455
    456	dst = skb_dst(skb);
    457	if (dst) {
    458		struct dst_entry *iter;
    459
    460		for (iter = dst; iter != NULL; iter = xfrm_dst_child(iter)) {
    461			struct xfrm_state *x = iter->xfrm;
    462
    463			if (x && selinux_authorizable_xfrm(x))
    464				return 0;
    465		}
    466	}
    467
    468	/* This check even when there's no association involved is intended,
    469	 * according to Trent Jaeger, to make sure a process can't engage in
    470	 * non-IPsec communication unless explicitly allowed by policy. */
    471	return avc_has_perm(&selinux_state, sk_sid, SECINITSID_UNLABELED,
    472			    SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
    473}