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/semaphore.h>
  49
  50#include "avc.h"
  51#include "objsec.h"
  52#include "xfrm.h"
  53
  54
  55/*
  56 * Returns true if 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 * LSM hook implementation that authorizes that a flow can use
  75 * a xfrm policy rule.
  76 */
  77int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
  78{
  79        int rc;
  80        u32 sel_sid;
  81        struct xfrm_sec_ctx *ctx;
  82
  83        /* Context sid is either set to label or ANY_ASSOC */
  84        if ((ctx = xp->security)) {
  85                if (!selinux_authorizable_ctx(ctx))
  86                        return -EINVAL;
  87
  88                sel_sid = ctx->ctx_sid;
  89        }
  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                rc = -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                                }
 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        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_doi != 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_policy *xp,
 288                struct xfrm_user_sec_ctx *uctx)
 289{
 290        int err;
 291
 292        BUG_ON(!xp);
 293        BUG_ON(!uctx);
 294
 295        err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0);
 296        return err;
 297}
 298
 299
 300/*
 301 * LSM hook implementation that copies security data structure from old to
 302 * new for policy cloning.
 303 */
 304int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
 305{
 306        struct xfrm_sec_ctx *old_ctx, *new_ctx;
 307
 308        old_ctx = old->security;
 309
 310        if (old_ctx) {
 311                new_ctx = new->security = kmalloc(sizeof(*new_ctx) +
 312                                                  old_ctx->ctx_len,
 313                                                  GFP_KERNEL);
 314
 315                if (!new_ctx)
 316                        return -ENOMEM;
 317
 318                memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
 319                memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
 320        }
 321        return 0;
 322}
 323
 324/*
 325 * LSM hook implementation that frees xfrm_policy security information.
 326 */
 327void selinux_xfrm_policy_free(struct xfrm_policy *xp)
 328{
 329        struct xfrm_sec_ctx *ctx = xp->security;
 330        if (ctx)
 331                kfree(ctx);
 332}
 333
 334/*
 335 * LSM hook implementation that authorizes deletion of labeled policies.
 336 */
 337int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
 338{
 339        struct task_security_struct *tsec = current->security;
 340        struct xfrm_sec_ctx *ctx = xp->security;
 341        int rc = 0;
 342
 343        if (ctx)
 344                rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
 345                                  SECCLASS_ASSOCIATION,
 346                                  ASSOCIATION__SETCONTEXT, NULL);
 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        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        struct xfrm_sec_ctx *ctx = x->security;
 372        if (ctx)
 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
 390        return rc;
 391}
 392
 393/*
 394 * LSM hook that controls access to unlabelled packets.  If
 395 * a xfrm_state is authorizable (defined by macro) then it was
 396 * already authorized by the IPSec process.  If not, then
 397 * we need to check for unlabelled access since this may not have
 398 * gone thru the IPSec process.
 399 */
 400int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
 401                                struct avc_audit_data *ad)
 402{
 403        int i, rc = 0;
 404        struct sec_path *sp;
 405        u32 sel_sid = SECINITSID_UNLABELED;
 406
 407        sp = skb->sp;
 408
 409        if (sp) {
 410                for (i = 0; i < sp->len; i++) {
 411                        struct xfrm_state *x = sp->xvec[i];
 412
 413                        if (x && selinux_authorizable_xfrm(x)) {
 414                                struct xfrm_sec_ctx *ctx = x->security;
 415                                sel_sid = ctx->ctx_sid;
 416                                break;
 417                        }
 418                }
 419        }
 420
 421        /*
 422         * This check even when there's no association involved is
 423         * intended, according to Trent Jaeger, to make sure a
 424         * process can't engage in non-ipsec communication unless
 425         * explicitly allowed by policy.
 426         */
 427
 428        rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
 429                          ASSOCIATION__RECVFROM, ad);
 430
 431        return rc;
 432}
 433
 434/*
 435 * POSTROUTE_LAST hook's XFRM processing:
 436 * If we have no security association, then we need to determine
 437 * whether the socket is allowed to send to an unlabelled destination.
 438 * If we do have a authorizable security association, then it has already been
 439 * checked in the selinux_xfrm_state_pol_flow_match hook above.
 440 */
 441int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
 442                                        struct avc_audit_data *ad, u8 proto)
 443{
 444        struct dst_entry *dst;
 445        int rc = 0;
 446
 447        dst = skb->dst;
 448
 449        if (dst) {
 450                struct dst_entry *dst_test;
 451
 452                for (dst_test = dst; dst_test != NULL;
 453                     dst_test = dst_test->child) {
 454                        struct xfrm_state *x = dst_test->xfrm;
 455
 456                        if (x && selinux_authorizable_xfrm(x))
 457                                goto out;
 458                }
 459        }
 460
 461        switch (proto) {
 462        case IPPROTO_AH:
 463        case IPPROTO_ESP:
 464        case IPPROTO_COMP:
 465                /*
 466                 * We should have already seen this packet once before
 467                 * it underwent xfrm(s). No need to subject it to the
 468                 * unlabeled check.
 469                 */
 470                goto out;
 471        default:
 472                break;
 473        }
 474
 475        /*
 476         * This check even when there's no association involved is
 477         * intended, according to Trent Jaeger, to make sure a
 478         * process can't engage in non-ipsec communication unless
 479         * explicitly allowed by policy.
 480         */
 481
 482        rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
 483                          ASSOCIATION__SENDTO, ad);
 484out:
 485        return rc;
 486}
 487