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