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_KERNEL);
 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                *new_ctxp = new_ctx;
 320        }
 321        return 0;
 322}
 323
 324/*
 325 * LSM hook implementation that frees xfrm_sec_ctx security information.
 326 */
 327void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
 328{
 329        kfree(ctx);
 330}
 331
 332/*
 333 * LSM hook implementation that authorizes deletion of labeled policies.
 334 */
 335int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
 336{
 337        const struct task_security_struct *tsec = current_security();
 338        int rc = 0;
 339
 340        if (ctx) {
 341                rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 342                                  SECCLASS_ASSOCIATION,
 343                                  ASSOCIATION__SETCONTEXT, NULL);
 344                if (rc == 0)
 345                        atomic_dec(&selinux_xfrm_refcount);
 346        }
 347
 348        return rc;
 349}
 350
 351/*
 352 * LSM hook implementation that allocs and transfers sec_ctx spec to
 353 * xfrm_state.
 354 */
 355int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx,
 356                u32 secid)
 357{
 358        int err;
 359
 360        BUG_ON(!x);
 361
 362        err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
 363        if (err == 0)
 364                atomic_inc(&selinux_xfrm_refcount);
 365        return err;
 366}
 367
 368/*
 369 * LSM hook implementation that frees xfrm_state security information.
 370 */
 371void selinux_xfrm_state_free(struct xfrm_state *x)
 372{
 373        struct xfrm_sec_ctx *ctx = x->security;
 374        kfree(ctx);
 375}
 376
 377 /*
 378  * LSM hook implementation that authorizes deletion of labeled SAs.
 379  */
 380int selinux_xfrm_state_delete(struct xfrm_state *x)
 381{
 382        const struct task_security_struct *tsec = current_security();
 383        struct xfrm_sec_ctx *ctx = x->security;
 384        int rc = 0;
 385
 386        if (ctx) {
 387                rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 388                                  SECCLASS_ASSOCIATION,
 389                                  ASSOCIATION__SETCONTEXT, NULL);
 390                if (rc == 0)
 391                        atomic_dec(&selinux_xfrm_refcount);
 392        }
 393
 394        return rc;
 395}
 396
 397/*
 398 * LSM hook that controls access to unlabelled packets.  If
 399 * a xfrm_state is authorizable (defined by macro) then it was
 400 * already authorized by the IPSec process.  If not, then
 401 * we need to check for unlabelled access since this may not have
 402 * gone thru the IPSec process.
 403 */
 404int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
 405                                struct common_audit_data *ad)
 406{
 407        int i, rc = 0;
 408        struct sec_path *sp;
 409        u32 sel_sid = SECINITSID_UNLABELED;
 410
 411        sp = skb->sp;
 412
 413        if (sp) {
 414                for (i = 0; i < sp->len; i++) {
 415                        struct xfrm_state *x = sp->xvec[i];
 416
 417                        if (x && selinux_authorizable_xfrm(x)) {
 418                                struct xfrm_sec_ctx *ctx = x->security;
 419                                sel_sid = ctx->ctx_sid;
 420                                break;
 421                        }
 422                }
 423        }
 424
 425        /*
 426         * This check even when there's no association involved is
 427         * intended, according to Trent Jaeger, to make sure a
 428         * process can't engage in non-ipsec communication unless
 429         * explicitly allowed by policy.
 430         */
 431
 432        rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
 433                          ASSOCIATION__RECVFROM, ad);
 434
 435        return rc;
 436}
 437
 438/*
 439 * POSTROUTE_LAST hook's XFRM processing:
 440 * If we have no security association, then we need to determine
 441 * whether the socket is allowed to send to an unlabelled destination.
 442 * If we do have a authorizable security association, then it has already been
 443 * checked in the selinux_xfrm_state_pol_flow_match hook above.
 444 */
 445int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
 446                                        struct common_audit_data *ad, u8 proto)
 447{
 448        struct dst_entry *dst;
 449        int rc = 0;
 450
 451        dst = skb_dst(skb);
 452
 453        if (dst) {
 454                struct dst_entry *dst_test;
 455
 456                for (dst_test = dst; dst_test != NULL;
 457                     dst_test = dst_test->child) {
 458                        struct xfrm_state *x = dst_test->xfrm;
 459
 460                        if (x && selinux_authorizable_xfrm(x))
 461                                goto out;
 462                }
 463        }
 464
 465        switch (proto) {
 466        case IPPROTO_AH:
 467        case IPPROTO_ESP:
 468        case IPPROTO_COMP:
 469                /*
 470                 * We should have already seen this packet once before
 471                 * it underwent xfrm(s). No need to subject it to the
 472                 * unlabeled check.
 473                 */
 474                goto out;
 475        default:
 476                break;
 477        }
 478
 479        /*
 480         * This check even when there's no association involved is
 481         * intended, according to Trent Jaeger, to make sure a
 482         * process can't engage in non-ipsec communication unless
 483         * explicitly allowed by policy.
 484         */
 485
 486        rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
 487                          ASSOCIATION__SENDTO, ad);
 488out:
 489        return rc;
 490}
 491
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.