linux/security/smack/smackfs.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
   3 *
   4 *      This program is free software; you can redistribute it and/or modify
   5 *      it under the terms of the GNU General Public License as published by
   6 *      the Free Software Foundation, version 2.
   7 *
   8 * Authors:
   9 *      Casey Schaufler <casey@schaufler-ca.com>
  10 *      Ahmed S. Darwish <darwish.07@gmail.com>
  11 *
  12 * Special thanks to the authors of selinuxfs.
  13 *
  14 *      Karl MacMillan <kmacmillan@tresys.com>
  15 *      James Morris <jmorris@redhat.com>
  16 *
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/vmalloc.h>
  21#include <linux/security.h>
  22#include <linux/mutex.h>
  23#include <linux/slab.h>
  24#include <net/net_namespace.h>
  25#include <net/netlabel.h>
  26#include <net/cipso_ipv4.h>
  27#include <linux/seq_file.h>
  28#include <linux/ctype.h>
  29#include <linux/audit.h>
  30#include "smack.h"
  31
  32/*
  33 * smackfs pseudo filesystem.
  34 */
  35
  36enum smk_inos {
  37        SMK_ROOT_INO    = 2,
  38        SMK_LOAD        = 3,    /* load policy */
  39        SMK_CIPSO       = 4,    /* load label -> CIPSO mapping */
  40        SMK_DOI         = 5,    /* CIPSO DOI */
  41        SMK_DIRECT      = 6,    /* CIPSO level indicating direct label */
  42        SMK_AMBIENT     = 7,    /* internet ambient label */
  43        SMK_NETLBLADDR  = 8,    /* single label hosts */
  44        SMK_ONLYCAP     = 9,    /* the only "capable" label */
  45        SMK_LOGGING     = 10,   /* logging */
  46        SMK_LOAD_SELF   = 11,   /* task specific rules */
  47        SMK_ACCESSES    = 12,   /* access policy */
  48};
  49
  50/*
  51 * List locks
  52 */
  53static DEFINE_MUTEX(smack_list_lock);
  54static DEFINE_MUTEX(smack_cipso_lock);
  55static DEFINE_MUTEX(smack_ambient_lock);
  56static DEFINE_MUTEX(smk_netlbladdr_lock);
  57
  58/*
  59 * This is the "ambient" label for network traffic.
  60 * If it isn't somehow marked, use this.
  61 * It can be reset via smackfs/ambient
  62 */
  63char *smack_net_ambient = smack_known_floor.smk_known;
  64
  65/*
  66 * This is the level in a CIPSO header that indicates a
  67 * smack label is contained directly in the category set.
  68 * It can be reset via smackfs/direct
  69 */
  70int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;
  71
  72/*
  73 * Unless a process is running with this label even
  74 * having CAP_MAC_OVERRIDE isn't enough to grant
  75 * privilege to violate MAC policy. If no label is
  76 * designated (the NULL case) capabilities apply to
  77 * everyone. It is expected that the hat (^) label
  78 * will be used if any label is used.
  79 */
  80char *smack_onlycap;
  81
  82/*
  83 * Certain IP addresses may be designated as single label hosts.
  84 * Packets are sent there unlabeled, but only from tasks that
  85 * can write to the specified label.
  86 */
  87
  88LIST_HEAD(smk_netlbladdr_list);
  89
  90/*
  91 * Rule lists are maintained for each label.
  92 * This master list is just for reading /smack/load.
  93 */
  94struct smack_master_list {
  95        struct list_head        list;
  96        struct smack_rule       *smk_rule;
  97};
  98
  99LIST_HEAD(smack_rule_list);
 100
 101static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 102
 103const char *smack_cipso_option = SMACK_CIPSO_OPTION;
 104
 105/*
 106 * Values for parsing cipso rules
 107 * SMK_DIGITLEN: Length of a digit field in a rule.
 108 * SMK_CIPSOMIN: Minimum possible cipso rule length.
 109 * SMK_CIPSOMAX: Maximum possible cipso rule length.
 110 */
 111#define SMK_DIGITLEN 4
 112#define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
 113#define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
 114
 115/*
 116 * Values for parsing MAC rules
 117 * SMK_ACCESS: Maximum possible combination of access permissions
 118 * SMK_ACCESSLEN: Maximum length for a rule access field
 119 * SMK_LOADLEN: Smack rule length
 120 */
 121#define SMK_OACCESS     "rwxa"
 122#define SMK_ACCESS      "rwxat"
 123#define SMK_OACCESSLEN  (sizeof(SMK_OACCESS) - 1)
 124#define SMK_ACCESSLEN   (sizeof(SMK_ACCESS) - 1)
 125#define SMK_OLOADLEN    (SMK_LABELLEN + SMK_LABELLEN + SMK_OACCESSLEN)
 126#define SMK_LOADLEN     (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
 127
 128/**
 129 * smk_netlabel_audit_set - fill a netlbl_audit struct
 130 * @nap: structure to fill
 131 */
 132static void smk_netlabel_audit_set(struct netlbl_audit *nap)
 133{
 134        nap->loginuid = audit_get_loginuid(current);
 135        nap->sessionid = audit_get_sessionid(current);
 136        nap->secid = smack_to_secid(smk_of_current());
 137}
 138
 139/*
 140 * Values for parsing single label host rules
 141 * "1.2.3.4 X"
 142 * "192.168.138.129/32 abcdefghijklmnopqrstuvw"
 143 */
 144#define SMK_NETLBLADDRMIN       9
 145#define SMK_NETLBLADDRMAX       42
 146
 147/**
 148 * smk_set_access - add a rule to the rule list
 149 * @srp: the new rule to add
 150 * @rule_list: the list of rules
 151 * @rule_lock: the rule list lock
 152 *
 153 * Looks through the current subject/object/access list for
 154 * the subject/object pair and replaces the access that was
 155 * there. If the pair isn't found add it with the specified
 156 * access.
 157 *
 158 * Returns 1 if a rule was found to exist already, 0 if it is new
 159 * Returns 0 if nothing goes wrong or -ENOMEM if it fails
 160 * during the allocation of the new pair to add.
 161 */
 162static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
 163                                struct mutex *rule_lock)
 164{
 165        struct smack_rule *sp;
 166        int found = 0;
 167
 168        mutex_lock(rule_lock);
 169
 170        /*
 171         * Because the object label is less likely to match
 172         * than the subject label check it first
 173         */
 174        list_for_each_entry_rcu(sp, rule_list, list) {
 175                if (sp->smk_object == srp->smk_object &&
 176                    sp->smk_subject == srp->smk_subject) {
 177                        found = 1;
 178                        sp->smk_access = srp->smk_access;
 179                        break;
 180                }
 181        }
 182        if (found == 0)
 183                list_add_rcu(&srp->list, rule_list);
 184
 185        mutex_unlock(rule_lock);
 186
 187        return found;
 188}
 189
 190/**
 191 * smk_parse_rule - parse Smack rule from load string
 192 * @data: string to be parsed whose size is SMK_LOADLEN
 193 * @rule: Smack rule
 194 * @import: if non-zero, import labels
 195 */
 196static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
 197{
 198        char smack[SMK_LABELLEN];
 199        struct smack_known *skp;
 200
 201        if (import) {
 202                rule->smk_subject = smk_import(data, 0);
 203                if (rule->smk_subject == NULL)
 204                        return -1;
 205
 206                rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
 207                if (rule->smk_object == NULL)
 208                        return -1;
 209        } else {
 210                smk_parse_smack(data, 0, smack);
 211                skp = smk_find_entry(smack);
 212                if (skp == NULL)
 213                        return -1;
 214                rule->smk_subject = skp->smk_known;
 215
 216                smk_parse_smack(data + SMK_LABELLEN, 0, smack);
 217                skp = smk_find_entry(smack);
 218                if (skp == NULL)
 219                        return -1;
 220                rule->smk_object = skp->smk_known;
 221        }
 222
 223        rule->smk_access = 0;
 224
 225        switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
 226        case '-':
 227                break;
 228        case 'r':
 229        case 'R':
 230                rule->smk_access |= MAY_READ;
 231                break;
 232        default:
 233                return -1;
 234        }
 235
 236        switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
 237        case '-':
 238                break;
 239        case 'w':
 240        case 'W':
 241                rule->smk_access |= MAY_WRITE;
 242                break;
 243        default:
 244                return -1;
 245        }
 246
 247        switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
 248        case '-':
 249                break;
 250        case 'x':
 251        case 'X':
 252                rule->smk_access |= MAY_EXEC;
 253                break;
 254        default:
 255                return -1;
 256        }
 257
 258        switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
 259        case '-':
 260                break;
 261        case 'a':
 262        case 'A':
 263                rule->smk_access |= MAY_APPEND;
 264                break;
 265        default:
 266                return -1;
 267        }
 268
 269        switch (data[SMK_LABELLEN + SMK_LABELLEN + 4]) {
 270        case '-':
 271                break;
 272        case 't':
 273        case 'T':
 274                rule->smk_access |= MAY_TRANSMUTE;
 275                break;
 276        default:
 277                return -1;
 278        }
 279
 280        return 0;
 281}
 282
 283/**
 284 * smk_write_load_list - write() for any /smack/load
 285 * @file: file pointer, not actually used
 286 * @buf: where to get the data from
 287 * @count: bytes sent
 288 * @ppos: where to start - must be 0
 289 * @rule_list: the list of rules to write to
 290 * @rule_lock: lock for the rule list
 291 *
 292 * Get one smack access rule from above.
 293 * The format is exactly:
 294 *     char subject[SMK_LABELLEN]
 295 *     char object[SMK_LABELLEN]
 296 *     char access[SMK_ACCESSLEN]
 297 *
 298 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
 299 */
 300static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
 301                                size_t count, loff_t *ppos,
 302                                struct list_head *rule_list,
 303                                struct mutex *rule_lock)
 304{
 305        struct smack_master_list *smlp;
 306        struct smack_known *skp;
 307        struct smack_rule *rule;
 308        char *data;
 309        int rc = -EINVAL;
 310        int load = 0;
 311
 312        /*
 313         * No partial writes.
 314         * Enough data must be present.
 315         */
 316        if (*ppos != 0)
 317                return -EINVAL;
 318        /*
 319         * Minor hack for backward compatibility
 320         */
 321        if (count < (SMK_OLOADLEN) || count > SMK_LOADLEN)
 322                return -EINVAL;
 323
 324        data = kzalloc(SMK_LOADLEN, GFP_KERNEL);
 325        if (data == NULL)
 326                return -ENOMEM;
 327
 328        if (copy_from_user(data, buf, count) != 0) {
 329                rc = -EFAULT;
 330                goto out;
 331        }
 332
 333        /*
 334         * More on the minor hack for backward compatibility
 335         */
 336        if (count == (SMK_OLOADLEN))
 337                data[SMK_OLOADLEN] = '-';
 338
 339        rule = kzalloc(sizeof(*rule), GFP_KERNEL);
 340        if (rule == NULL) {
 341                rc = -ENOMEM;
 342                goto out;
 343        }
 344
 345        if (smk_parse_rule(data, rule, 1))
 346                goto out_free_rule;
 347
 348        if (rule_list == NULL) {
 349                load = 1;
 350                skp = smk_find_entry(rule->smk_subject);
 351                rule_list = &skp->smk_rules;
 352                rule_lock = &skp->smk_rules_lock;
 353        }
 354
 355        rc = count;
 356        /*
 357         * If this is "load" as opposed to "load-self" and a new rule
 358         * it needs to get added for reporting.
 359         * smk_set_access returns true if there was already a rule
 360         * for the subject/object pair, and false if it was new.
 361         */
 362        if (load && !smk_set_access(rule, rule_list, rule_lock)) {
 363                smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
 364                if (smlp != NULL) {
 365                        smlp->smk_rule = rule;
 366                        list_add_rcu(&smlp->list, &smack_rule_list);
 367                } else
 368                        rc = -ENOMEM;
 369                goto out;
 370        }
 371
 372out_free_rule:
 373        kfree(rule);
 374out:
 375        kfree(data);
 376        return rc;
 377}
 378
 379/*
 380 * Core logic for smackfs seq list operations.
 381 */
 382
 383static void *smk_seq_start(struct seq_file *s, loff_t *pos,
 384                                struct list_head *head)
 385{
 386        struct list_head *list;
 387
 388        /*
 389         * This is 0 the first time through.
 390         */
 391        if (s->index == 0)
 392                s->private = head;
 393
 394        if (s->private == NULL)
 395                return NULL;
 396
 397        list = s->private;
 398        if (list_empty(list))
 399                return NULL;
 400
 401        if (s->index == 0)
 402                return list->next;
 403        return list;
 404}
 405
 406static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
 407                                struct list_head *head)
 408{
 409        struct list_head *list = v;
 410
 411        if (list_is_last(list, head)) {
 412                s->private = NULL;
 413                return NULL;
 414        }
 415        s->private = list->next;
 416        return list->next;
 417}
 418
 419static void smk_seq_stop(struct seq_file *s, void *v)
 420{
 421        /* No-op */
 422}
 423
 424/*
 425 * Seq_file read operations for /smack/load
 426 */
 427
 428static void *load_seq_start(struct seq_file *s, loff_t *pos)
 429{
 430        return smk_seq_start(s, pos, &smack_rule_list);
 431}
 432
 433static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
 434{
 435        return smk_seq_next(s, v, pos, &smack_rule_list);
 436}
 437
 438static int load_seq_show(struct seq_file *s, void *v)
 439{
 440        struct list_head *list = v;
 441        struct smack_master_list *smlp =
 442                 list_entry(list, struct smack_master_list, list);
 443        struct smack_rule *srp = smlp->smk_rule;
 444
 445        seq_printf(s, "%s %s", (char *)srp->smk_subject,
 446                   (char *)srp->smk_object);
 447
 448        seq_putc(s, ' ');
 449
 450        if (srp->smk_access & MAY_READ)
 451                seq_putc(s, 'r');
 452        if (srp->smk_access & MAY_WRITE)
 453                seq_putc(s, 'w');
 454        if (srp->smk_access & MAY_EXEC)
 455                seq_putc(s, 'x');
 456        if (srp->smk_access & MAY_APPEND)
 457                seq_putc(s, 'a');
 458        if (srp->smk_access & MAY_TRANSMUTE)
 459                seq_putc(s, 't');
 460        if (srp->smk_access == 0)
 461                seq_putc(s, '-');
 462
 463        seq_putc(s, '\n');
 464
 465        return 0;
 466}
 467
 468static const struct seq_operations load_seq_ops = {
 469        .start = load_seq_start,
 470        .next  = load_seq_next,
 471        .show  = load_seq_show,
 472        .stop  = smk_seq_stop,
 473};
 474
 475/**
 476 * smk_open_load - open() for /smack/load
 477 * @inode: inode structure representing file
 478 * @file: "load" file pointer
 479 *
 480 * For reading, use load_seq_* seq_file reading operations.
 481 */
 482static int smk_open_load(struct inode *inode, struct file *file)
 483{
 484        return seq_open(file, &load_seq_ops);
 485}
 486
 487/**
 488 * smk_write_load - write() for /smack/load
 489 * @file: file pointer, not actually used
 490 * @buf: where to get the data from
 491 * @count: bytes sent
 492 * @ppos: where to start - must be 0
 493 *
 494 */
 495static ssize_t smk_write_load(struct file *file, const char __user *buf,
 496                              size_t count, loff_t *ppos)
 497{
 498
 499        /*
 500         * Must have privilege.
 501         * No partial writes.
 502         * Enough data must be present.
 503         */
 504        if (!capable(CAP_MAC_ADMIN))
 505                return -EPERM;
 506
 507        return smk_write_load_list(file, buf, count, ppos, NULL, NULL);
 508}
 509
 510static const struct file_operations smk_load_ops = {
 511        .open           = smk_open_load,
 512        .read           = seq_read,
 513        .llseek         = seq_lseek,
 514        .write          = smk_write_load,
 515        .release        = seq_release,
 516};
 517
 518/**
 519 * smk_cipso_doi - initialize the CIPSO domain
 520 */
 521static void smk_cipso_doi(void)
 522{
 523        int rc;
 524        struct cipso_v4_doi *doip;
 525        struct netlbl_audit nai;
 526
 527        smk_netlabel_audit_set(&nai);
 528
 529        rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai);
 530        if (rc != 0)
 531                printk(KERN_WARNING "%s:%d remove rc = %d\n",
 532                       __func__, __LINE__, rc);
 533
 534        doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
 535        if (doip == NULL)
 536                panic("smack:  Failed to initialize cipso DOI.\n");
 537        doip->map.std = NULL;
 538        doip->doi = smk_cipso_doi_value;
 539        doip->type = CIPSO_V4_MAP_PASS;
 540        doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
 541        for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
 542                doip->tags[rc] = CIPSO_V4_TAG_INVALID;
 543
 544        rc = netlbl_cfg_cipsov4_add(doip, &nai);
 545        if (rc != 0) {
 546                printk(KERN_WARNING "%s:%d cipso add rc = %d\n",
 547                       __func__, __LINE__, rc);
 548                kfree(doip);
 549                return;
 550        }
 551        rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai);
 552        if (rc != 0) {
 553                printk(KERN_WARNING "%s:%d map add rc = %d\n",
 554                       __func__, __LINE__, rc);
 555                kfree(doip);
 556                return;
 557        }
 558}
 559
 560/**
 561 * smk_unlbl_ambient - initialize the unlabeled domain
 562 * @oldambient: previous domain string
 563 */
 564static void smk_unlbl_ambient(char *oldambient)
 565{
 566        int rc;
 567        struct netlbl_audit nai;
 568
 569        smk_netlabel_audit_set(&nai);
 570
 571        if (oldambient != NULL) {
 572                rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai);
 573                if (rc != 0)
 574                        printk(KERN_WARNING "%s:%d remove rc = %d\n",
 575                               __func__, __LINE__, rc);
 576        }
 577
 578        rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET,
 579                                      NULL, NULL, &nai);
 580        if (rc != 0)
 581                printk(KERN_WARNING "%s:%d add rc = %d\n",
 582                       __func__, __LINE__, rc);
 583}
 584
 585/*
 586 * Seq_file read operations for /smack/cipso
 587 */
 588
 589static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
 590{
 591        return smk_seq_start(s, pos, &smack_known_list);
 592}
 593
 594static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
 595{
 596        return smk_seq_next(s, v, pos, &smack_known_list);
 597}
 598
 599/*
 600 * Print cipso labels in format:
 601 * label level[/cat[,cat]]
 602 */
 603static int cipso_seq_show(struct seq_file *s, void *v)
 604{
 605        struct list_head  *list = v;
 606        struct smack_known *skp =
 607                 list_entry(list, struct smack_known, list);
 608        struct smack_cipso *scp = skp->smk_cipso;
 609        char *cbp;
 610        char sep = '/';
 611        int cat = 1;
 612        int i;
 613        unsigned char m;
 614
 615        if (scp == NULL)
 616                return 0;
 617
 618        seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);
 619
 620        cbp = scp->smk_catset;
 621        for (i = 0; i < SMK_LABELLEN; i++)
 622                for (m = 0x80; m != 0; m >>= 1) {
 623                        if (m & cbp[i]) {
 624                                seq_printf(s, "%c%d", sep, cat);
 625                                sep = ',';
 626                        }
 627                        cat++;
 628                }
 629
 630        seq_putc(s, '\n');
 631
 632        return 0;
 633}
 634
 635static const struct seq_operations cipso_seq_ops = {
 636        .start = cipso_seq_start,
 637        .next  = cipso_seq_next,
 638        .show  = cipso_seq_show,
 639        .stop  = smk_seq_stop,
 640};
 641
 642/**
 643 * smk_open_cipso - open() for /smack/cipso
 644 * @inode: inode structure representing file
 645 * @file: "cipso" file pointer
 646 *
 647 * Connect our cipso_seq_* operations with /smack/cipso
 648 * file_operations
 649 */
 650static int smk_open_cipso(struct inode *inode, struct file *file)
 651{
 652        return seq_open(file, &cipso_seq_ops);
 653}
 654
 655/**
 656 * smk_write_cipso - write() for /smack/cipso
 657 * @file: file pointer, not actually used
 658 * @buf: where to get the data from
 659 * @count: bytes sent
 660 * @ppos: where to start
 661 *
 662 * Accepts only one cipso rule per write call.
 663 * Returns number of bytes written or error code, as appropriate
 664 */
 665static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
 666                               size_t count, loff_t *ppos)
 667{
 668        struct smack_known *skp;
 669        struct smack_cipso *scp = NULL;
 670        char mapcatset[SMK_LABELLEN];
 671        int maplevel;
 672        int cat;
 673        int catlen;
 674        ssize_t rc = -EINVAL;
 675        char *data = NULL;
 676        char *rule;
 677        int ret;
 678        int i;
 679
 680        /*
 681         * Must have privilege.
 682         * No partial writes.
 683         * Enough data must be present.
 684         */
 685        if (!capable(CAP_MAC_ADMIN))
 686                return -EPERM;
 687        if (*ppos != 0)
 688                return -EINVAL;
 689        if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
 690                return -EINVAL;
 691
 692        data = kzalloc(count + 1, GFP_KERNEL);
 693        if (data == NULL)
 694                return -ENOMEM;
 695
 696        if (copy_from_user(data, buf, count) != 0) {
 697                rc = -EFAULT;
 698                goto unlockedout;
 699        }
 700
 701        /* labels cannot begin with a '-' */
 702        if (data[0] == '-') {
 703                rc = -EINVAL;
 704                goto unlockedout;
 705        }
 706        data[count] = '\0';
 707        rule = data;
 708        /*
 709         * Only allow one writer at a time. Writes should be
 710         * quite rare and small in any case.
 711         */
 712        mutex_lock(&smack_cipso_lock);
 713
 714        skp = smk_import_entry(rule, 0);
 715        if (skp == NULL)
 716                goto out;
 717
 718        rule += SMK_LABELLEN;
 719        ret = sscanf(rule, "%d", &maplevel);
 720        if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
 721                goto out;
 722
 723        rule += SMK_DIGITLEN;
 724        ret = sscanf(rule, "%d", &catlen);
 725        if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
 726                goto out;
 727
 728        if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
 729                goto out;
 730
 731        memset(mapcatset, 0, sizeof(mapcatset));
 732
 733        for (i = 0; i < catlen; i++) {
 734                rule += SMK_DIGITLEN;
 735                ret = sscanf(rule, "%d", &cat);
 736                if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
 737                        goto out;
 738
 739                smack_catset_bit(cat, mapcatset);
 740        }
 741
 742        if (skp->smk_cipso == NULL) {
 743                scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
 744                if (scp == NULL) {
 745                        rc = -ENOMEM;
 746                        goto out;
 747                }
 748        }
 749
 750        spin_lock_bh(&skp->smk_cipsolock);
 751
 752        if (scp == NULL)
 753                scp = skp->smk_cipso;
 754        else
 755                skp->smk_cipso = scp;
 756
 757        scp->smk_level = maplevel;
 758        memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));
 759
 760        spin_unlock_bh(&skp->smk_cipsolock);
 761
 762        rc = count;
 763out:
 764        mutex_unlock(&smack_cipso_lock);
 765unlockedout:
 766        kfree(data);
 767        return rc;
 768}
 769
 770static const struct file_operations smk_cipso_ops = {
 771        .open           = smk_open_cipso,
 772        .read           = seq_read,
 773        .llseek         = seq_lseek,
 774        .write          = smk_write_cipso,
 775        .release        = seq_release,
 776};
 777
 778/*
 779 * Seq_file read operations for /smack/netlabel
 780 */
 781
 782static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
 783{
 784        return smk_seq_start(s, pos, &smk_netlbladdr_list);
 785}
 786
 787static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
 788{
 789        return smk_seq_next(s, v, pos, &smk_netlbladdr_list);
 790}
 791#define BEBITS  (sizeof(__be32) * 8)
 792
 793/*
 794 * Print host/label pairs
 795 */
 796static int netlbladdr_seq_show(struct seq_file *s, void *v)
 797{
 798        struct list_head *list = v;
 799        struct smk_netlbladdr *skp =
 800                         list_entry(list, struct smk_netlbladdr, list);
 801        unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
 802        int maskn;
 803        u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
 804
 805        for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
 806
 807        seq_printf(s, "%u.%u.%u.%u/%d %s\n",
 808                hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
 809
 810        return 0;
 811}
 812
 813static const struct seq_operations netlbladdr_seq_ops = {
 814        .start = netlbladdr_seq_start,
 815        .next  = netlbladdr_seq_next,
 816        .show  = netlbladdr_seq_show,
 817        .stop  = smk_seq_stop,
 818};
 819
 820/**
 821 * smk_open_netlbladdr - open() for /smack/netlabel
 822 * @inode: inode structure representing file
 823 * @file: "netlabel" file pointer
 824 *
 825 * Connect our netlbladdr_seq_* operations with /smack/netlabel
 826 * file_operations
 827 */
 828static int smk_open_netlbladdr(struct inode *inode, struct file *file)
 829{
 830        return seq_open(file, &netlbladdr_seq_ops);
 831}
 832
 833/**
 834 * smk_netlbladdr_insert
 835 * @new : netlabel to insert
 836 *
 837 * This helper insert netlabel in the smack_netlbladdrs list
 838 * sorted by netmask length (longest to smallest)
 839 * locked by &smk_netlbladdr_lock in smk_write_netlbladdr
 840 *
 841 */
 842static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
 843{
 844        struct smk_netlbladdr *m, *m_next;
 845
 846        if (list_empty(&smk_netlbladdr_list)) {
 847                list_add_rcu(&new->list, &smk_netlbladdr_list);
 848                return;
 849        }
 850
 851        m = list_entry_rcu(smk_netlbladdr_list.next,
 852                           struct smk_netlbladdr, list);
 853
 854        /* the comparison '>' is a bit hacky, but works */
 855        if (new->smk_mask.s_addr > m->smk_mask.s_addr) {
 856                list_add_rcu(&new->list, &smk_netlbladdr_list);
 857                return;
 858        }
 859
 860        list_for_each_entry_rcu(m, &smk_netlbladdr_list, list) {
 861                if (list_is_last(&m->list, &smk_netlbladdr_list)) {
 862                        list_add_rcu(&new->list, &m->list);
 863                        return;
 864                }
 865                m_next = list_entry_rcu(m->list.next,
 866                                        struct smk_netlbladdr, list);
 867                if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) {
 868                        list_add_rcu(&new->list, &m->list);
 869                        return;
 870                }
 871        }
 872}
 873
 874
 875/**
 876 * smk_write_netlbladdr - write() for /smack/netlabel
 877 * @file: file pointer, not actually used
 878 * @buf: where to get the data from
 879 * @count: bytes sent
 880 * @ppos: where to start
 881 *
 882 * Accepts only one netlbladdr per write call.
 883 * Returns number of bytes written or error code, as appropriate
 884 */
 885static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
 886                                size_t count, loff_t *ppos)
 887{
 888        struct smk_netlbladdr *skp;
 889        struct sockaddr_in newname;
 890        char smack[SMK_LABELLEN];
 891        char *sp;
 892        char data[SMK_NETLBLADDRMAX + 1];
 893        char *host = (char *)&newname.sin_addr.s_addr;
 894        int rc;
 895        struct netlbl_audit audit_info;
 896        struct in_addr mask;
 897        unsigned int m;
 898        int found;
 899        u32 mask_bits = (1<<31);
 900        __be32 nsa;
 901        u32 temp_mask;
 902
 903        /*
 904         * Must have privilege.
 905         * No partial writes.
 906         * Enough data must be present.
 907         * "<addr/mask, as a.b.c.d/e><space><label>"
 908         * "<addr, as a.b.c.d><space><label>"
 909         */
 910        if (!capable(CAP_MAC_ADMIN))
 911                return -EPERM;
 912        if (*ppos != 0)
 913                return -EINVAL;
 914        if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX)
 915                return -EINVAL;
 916        if (copy_from_user(data, buf, count) != 0)
 917                return -EFAULT;
 918
 919        data[count] = '\0';
 920
 921        rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s",
 922                &host[0], &host[1], &host[2], &host[3], &m, smack);
 923        if (rc != 6) {
 924                rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s",
 925                        &host[0], &host[1], &host[2], &host[3], smack);
 926                if (rc != 5)
 927                        return -EINVAL;
 928                m = BEBITS;
 929        }
 930        if (m > BEBITS)
 931                return -EINVAL;
 932
 933        /* if smack begins with '-', its an option, don't import it */
 934        if (smack[0] != '-') {
 935                sp = smk_import(smack, 0);
 936                if (sp == NULL)
 937                        return -EINVAL;
 938        } else {
 939                /* check known options */
 940                if (strcmp(smack, smack_cipso_option) == 0)
 941                        sp = (char *)smack_cipso_option;
 942                else
 943                        return -EINVAL;
 944        }
 945
 946        for (temp_mask = 0; m > 0; m--) {
 947                temp_mask |= mask_bits;
 948                mask_bits >>= 1;
 949        }
 950        mask.s_addr = cpu_to_be32(temp_mask);
 951
 952        newname.sin_addr.s_addr &= mask.s_addr;
 953        /*
 954         * Only allow one writer at a time. Writes should be
 955         * quite rare and small in any case.
 956         */
 957        mutex_lock(&smk_netlbladdr_lock);
 958
 959        nsa = newname.sin_addr.s_addr;
 960        /* try to find if the prefix is already in the list */
 961        found = 0;
 962        list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) {
 963                if (skp->smk_host.sin_addr.s_addr == nsa &&
 964                    skp->smk_mask.s_addr == mask.s_addr) {
 965                        found = 1;
 966                        break;
 967                }
 968        }
 969        smk_netlabel_audit_set(&audit_info);
 970
 971        if (found == 0) {
 972                skp = kzalloc(sizeof(*skp), GFP_KERNEL);
 973                if (skp == NULL)
 974                        rc = -ENOMEM;
 975                else {
 976                        rc = 0;
 977                        skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
 978                        skp->smk_mask.s_addr = mask.s_addr;
 979                        skp->smk_label = sp;
 980                        smk_netlbladdr_insert(skp);
 981                }
 982        } else {
 983                /* we delete the unlabeled entry, only if the previous label
 984                 * wasn't the special CIPSO option */
 985                if (skp->smk_label != smack_cipso_option)
 986                        rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
 987                                        &skp->smk_host.sin_addr, &skp->smk_mask,
 988                                        PF_INET, &audit_info);
 989                else
 990                        rc = 0;
 991                skp->smk_label = sp;
 992        }
 993
 994        /*
 995         * Now tell netlabel about the single label nature of
 996         * this host so that incoming packets get labeled.
 997         * but only if we didn't get the special CIPSO option
 998         */
 999        if (rc == 0 && sp != smack_cipso_option)
1000                rc = netlbl_cfg_unlbl_static_add(&init_net, NULL,
1001                        &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET,
1002                        smack_to_secid(skp->smk_label), &audit_info);
1003
1004        if (rc == 0)
1005                rc = count;
1006
1007        mutex_unlock(&smk_netlbladdr_lock);
1008
1009        return rc;
1010}
1011
1012static const struct file_operations smk_netlbladdr_ops = {
1013        .open           = smk_open_netlbladdr,
1014        .read           = seq_read,
1015        .llseek         = seq_lseek,
1016        .write          = smk_write_netlbladdr,
1017        .release        = seq_release,
1018};
1019
1020/**
1021 * smk_read_doi - read() for /smack/doi
1022 * @filp: file pointer, not actually used
1023 * @buf: where to put the result
1024 * @count: maximum to send along
1025 * @ppos: where to start
1026 *
1027 * Returns number of bytes read or error code, as appropriate
1028 */
1029static ssize_t smk_read_doi(struct file *filp, char __user *buf,
1030                            size_t count, loff_t *ppos)
1031{
1032        char temp[80];
1033        ssize_t rc;
1034
1035        if (*ppos != 0)
1036                return 0;
1037
1038        sprintf(temp, "%d", smk_cipso_doi_value);
1039        rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1040
1041        return rc;
1042}
1043
1044/**
1045 * smk_write_doi - write() for /smack/doi
1046 * @file: file pointer, not actually used
1047 * @buf: where to get the data from
1048 * @count: bytes sent
1049 * @ppos: where to start
1050 *
1051 * Returns number of bytes written or error code, as appropriate
1052 */
1053static ssize_t smk_write_doi(struct file *file, const char __user *buf,
1054                             size_t count, loff_t *ppos)
1055{
1056        char temp[80];
1057        int i;
1058
1059        if (!capable(CAP_MAC_ADMIN))
1060                return -EPERM;
1061
1062        if (count >= sizeof(temp) || count == 0)
1063                return -EINVAL;
1064
1065        if (copy_from_user(temp, buf, count) != 0)
1066                return -EFAULT;
1067
1068        temp[count] = '\0';
1069
1070        if (sscanf(temp, "%d", &i) != 1)
1071                return -EINVAL;
1072
1073        smk_cipso_doi_value = i;
1074
1075        smk_cipso_doi();
1076
1077        return count;
1078}
1079
1080static const struct file_operations smk_doi_ops = {
1081        .read           = smk_read_doi,
1082        .write          = smk_write_doi,
1083        .llseek         = default_llseek,
1084};
1085
1086/**
1087 * smk_read_direct - read() for /smack/direct
1088 * @filp: file pointer, not actually used
1089 * @buf: where to put the result
1090 * @count: maximum to send along
1091 * @ppos: where to start
1092 *
1093 * Returns number of bytes read or error code, as appropriate
1094 */
1095static ssize_t smk_read_direct(struct file *filp, char __user *buf,
1096                               size_t count, loff_t *ppos)
1097{
1098        char temp[80];
1099        ssize_t rc;
1100
1101        if (*ppos != 0)
1102                return 0;
1103
1104        sprintf(temp, "%d", smack_cipso_direct);
1105        rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1106
1107        return rc;
1108}
1109
1110/**
1111 * smk_write_direct - write() for /smack/direct
1112 * @file: file pointer, not actually used
1113 * @buf: where to get the data from
1114 * @count: bytes sent
1115 * @ppos: where to start
1116 *
1117 * Returns number of bytes written or error code, as appropriate
1118 */
1119static ssize_t smk_write_direct(struct file *file, const char __user *buf,
1120                                size_t count, loff_t *ppos)
1121{
1122        char temp[80];
1123        int i;
1124
1125        if (!capable(CAP_MAC_ADMIN))
1126                return -EPERM;
1127
1128        if (count >= sizeof(temp) || count == 0)
1129                return -EINVAL;
1130
1131        if (copy_from_user(temp, buf, count) != 0)
1132                return -EFAULT;
1133
1134        temp[count] = '\0';
1135
1136        if (sscanf(temp, "%d", &i) != 1)
1137                return -EINVAL;
1138
1139        smack_cipso_direct = i;
1140
1141        return count;
1142}
1143
1144static const struct file_operations smk_direct_ops = {
1145        .read           = smk_read_direct,
1146        .write          = smk_write_direct,
1147        .llseek         = default_llseek,
1148};
1149
1150/**
1151 * smk_read_ambient - read() for /smack/ambient
1152 * @filp: file pointer, not actually used
1153 * @buf: where to put the result
1154 * @cn: maximum to send along
1155 * @ppos: where to start
1156 *
1157 * Returns number of bytes read or error code, as appropriate
1158 */
1159static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
1160                                size_t cn, loff_t *ppos)
1161{
1162        ssize_t rc;
1163        int asize;
1164
1165        if (*ppos != 0)
1166                return 0;
1167        /*
1168         * Being careful to avoid a problem in the case where
1169         * smack_net_ambient gets changed in midstream.
1170         */
1171        mutex_lock(&smack_ambient_lock);
1172
1173        asize = strlen(smack_net_ambient) + 1;
1174
1175        if (cn >= asize)
1176                rc = simple_read_from_buffer(buf, cn, ppos,
1177                                             smack_net_ambient, asize);
1178        else
1179                rc = -EINVAL;
1180
1181        mutex_unlock(&smack_ambient_lock);
1182
1183        return rc;
1184}
1185
1186/**
1187 * smk_write_ambient - write() for /smack/ambient
1188 * @file: file pointer, not actually used
1189 * @buf: where to get the data from
1190 * @count: bytes sent
1191 * @ppos: where to start
1192 *
1193 * Returns number of bytes written or error code, as appropriate
1194 */
1195static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
1196                                 size_t count, loff_t *ppos)
1197{
1198        char in[SMK_LABELLEN];
1199        char *oldambient;
1200        char *smack;
1201
1202        if (!capable(CAP_MAC_ADMIN))
1203                return -EPERM;
1204
1205        if (count >= SMK_LABELLEN)
1206                return -EINVAL;
1207
1208        if (copy_from_user(in, buf, count) != 0)
1209                return -EFAULT;
1210
1211        smack = smk_import(in, count);
1212        if (smack == NULL)
1213                return -EINVAL;
1214
1215        mutex_lock(&smack_ambient_lock);
1216
1217        oldambient = smack_net_ambient;
1218        smack_net_ambient = smack;
1219        smk_unlbl_ambient(oldambient);
1220
1221        mutex_unlock(&smack_ambient_lock);
1222
1223        return count;
1224}
1225
1226static const struct file_operations smk_ambient_ops = {
1227        .read           = smk_read_ambient,
1228        .write          = smk_write_ambient,
1229        .llseek         = default_llseek,
1230};
1231
1232/**
1233 * smk_read_onlycap - read() for /smack/onlycap
1234 * @filp: file pointer, not actually used
1235 * @buf: where to put the result
1236 * @cn: maximum to send along
1237 * @ppos: where to start
1238 *
1239 * Returns number of bytes read or error code, as appropriate
1240 */
1241static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
1242                                size_t cn, loff_t *ppos)
1243{
1244        char *smack = "";
1245        ssize_t rc = -EINVAL;
1246        int asize;
1247
1248        if (*ppos != 0)
1249                return 0;
1250
1251        if (smack_onlycap != NULL)
1252                smack = smack_onlycap;
1253
1254        asize = strlen(smack) + 1;
1255
1256        if (cn >= asize)
1257                rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
1258
1259        return rc;
1260}
1261
1262/**
1263 * smk_write_onlycap - write() for /smack/onlycap
1264 * @file: file pointer, not actually used
1265 * @buf: where to get the data from
1266 * @count: bytes sent
1267 * @ppos: where to start
1268 *
1269 * Returns number of bytes written or error code, as appropriate
1270 */
1271static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
1272                                 size_t count, loff_t *ppos)
1273{
1274        char in[SMK_LABELLEN];
1275        char *sp = smk_of_task(current->cred->security);
1276
1277        if (!capable(CAP_MAC_ADMIN))
1278                return -EPERM;
1279
1280        /*
1281         * This can be done using smk_access() but is done
1282         * explicitly for clarity. The smk_access() implementation
1283         * would use smk_access(smack_onlycap, MAY_WRITE)
1284         */
1285        if (smack_onlycap != NULL && smack_onlycap != sp)
1286                return -EPERM;
1287
1288        if (count >= SMK_LABELLEN)
1289                return -EINVAL;
1290
1291        if (copy_from_user(in, buf, count) != 0)
1292                return -EFAULT;
1293
1294        /*
1295         * Should the null string be passed in unset the onlycap value.
1296         * This seems like something to be careful with as usually
1297         * smk_import only expects to return NULL for errors. It
1298         * is usually the case that a nullstring or "\n" would be
1299         * bad to pass to smk_import but in fact this is useful here.
1300         */
1301        smack_onlycap = smk_import(in, count);
1302
1303        return count;
1304}
1305
1306static const struct file_operations smk_onlycap_ops = {
1307        .read           = smk_read_onlycap,
1308        .write          = smk_write_onlycap,
1309        .llseek         = default_llseek,
1310};
1311
1312/**
1313 * smk_read_logging - read() for /smack/logging
1314 * @filp: file pointer, not actually used
1315 * @buf: where to put the result
1316 * @cn: maximum to send along
1317 * @ppos: where to start
1318 *
1319 * Returns number of bytes read or error code, as appropriate
1320 */
1321static ssize_t smk_read_logging(struct file *filp, char __user *buf,
1322                                size_t count, loff_t *ppos)
1323{
1324        char temp[32];
1325        ssize_t rc;
1326
1327        if (*ppos != 0)
1328                return 0;
1329
1330        sprintf(temp, "%d\n", log_policy);
1331        rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
1332        return rc;
1333}
1334
1335/**
1336 * smk_write_logging - write() for /smack/logging
1337 * @file: file pointer, not actually used
1338 * @buf: where to get the data from
1339 * @count: bytes sent
1340 * @ppos: where to start
1341 *
1342 * Returns number of bytes written or error code, as appropriate
1343 */
1344static ssize_t smk_write_logging(struct file *file, const char __user *buf,
1345                                size_t count, loff_t *ppos)
1346{
1347        char temp[32];
1348        int i;
1349
1350        if (!capable(CAP_MAC_ADMIN))
1351                return -EPERM;
1352
1353        if (count >= sizeof(temp) || count == 0)
1354                return -EINVAL;
1355
1356        if (copy_from_user(temp, buf, count) != 0)
1357                return -EFAULT;
1358
1359        temp[count] = '\0';
1360
1361        if (sscanf(temp, "%d", &i) != 1)
1362                return -EINVAL;
1363        if (i < 0 || i > 3)
1364                return -EINVAL;
1365        log_policy = i;
1366        return count;
1367}
1368
1369
1370
1371static const struct file_operations smk_logging_ops = {
1372        .read           = smk_read_logging,
1373        .write          = smk_write_logging,
1374        .llseek         = default_llseek,
1375};
1376
1377/*
1378 * Seq_file read operations for /smack/load-self
1379 */
1380
1381static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
1382{
1383        struct task_smack *tsp = current_security();
1384
1385        return smk_seq_start(s, pos, &tsp->smk_rules);
1386}
1387
1388static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
1389{
1390        struct task_smack *tsp = current_security();
1391
1392        return smk_seq_next(s, v, pos, &tsp->smk_rules);
1393}
1394
1395static int load_self_seq_show(struct seq_file *s, void *v)
1396{
1397        struct list_head *list = v;
1398        struct smack_rule *srp =
1399                 list_entry(list, struct smack_rule, list);
1400
1401        seq_printf(s, "%s %s", (char *)srp->smk_subject,
1402                   (char *)srp->smk_object);
1403
1404        seq_putc(s, ' ');
1405
1406        if (srp->smk_access & MAY_READ)
1407                seq_putc(s, 'r');
1408        if (srp->smk_access & MAY_WRITE)
1409                seq_putc(s, 'w');
1410        if (srp->smk_access & MAY_EXEC)
1411                seq_putc(s, 'x');
1412        if (srp->smk_access & MAY_APPEND)
1413                seq_putc(s, 'a');
1414        if (srp->smk_access & MAY_TRANSMUTE)
1415                seq_putc(s, 't');
1416        if (srp->smk_access == 0)
1417                seq_putc(s, '-');
1418
1419        seq_putc(s, '\n');
1420
1421        return 0;
1422}
1423
1424static const struct seq_operations load_self_seq_ops = {
1425        .start = load_self_seq_start,
1426        .next  = load_self_seq_next,
1427        .show  = load_self_seq_show,
1428        .stop  = smk_seq_stop,
1429};
1430
1431
1432/**
1433 * smk_open_load_self - open() for /smack/load-self
1434 * @inode: inode structure representing file
1435 * @file: "load" file pointer
1436 *
1437 * For reading, use load_seq_* seq_file reading operations.
1438 */
1439static int smk_open_load_self(struct inode *inode, struct file *file)
1440{
1441        return seq_open(file, &load_self_seq_ops);
1442}
1443
1444/**
1445 * smk_write_load_self - write() for /smack/load-self
1446 * @file: file pointer, not actually used
1447 * @buf: where to get the data from
1448 * @count: bytes sent
1449 * @ppos: where to start - must be 0
1450 *
1451 */
1452static ssize_t smk_write_load_self(struct file *file, const char __user *buf,
1453                              size_t count, loff_t *ppos)
1454{
1455        struct task_smack *tsp = current_security();
1456
1457        return smk_write_load_list(file, buf, count, ppos, &tsp->smk_rules,
1458                                        &tsp->smk_rules_lock);
1459}
1460
1461static const struct file_operations smk_load_self_ops = {
1462        .open           = smk_open_load_self,
1463        .read           = seq_read,
1464        .llseek         = seq_lseek,
1465        .write          = smk_write_load_self,
1466        .release        = seq_release,
1467};
1468
1469/**
1470 * smk_write_access - handle access check transaction
1471 * @file: file pointer
1472 * @buf: data from user space
1473 * @count: bytes sent
1474 * @ppos: where to start - must be 0
1475 */
1476static ssize_t smk_write_access(struct file *file, const char __user *buf,
1477                                size_t count, loff_t *ppos)
1478{
1479        struct smack_rule rule;
1480        char *data;
1481        int res;
1482
1483        data = simple_transaction_get(file, buf, count);
1484        if (IS_ERR(data))
1485                return PTR_ERR(data);
1486
1487        if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0))
1488                return -EINVAL;
1489
1490        res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
1491                          NULL);
1492        data[0] = res == 0 ? '1' : '0';
1493        data[1] = '\0';
1494
1495        simple_transaction_set(file, 2);
1496        return SMK_LOADLEN;
1497}
1498
1499static const struct file_operations smk_access_ops = {
1500        .write          = smk_write_access,
1501        .read           = simple_transaction_read,
1502        .release        = simple_transaction_release,
1503        .llseek         = generic_file_llseek,
1504};
1505
1506/**
1507 * smk_fill_super - fill the /smackfs superblock
1508 * @sb: the empty superblock
1509 * @data: unused
1510 * @silent: unused
1511 *
1512 * Fill in the well known entries for /smack
1513 *
1514 * Returns 0 on success, an error code on failure
1515 */
1516static int smk_fill_super(struct super_block *sb, void *data, int silent)
1517{
1518        int rc;
1519        struct inode *root_inode;
1520
1521        static struct tree_descr smack_files[] = {
1522                [SMK_LOAD] = {
1523                        "load", &smk_load_ops, S_IRUGO|S_IWUSR},
1524                [SMK_CIPSO] = {
1525                        "cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
1526                [SMK_DOI] = {
1527                        "doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
1528                [SMK_DIRECT] = {
1529                        "direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
1530                [SMK_AMBIENT] = {
1531                        "ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
1532                [SMK_NETLBLADDR] = {
1533                        "netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR},
1534                [SMK_ONLYCAP] = {
1535                        "onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR},
1536                [SMK_LOGGING] = {
1537                        "logging", &smk_logging_ops, S_IRUGO|S_IWUSR},
1538                [SMK_LOAD_SELF] = {
1539                        "load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
1540                [SMK_ACCESSES] = {
1541                        "access", &smk_access_ops, S_IRUGO|S_IWUGO},
1542                /* last one */
1543                        {""}
1544        };
1545
1546        rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
1547        if (rc != 0) {
1548                printk(KERN_ERR "%s failed %d while creating inodes\n",
1549                        __func__, rc);
1550                return rc;
1551        }
1552
1553        root_inode = sb->s_root->d_inode;
1554        root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);
1555
1556        return 0;
1557}
1558
1559/**
1560 * smk_mount - get the smackfs superblock
1561 * @fs_type: passed along without comment
1562 * @flags: passed along without comment
1563 * @dev_name: passed along without comment
1564 * @data: passed along without comment
1565 *
1566 * Just passes everything along.
1567 *
1568 * Returns what the lower level code does.
1569 */
1570static struct dentry *smk_mount(struct file_system_type *fs_type,
1571                      int flags, const char *dev_name, void *data)
1572{
1573        return mount_single(fs_type, flags, data, smk_fill_super);
1574}
1575
1576static struct file_system_type smk_fs_type = {
1577        .name           = "smackfs",
1578        .mount          = smk_mount,
1579        .kill_sb        = kill_litter_super,
1580};
1581
1582static struct vfsmount *smackfs_mount;
1583
1584/**
1585 * init_smk_fs - get the smackfs superblock
1586 *
1587 * register the smackfs
1588 *
1589 * Do not register smackfs if Smack wasn't enabled
1590 * on boot. We can not put this method normally under the
1591 * smack_init() code path since the security subsystem get
1592 * initialized before the vfs caches.
1593 *
1594 * Returns true if we were not chosen on boot or if
1595 * we were chosen and filesystem registration succeeded.
1596 */
1597static int __init init_smk_fs(void)
1598{
1599        int err;
1600
1601        if (!security_module_enable(&smack_ops))
1602                return 0;
1603
1604        err = register_filesystem(&smk_fs_type);
1605        if (!err) {
1606                smackfs_mount = kern_mount(&smk_fs_type);
1607                if (IS_ERR(smackfs_mount)) {
1608                        printk(KERN_ERR "smackfs:  could not mount!\n");
1609                        err = PTR_ERR(smackfs_mount);
1610                        smackfs_mount = NULL;
1611                }
1612        }
1613
1614        smk_cipso_doi();
1615        smk_unlbl_ambient(NULL);
1616
1617        mutex_init(&smack_known_floor.smk_rules_lock);
1618        mutex_init(&smack_known_hat.smk_rules_lock);
1619        mutex_init(&smack_known_huh.smk_rules_lock);
1620        mutex_init(&smack_known_invalid.smk_rules_lock);
1621        mutex_init(&smack_known_star.smk_rules_lock);
1622        mutex_init(&smack_known_web.smk_rules_lock);
1623
1624        INIT_LIST_HEAD(&smack_known_floor.smk_rules);
1625        INIT_LIST_HEAD(&smack_known_hat.smk_rules);
1626        INIT_LIST_HEAD(&smack_known_huh.smk_rules);
1627        INIT_LIST_HEAD(&smack_known_invalid.smk_rules);
1628        INIT_LIST_HEAD(&smack_known_star.smk_rules);
1629        INIT_LIST_HEAD(&smack_known_web.smk_rules);
1630
1631        return err;
1632}
1633
1634__initcall(init_smk_fs);
1635
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.