linux/security/apparmor/policy_unpack.c
<<
>>
Prefs
   1/*
   2 * AppArmor security module
   3 *
   4 * This file contains AppArmor functions for unpacking policy loaded from
   5 * userspace.
   6 *
   7 * Copyright (C) 1998-2008 Novell/SUSE
   8 * Copyright 2009-2010 Canonical Ltd.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation, version 2 of the
  13 * License.
  14 *
  15 * AppArmor uses a serialized binary format for loading policy. To find
  16 * policy format documentation look in Documentation/security/apparmor.txt
  17 * All policy is validated before it is used.
  18 */
  19
  20#include <asm/unaligned.h>
  21#include <linux/ctype.h>
  22#include <linux/errno.h>
  23
  24#include "include/apparmor.h"
  25#include "include/audit.h"
  26#include "include/context.h"
  27#include "include/match.h"
  28#include "include/policy.h"
  29#include "include/policy_unpack.h"
  30#include "include/sid.h"
  31
  32/*
  33 * The AppArmor interface treats data as a type byte followed by the
  34 * actual data.  The interface has the notion of a a named entry
  35 * which has a name (AA_NAME typecode followed by name string) followed by
  36 * the entries typecode and data.  Named types allow for optional
  37 * elements and extensions to be added and tested for without breaking
  38 * backwards compatibility.
  39 */
  40
  41enum aa_code {
  42        AA_U8,
  43        AA_U16,
  44        AA_U32,
  45        AA_U64,
  46        AA_NAME,                /* same as string except it is items name */
  47        AA_STRING,
  48        AA_BLOB,
  49        AA_STRUCT,
  50        AA_STRUCTEND,
  51        AA_LIST,
  52        AA_LISTEND,
  53        AA_ARRAY,
  54        AA_ARRAYEND,
  55};
  56
  57/*
  58 * aa_ext is the read of the buffer containing the serialized profile.  The
  59 * data is copied into a kernel buffer in apparmorfs and then handed off to
  60 * the unpack routines.
  61 */
  62struct aa_ext {
  63        void *start;
  64        void *end;
  65        void *pos;              /* pointer to current position in the buffer */
  66        u32 version;
  67};
  68
  69/* audit callback for unpack fields */
  70static void audit_cb(struct audit_buffer *ab, void *va)
  71{
  72        struct common_audit_data *sa = va;
  73        if (sa->aad.iface.target) {
  74                struct aa_profile *name = sa->aad.iface.target;
  75                audit_log_format(ab, " name=");
  76                audit_log_untrustedstring(ab, name->base.hname);
  77        }
  78        if (sa->aad.iface.pos)
  79                audit_log_format(ab, " offset=%ld", sa->aad.iface.pos);
  80}
  81
  82/**
  83 * audit_iface - do audit message for policy unpacking/load/replace/remove
  84 * @new: profile if it has been allocated (MAYBE NULL)
  85 * @name: name of the profile being manipulated (MAYBE NULL)
  86 * @info: any extra info about the failure (MAYBE NULL)
  87 * @e: buffer position info (NOT NULL)
  88 * @error: error code
  89 *
  90 * Returns: %0 or error
  91 */
  92static int audit_iface(struct aa_profile *new, const char *name,
  93                       const char *info, struct aa_ext *e, int error)
  94{
  95        struct aa_profile *profile = __aa_current_profile();
  96        struct common_audit_data sa;
  97        COMMON_AUDIT_DATA_INIT(&sa, NONE);
  98        sa.aad.iface.pos = e->pos - e->start;
  99        sa.aad.iface.target = new;
 100        sa.aad.name = name;
 101        sa.aad.info = info;
 102        sa.aad.error = error;
 103
 104        return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa,
 105                        audit_cb);
 106}
 107
 108/* test if read will be in packed data bounds */
 109static bool inbounds(struct aa_ext *e, size_t size)
 110{
 111        return (size <= e->end - e->pos);
 112}
 113
 114/**
 115 * aa_u16_chunck - test and do bounds checking for a u16 size based chunk
 116 * @e: serialized data read head (NOT NULL)
 117 * @chunk: start address for chunk of data (NOT NULL)
 118 *
 119 * Returns: the size of chunk found with the read head at the end of the chunk.
 120 */
 121static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
 122{
 123        size_t size = 0;
 124
 125        if (!inbounds(e, sizeof(u16)))
 126                return 0;
 127        size = le16_to_cpu(get_unaligned((u16 *) e->pos));
 128        e->pos += sizeof(u16);
 129        if (!inbounds(e, size))
 130                return 0;
 131        *chunk = e->pos;
 132        e->pos += size;
 133        return size;
 134}
 135
 136/* unpack control byte */
 137static bool unpack_X(struct aa_ext *e, enum aa_code code)
 138{
 139        if (!inbounds(e, 1))
 140                return 0;
 141        if (*(u8 *) e->pos != code)
 142                return 0;
 143        e->pos++;
 144        return 1;
 145}
 146
 147/**
 148 * unpack_nameX - check is the next element is of type X with a name of @name
 149 * @e: serialized data extent information  (NOT NULL)
 150 * @code: type code
 151 * @name: name to match to the serialized element.  (MAYBE NULL)
 152 *
 153 * check that the next serialized data element is of type X and has a tag
 154 * name @name.  If @name is specified then there must be a matching
 155 * name element in the stream.  If @name is NULL any name element will be
 156 * skipped and only the typecode will be tested.
 157 *
 158 * Returns 1 on success (both type code and name tests match) and the read
 159 * head is advanced past the headers
 160 *
 161 * Returns: 0 if either match fails, the read head does not move
 162 */
 163static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
 164{
 165        /*
 166         * May need to reset pos if name or type doesn't match
 167         */
 168        void *pos = e->pos;
 169        /*
 170         * Check for presence of a tagname, and if present name size
 171         * AA_NAME tag value is a u16.
 172         */
 173        if (unpack_X(e, AA_NAME)) {
 174                char *tag = NULL;
 175                size_t size = unpack_u16_chunk(e, &tag);
 176                /* if a name is specified it must match. otherwise skip tag */
 177                if (name && (!size || strcmp(name, tag)))
 178                        goto fail;
 179        } else if (name) {
 180                /* if a name is specified and there is no name tag fail */
 181                goto fail;
 182        }
 183
 184        /* now check if type code matches */
 185        if (unpack_X(e, code))
 186                return 1;
 187
 188fail:
 189        e->pos = pos;
 190        return 0;
 191}
 192
 193static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
 194{
 195        if (unpack_nameX(e, AA_U32, name)) {
 196                if (!inbounds(e, sizeof(u32)))
 197                        return 0;
 198                if (data)
 199                        *data = le32_to_cpu(get_unaligned((u32 *) e->pos));
 200                e->pos += sizeof(u32);
 201                return 1;
 202        }
 203        return 0;
 204}
 205
 206static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
 207{
 208        if (unpack_nameX(e, AA_U64, name)) {
 209                if (!inbounds(e, sizeof(u64)))
 210                        return 0;
 211                if (data)
 212                        *data = le64_to_cpu(get_unaligned((u64 *) e->pos));
 213                e->pos += sizeof(u64);
 214                return 1;
 215        }
 216        return 0;
 217}
 218
 219static size_t unpack_array(struct aa_ext *e, const char *name)
 220{
 221        if (unpack_nameX(e, AA_ARRAY, name)) {
 222                int size;
 223                if (!inbounds(e, sizeof(u16)))
 224                        return 0;
 225                size = (int)le16_to_cpu(get_unaligned((u16 *) e->pos));
 226                e->pos += sizeof(u16);
 227                return size;
 228        }
 229        return 0;
 230}
 231
 232static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
 233{
 234        if (unpack_nameX(e, AA_BLOB, name)) {
 235                u32 size;
 236                if (!inbounds(e, sizeof(u32)))
 237                        return 0;
 238                size = le32_to_cpu(get_unaligned((u32 *) e->pos));
 239                e->pos += sizeof(u32);
 240                if (inbounds(e, (size_t) size)) {
 241                        *blob = e->pos;
 242                        e->pos += size;
 243                        return size;
 244                }
 245        }
 246        return 0;
 247}
 248
 249static int unpack_str(struct aa_ext *e, const char **string, const char *name)
 250{
 251        char *src_str;
 252        size_t size = 0;
 253        void *pos = e->pos;
 254        *string = NULL;
 255        if (unpack_nameX(e, AA_STRING, name)) {
 256                size = unpack_u16_chunk(e, &src_str);
 257                if (size) {
 258                        /* strings are null terminated, length is size - 1 */
 259                        if (src_str[size - 1] != 0)
 260                                goto fail;
 261                        *string = src_str;
 262                }
 263        }
 264        return size;
 265
 266fail:
 267        e->pos = pos;
 268        return 0;
 269}
 270
 271static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
 272{
 273        const char *tmp;
 274        void *pos = e->pos;
 275        int res = unpack_str(e, &tmp, name);
 276        *string = NULL;
 277
 278        if (!res)
 279                return 0;
 280
 281        *string = kmemdup(tmp, res, GFP_KERNEL);
 282        if (!*string) {
 283                e->pos = pos;
 284                return 0;
 285        }
 286
 287        return res;
 288}
 289
 290/**
 291 * verify_accept - verify the accept tables of a dfa
 292 * @dfa: dfa to verify accept tables of (NOT NULL)
 293 * @flags: flags governing dfa
 294 *
 295 * Returns: 1 if valid accept tables else 0 if error
 296 */
 297static bool verify_accept(struct aa_dfa *dfa, int flags)
 298{
 299        int i;
 300
 301        /* verify accept permissions */
 302        for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
 303                int mode = ACCEPT_TABLE(dfa)[i];
 304
 305                if (mode & ~DFA_VALID_PERM_MASK)
 306                        return 0;
 307
 308                if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
 309                        return 0;
 310        }
 311        return 1;
 312}
 313
 314/**
 315 * unpack_dfa - unpack a file rule dfa
 316 * @e: serialized data extent information (NOT NULL)
 317 *
 318 * returns dfa or ERR_PTR or NULL if no dfa
 319 */
 320static struct aa_dfa *unpack_dfa(struct aa_ext *e)
 321{
 322        char *blob = NULL;
 323        size_t size;
 324        struct aa_dfa *dfa = NULL;
 325
 326        size = unpack_blob(e, &blob, "aadfa");
 327        if (size) {
 328                /*
 329                 * The dfa is aligned with in the blob to 8 bytes
 330                 * from the beginning of the stream.
 331                 */
 332                size_t sz = blob - (char *)e->start;
 333                size_t pad = ALIGN(sz, 8) - sz;
 334                int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
 335                        TO_ACCEPT2_FLAG(YYTD_DATA32);
 336
 337
 338                if (aa_g_paranoid_load)
 339                        flags |= DFA_FLAG_VERIFY_STATES;
 340
 341                dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
 342
 343                if (IS_ERR(dfa))
 344                        return dfa;
 345
 346                if (!verify_accept(dfa, flags))
 347                        goto fail;
 348        }
 349
 350        return dfa;
 351
 352fail:
 353        aa_put_dfa(dfa);
 354        return ERR_PTR(-EPROTO);
 355}
 356
 357/**
 358 * unpack_trans_table - unpack a profile transition table
 359 * @e: serialized data extent information  (NOT NULL)
 360 * @profile: profile to add the accept table to (NOT NULL)
 361 *
 362 * Returns: 1 if table successfully unpacked
 363 */
 364static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
 365{
 366        void *pos = e->pos;
 367
 368        /* exec table is optional */
 369        if (unpack_nameX(e, AA_STRUCT, "xtable")) {
 370                int i, size;
 371
 372                size = unpack_array(e, NULL);
 373                /* currently 4 exec bits and entries 0-3 are reserved iupcx */
 374                if (size > 16 - 4)
 375                        goto fail;
 376                profile->file.trans.table = kzalloc(sizeof(char *) * size,
 377                                                    GFP_KERNEL);
 378                if (!profile->file.trans.table)
 379                        goto fail;
 380
 381                profile->file.trans.size = size;
 382                for (i = 0; i < size; i++) {
 383                        char *str;
 384                        int c, j, size = unpack_strdup(e, &str, NULL);
 385                        /* unpack_strdup verifies that the last character is
 386                         * null termination byte.
 387                         */
 388                        if (!size)
 389                                goto fail;
 390                        profile->file.trans.table[i] = str;
 391                        /* verify that name doesn't start with space */
 392                        if (isspace(*str))
 393                                goto fail;
 394
 395                        /* count internal #  of internal \0 */
 396                        for (c = j = 0; j < size - 2; j++) {
 397                                if (!str[j])
 398                                        c++;
 399                        }
 400                        if (*str == ':') {
 401                                /* beginning with : requires an embedded \0,
 402                                 * verify that exactly 1 internal \0 exists
 403                                 * trailing \0 already verified by unpack_strdup
 404                                 */
 405                                if (c != 1)
 406                                        goto fail;
 407                                /* first character after : must be valid */
 408                                if (!str[1])
 409                                        goto fail;
 410                        } else if (c)
 411                                /* fail - all other cases with embedded \0 */
 412                                goto fail;
 413                }
 414                if (!unpack_nameX(e, AA_ARRAYEND, NULL))
 415                        goto fail;
 416                if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 417                        goto fail;
 418        }
 419        return 1;
 420
 421fail:
 422        aa_free_domain_entries(&profile->file.trans);
 423        e->pos = pos;
 424        return 0;
 425}
 426
 427static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
 428{
 429        void *pos = e->pos;
 430
 431        /* rlimits are optional */
 432        if (unpack_nameX(e, AA_STRUCT, "rlimits")) {
 433                int i, size;
 434                u32 tmp = 0;
 435                if (!unpack_u32(e, &tmp, NULL))
 436                        goto fail;
 437                profile->rlimits.mask = tmp;
 438
 439                size = unpack_array(e, NULL);
 440                if (size > RLIM_NLIMITS)
 441                        goto fail;
 442                for (i = 0; i < size; i++) {
 443                        u64 tmp = 0;
 444                        int a = aa_map_resource(i);
 445                        if (!unpack_u64(e, &tmp, NULL))
 446                                goto fail;
 447                        profile->rlimits.limits[a].rlim_max = tmp;
 448                }
 449                if (!unpack_nameX(e, AA_ARRAYEND, NULL))
 450                        goto fail;
 451                if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 452                        goto fail;
 453        }
 454        return 1;
 455
 456fail:
 457        e->pos = pos;
 458        return 0;
 459}
 460
 461/**
 462 * unpack_profile - unpack a serialized profile
 463 * @e: serialized data extent information (NOT NULL)
 464 *
 465 * NOTE: unpack profile sets audit struct if there is a failure
 466 */
 467static struct aa_profile *unpack_profile(struct aa_ext *e)
 468{
 469        struct aa_profile *profile = NULL;
 470        const char *name = NULL;
 471        int error = -EPROTO;
 472        kernel_cap_t tmpcap;
 473        u32 tmp;
 474
 475        /* check that we have the right struct being passed */
 476        if (!unpack_nameX(e, AA_STRUCT, "profile"))
 477                goto fail;
 478        if (!unpack_str(e, &name, NULL))
 479                goto fail;
 480
 481        profile = aa_alloc_profile(name);
 482        if (!profile)
 483                return ERR_PTR(-ENOMEM);
 484
 485        /* profile renaming is optional */
 486        (void) unpack_str(e, &profile->rename, "rename");
 487
 488        /* xmatch is optional and may be NULL */
 489        profile->xmatch = unpack_dfa(e);
 490        if (IS_ERR(profile->xmatch)) {
 491                error = PTR_ERR(profile->xmatch);
 492                profile->xmatch = NULL;
 493                goto fail;
 494        }
 495        /* xmatch_len is not optional if xmatch is set */
 496        if (profile->xmatch) {
 497                if (!unpack_u32(e, &tmp, NULL))
 498                        goto fail;
 499                profile->xmatch_len = tmp;
 500        }
 501
 502        /* per profile debug flags (complain, audit) */
 503        if (!unpack_nameX(e, AA_STRUCT, "flags"))
 504                goto fail;
 505        if (!unpack_u32(e, &tmp, NULL))
 506                goto fail;
 507        if (tmp)
 508                profile->flags |= PFLAG_HAT;
 509        if (!unpack_u32(e, &tmp, NULL))
 510                goto fail;
 511        if (tmp)
 512                profile->mode = APPARMOR_COMPLAIN;
 513        if (!unpack_u32(e, &tmp, NULL))
 514                goto fail;
 515        if (tmp)
 516                profile->audit = AUDIT_ALL;
 517
 518        if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 519                goto fail;
 520
 521        /* path_flags is optional */
 522        if (unpack_u32(e, &profile->path_flags, "path_flags"))
 523                profile->path_flags |= profile->flags & PFLAG_MEDIATE_DELETED;
 524        else
 525                /* set a default value if path_flags field is not present */
 526                profile->path_flags = PFLAG_MEDIATE_DELETED;
 527
 528        if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
 529                goto fail;
 530        if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
 531                goto fail;
 532        if (!unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL))
 533                goto fail;
 534        if (!unpack_u32(e, &tmpcap.cap[0], NULL))
 535                goto fail;
 536
 537        if (unpack_nameX(e, AA_STRUCT, "caps64")) {
 538                /* optional upper half of 64 bit caps */
 539                if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
 540                        goto fail;
 541                if (!unpack_u32(e, &(profile->caps.audit.cap[1]), NULL))
 542                        goto fail;
 543                if (!unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL))
 544                        goto fail;
 545                if (!unpack_u32(e, &(tmpcap.cap[1]), NULL))
 546                        goto fail;
 547                if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 548                        goto fail;
 549        }
 550
 551        if (unpack_nameX(e, AA_STRUCT, "capsx")) {
 552                /* optional extended caps mediation mask */
 553                if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
 554                        goto fail;
 555                if (!unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
 556                        goto fail;
 557        }
 558
 559        if (!unpack_rlimits(e, profile))
 560                goto fail;
 561
 562        /* get file rules */
 563        profile->file.dfa = unpack_dfa(e);
 564        if (IS_ERR(profile->file.dfa)) {
 565                error = PTR_ERR(profile->file.dfa);
 566                profile->file.dfa = NULL;
 567                goto fail;
 568        }
 569
 570        if (!unpack_u32(e, &profile->file.start, "dfa_start"))
 571                /* default start state */
 572                profile->file.start = DFA_START;
 573
 574        if (!unpack_trans_table(e, profile))
 575                goto fail;
 576
 577        if (!unpack_nameX(e, AA_STRUCTEND, NULL))
 578                goto fail;
 579
 580        return profile;
 581
 582fail:
 583        if (profile)
 584                name = NULL;
 585        else if (!name)
 586                name = "unknown";
 587        audit_iface(profile, name, "failed to unpack profile", e, error);
 588        aa_put_profile(profile);
 589
 590        return ERR_PTR(error);
 591}
 592
 593/**
 594 * verify_head - unpack serialized stream header
 595 * @e: serialized data read head (NOT NULL)
 596 * @ns: Returns - namespace if one is specified else NULL (NOT NULL)
 597 *
 598 * Returns: error or 0 if header is good
 599 */
 600static int verify_header(struct aa_ext *e, const char **ns)
 601{
 602        int error = -EPROTONOSUPPORT;
 603        /* get the interface version */
 604        if (!unpack_u32(e, &e->version, "version")) {
 605                audit_iface(NULL, NULL, "invalid profile format", e, error);
 606                return error;
 607        }
 608
 609        /* check that the interface version is currently supported */
 610        if (e->version != 5) {
 611                audit_iface(NULL, NULL, "unsupported interface version", e,
 612                            error);
 613                return error;
 614        }
 615
 616        /* read the namespace if present */
 617        if (!unpack_str(e, ns, "namespace"))
 618                *ns = NULL;
 619
 620        return 0;
 621}
 622
 623static bool verify_xindex(int xindex, int table_size)
 624{
 625        int index, xtype;
 626        xtype = xindex & AA_X_TYPE_MASK;
 627        index = xindex & AA_X_INDEX_MASK;
 628        if (xtype == AA_X_TABLE && index > table_size)
 629                return 0;
 630        return 1;
 631}
 632
 633/* verify dfa xindexes are in range of transition tables */
 634static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
 635{
 636        int i;
 637        for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
 638                if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
 639                        return 0;
 640                if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
 641                        return 0;
 642        }
 643        return 1;
 644}
 645
 646/**
 647 * verify_profile - Do post unpack analysis to verify profile consistency
 648 * @profile: profile to verify (NOT NULL)
 649 *
 650 * Returns: 0 if passes verification else error
 651 */
 652static int verify_profile(struct aa_profile *profile)
 653{
 654        if (aa_g_paranoid_load) {
 655                if (profile->file.dfa &&
 656                    !verify_dfa_xindex(profile->file.dfa,
 657                                       profile->file.trans.size)) {
 658                        audit_iface(profile, NULL, "Invalid named transition",
 659                                    NULL, -EPROTO);
 660                        return -EPROTO;
 661                }
 662        }
 663
 664        return 0;
 665}
 666
 667/**
 668 * aa_unpack - unpack packed binary profile data loaded from user space
 669 * @udata: user data copied to kmem  (NOT NULL)
 670 * @size: the size of the user data
 671 * @ns: Returns namespace profile is in if specified else NULL (NOT NULL)
 672 *
 673 * Unpack user data and return refcounted allocated profile or ERR_PTR
 674 *
 675 * Returns: profile else error pointer if fails to unpack
 676 */
 677struct aa_profile *aa_unpack(void *udata, size_t size, const char **ns)
 678{
 679        struct aa_profile *profile = NULL;
 680        int error;
 681        struct aa_ext e = {
 682                .start = udata,
 683                .end = udata + size,
 684                .pos = udata,
 685        };
 686
 687        error = verify_header(&e, ns);
 688        if (error)
 689                return ERR_PTR(error);
 690
 691        profile = unpack_profile(&e);
 692        if (IS_ERR(profile))
 693                return profile;
 694
 695        error = verify_profile(profile);
 696        if (error) {
 697                aa_put_profile(profile);
 698                profile = ERR_PTR(error);
 699        }
 700
 701        /* return refcount */
 702        return profile;
 703}
 704