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