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/netfilter.h>
  39#include <linux/netfilter_ipv4.h>
  40#include <linux/netfilter_ipv6.h>
  41#include <linux/ip.h>
  42#include <linux/tcp.h>
  43#include <linux/skbuff.h>
  44#include <linux/xfrm.h>
  45#include <net/xfrm.h>
  46#include <net/checksum.h>
  47#include <net/udp.h>
  48#include <asm/atomic.h>
  49
  50#include "avc.h"
  51#include "objsec.h"
  52#include "xfrm.h"
  53
  54/* Labeled XFRM instance counter */
  55atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0);
  56
  57/*
  58 * Returns true if an LSM/SELinux context
  59 */
  60static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
  61{
  62        return (ctx &&
  63                (ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
  64                (ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
  65}
  66
  67/*
  68 * Returns true if the xfrm contains a security blob for SELinux
  69 */
  70static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
  71{
  72        return selinux_authorizable_ctx(x->security);
  73}
  74
  75/*
  76 * LSM hook implementation that authorizes that a flow can use
  77 * a xfrm policy rule.
  78 */
  79int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
  80{
  81        int rc;
  82        u32 sel_sid;
  83
  84        /* Context sid is either set to label or ANY_ASSOC */
  85        if (ctx) {
  86                if (!selinux_authorizable_ctx(ctx))
  87                        return -EINVAL;
  88
  89                sel_sid = ctx->ctx_sid;
  90        } else
  91                /*
  92                 * All flows should be treated as polmatch'ing an
  93                 * otherwise applicable "non-labeled" policy. This
  94                 * would prevent inadvertent "leaks".
  95                 */
  96                return 0;
  97
  98        rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION,
  99                          ASSOCIATION__POLMATCH,
 100                          NULL);
 101
 102        if (rc == -EACCES)
 103                return -ESRCH;
 104
 105        return rc;
 106}
 107
 108/*
 109 * LSM hook implementation that authorizes that a state matches
 110 * the given policy, flow combo.
 111 */
 112
 113int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp,
 114                        struct flowi *fl)
 115{
 116        u32 state_sid;
 117        int rc;
 118
 119        if (!xp->security)
 120                if (x->security)
 121                        /* unlabeled policy and labeled SA can't match */
 122                        return 0;
 123                else
 124                        /* unlabeled policy and unlabeled SA match all flows */
 125                        return 1;
 126        else
 127                if (!x->security)
 128                        /* unlabeled SA and labeled policy can't match */
 129                        return 0;
 130                else
 131                        if (!selinux_authorizable_xfrm(x))
 132                                /* Not a SELinux-labeled SA */
 133                                return 0;
 134
 135        state_sid = x->security->ctx_sid;
 136
 137        if (fl->secid != state_sid)
 138                return 0;
 139
 140        rc = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
 141                          ASSOCIATION__SENDTO,
 142                          NULL)? 0:1;
 143
 144        /*
 145         * We don't need a separate SA Vs. policy polmatch check
 146         * since the SA is now of the same label as the flow and
 147         * a flow Vs. policy polmatch check had already happened
 148         * in selinux_xfrm_policy_lookup() above.
 149         */
 150
 151        return rc;
 152}
 153
 154/*
 155 * LSM hook implementation that checks and/or returns the xfrm sid for the
 156 * incoming packet.
 157 */
 158
 159int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
 160{
 161        struct sec_path *sp;
 162
 163        *sid = SECSID_NULL;
 164
 165        if (skb == NULL)
 166                return 0;
 167
 168        sp = skb->sp;
 169        if (sp) {
 170                int i, sid_set = 0;
 171
 172                for (i = sp->len-1; i >= 0; i--) {
 173                        struct xfrm_state *x = sp->xvec[i];
 174                        if (selinux_authorizable_xfrm(x)) {
 175                                struct xfrm_sec_ctx *ctx = x->security;
 176
 177                                if (!sid_set) {
 178                                        *sid = ctx->ctx_sid;
 179                                        sid_set = 1;
 180
 181                                        if (!ckall)
 182                                                break;
 183                                } else if (*sid != ctx->ctx_sid)
 184                                        return -EINVAL;
 185                        }
 186                }
 187        }
 188
 189        return 0;
 190}
 191
 192/*
 193 * Security blob allocation for xfrm_policy and xfrm_state
 194 * CTX does not have a meaningful value on input
 195 */
 196static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
 197        struct xfrm_user_sec_ctx *uctx, u32 sid)
 198{
 199        int rc = 0;
 200        struct task_security_struct *tsec = current->security;
 201        struct xfrm_sec_ctx *ctx = NULL;
 202        char *ctx_str = NULL;
 203        u32 str_len;
 204
 205        BUG_ON(uctx && sid);
 206
 207        if (!uctx)
 208                goto not_from_user;
 209
 210        if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX)
 211                return -EINVAL;
 212
 213        str_len = uctx->ctx_len;
 214        if (str_len >= PAGE_SIZE)
 215                return -ENOMEM;
 216
 217        *ctxp = ctx = kmalloc(sizeof(*ctx) +
 218                              str_len + 1,
 219                              GFP_KERNEL);
 220
 221        if (!ctx)
 222                return -ENOMEM;
 223
 224        ctx->ctx_doi = uctx->ctx_doi;
 225        ctx->ctx_len = str_len;
 226        ctx->ctx_alg = uctx->ctx_alg;
 227
 228        memcpy(ctx->ctx_str,
 229               uctx+1,
 230               str_len);
 231        ctx->ctx_str[str_len] = 0;
 232        rc = security_context_to_sid(ctx->ctx_str,
 233                                     str_len,
 234                                     &ctx->ctx_sid);
 235
 236        if (rc)
 237                goto out;
 238
 239        /*
 240         * Does the subject have permission to set security context?
 241         */
 242        rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 243                          SECCLASS_ASSOCIATION,
 244                          ASSOCIATION__SETCONTEXT, NULL);
 245        if (rc)
 246                goto out;
 247
 248        return rc;
 249
 250not_from_user:
 251        rc = security_sid_to_context(sid, &ctx_str, &str_len);
 252        if (rc)
 253                goto out;
 254
 255        *ctxp = ctx = kmalloc(sizeof(*ctx) +
 256                              str_len,
 257                              GFP_ATOMIC);
 258
 259        if (!ctx) {
 260                rc = -ENOMEM;
 261                goto out;
 262        }
 263
 264        ctx->ctx_doi = XFRM_SC_DOI_LSM;
 265        ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
 266        ctx->ctx_sid = sid;
 267        ctx->ctx_len = str_len;
 268        memcpy(ctx->ctx_str,
 269               ctx_str,
 270               str_len);
 271
 272        goto out2;
 273
 274out:
 275        *ctxp = NULL;
 276        kfree(ctx);
 277out2:
 278        kfree(ctx_str);
 279        return rc;
 280}
 281
 282/*
 283 * LSM hook implementation that allocs and transfers uctx spec to
 284 * xfrm_policy.
 285 */
 286int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
 287                              struct xfrm_user_sec_ctx *uctx)
 288{
 289        int err;
 290
 291        BUG_ON(!uctx);
 292
 293        err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
 294        if (err == 0)
 295                atomic_inc(&selinux_xfrm_refcount);
 296
 297        return err;
 298}
 299
 300
 301/*
 302 * LSM hook implementation that copies security data structure from old to
 303 * new for policy cloning.
 304 */
 305int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
 306                              struct xfrm_sec_ctx **new_ctxp)
 307{
 308        struct xfrm_sec_ctx *new_ctx;
 309
 310        if (old_ctx) {
 311                new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len,
 312                                  GFP_KERNEL);
 313                if (!new_ctx)
 314                        return -ENOMEM;
 315
 316                memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
 317                memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
 318                *new_ctxp = new_ctx;
 319        }
 320        return 0;
 321}
 322
 323/*
 324 * LSM hook implementation that frees xfrm_sec_ctx security information.
 325 */
 326void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 327{
 328        kfree(ctx);
 329}
 330
 331/*
 332 * LSM hook implementation that authorizes deletion of labeled policies.
 333 */
 334int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 335{
 336        struct task_security_struct *tsec = current->security;
 337        int rc = 0;
 338
 339        if (ctx) {
 340                rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 341                                  SECCLASS_ASSOCIATION,
 342                                  ASSOCIATION__SETCONTEXT, NULL);
 343                if (rc == 0)
 344                        atomic_dec(&selinux_xfrm_refcount);
 345        }
 346
 347        return rc;
 348}
 349
 350/*
 351 * LSM hook implementation that allocs and transfers sec_ctx spec to
 352 * xfrm_state.
 353 */
 354int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx,
 355                u32 secid)
 356{
 357        int err;
 358
 359        BUG_ON(!x);
 360
 361        err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
 362        if (err == 0)
 363                atomic_inc(&selinux_xfrm_refcount);
 364        return err;
 365}
 366
 367/*
 368 * LSM hook implementation that frees xfrm_state security information.
 369 */
 370void selinux_xfrm_state_free(struct xfrm_state *x)
 371{
 372        struct xfrm_sec_ctx *ctx = x->security;
 373        kfree(ctx);
 374}
 375
 376 /*
 377  * LSM hook implementation that authorizes deletion of labeled SAs.
 378  */
 379int selinux_xfrm_state_delete(struct xfrm_state *x)
 380{
 381        struct task_security_struct *tsec = current->security;
 382        struct xfrm_sec_ctx *ctx = x->security;
 383        int rc = 0;
 384
 385        if (ctx) {
 386                rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 387                                  SECCLASS_ASSOCIATION,
 388                                  ASSOCIATION__SETCONTEXT, NULL);
 389                if (rc == 0)
 390                        atomic_dec(&selinux_xfrm_refcount);
 391        }
 392
 393        return rc;
 394}
 395
 396/*
 397 * LSM hook that controls access to unlabelled packets.  If
 398 * a xfrm_state is authorizable (defined by macro) then it was
 399 * already authorized by the IPSec process.  If not, then
 400 * we need to check for unlabelled access since this may not have
 401 * gone thru the IPSec process.
 402 */
 403int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
 404                                struct avc_audit_data *ad)
 405{
 406        int i, rc = 0;
 407        struct sec_path *sp;
 408        u32 sel_sid = SECINITSID_UNLABELED;
 409
 410        sp = skb->sp;
 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                                sel_sid = ctx->ctx_sid;
 419                                break;
 420                        }
 421                }
 422        }
 423
 424        /*
 425         * This check even when there's no association involved is
 426         * intended, according to Trent Jaeger, to make sure a
 427         * process can't engage in non-ipsec communication unless
 428         * explicitly allowed by policy.
 429         */
 430
 431        rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
 432                          ASSOCIATION__RECVFROM, ad);
 433
 434        return rc;
 435}
 436
 437/*
 438 * POSTROUTE_LAST hook's XFRM processing:
 439 * If we have no security association, then we need to determine
 440 * whether the socket is allowed to send to an unlabelled destination.
 441 * If we do have a authorizable security association, then it has already been
 442 * checked in the selinux_xfrm_state_pol_flow_match hook above.
 443 */
 444int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
 445                                        struct avc_audit_data *ad, u8 proto)
 446{
 447        struct dst_entry *dst;
 448        int rc = 0;
 449
 450        dst = skb->dst;
 451
 452        if (dst) {
 453                struct dst_entry *dst_test;
 454
 455                for (dst_test = dst; dst_test != NULL;
 456                     dst_test = dst_test->child) {
 457                        struct xfrm_state *x = dst_test->xfrm;
 458
 459                        if (x && selinux_authorizable_xfrm(x))
 460                                goto out;
 461                }
 462        }
 463
 464        switch (proto) {
 465        case IPPROTO_AH:
 466        case IPPROTO_ESP:
 467        case IPPROTO_COMP:
 468                /*
 469                 * We should have already seen this packet once before
 470                 * it underwent xfrm(s). No need to subject it to the
 471                 * unlabeled check.
 472                 */
 473                goto out;
 474        default:
 475                break;
 476        }
 477
 478        /*
 479         * This check even when there's no association involved is
 480         * intended, according to Trent Jaeger, to make sure a
 481         * process can't engage in non-ipsec communication unless
 482         * explicitly allowed by policy.
 483         */
 484
 485        rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
 486                          ASSOCIATION__SENDTO, ad);
 487out:
 488        return rc;
 489}
 490