linux/security/selinux/selinuxfs.c
<<
>>
Prefs
   1/* Updated: Karl MacMillan <kmacmillan@tresys.com>
   2 *
   3 *      Added conditional policy language extensions
   4 *
   5 *  Updated: Hewlett-Packard <paul.moore@hp.com>
   6 *
   7 *      Added support for the policy capability bitmap
   8 *
   9 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  10 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  11 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
  12 *      This program is free software; you can redistribute it and/or modify
  13 *      it under the terms of the GNU General Public License as published by
  14 *      the Free Software Foundation, version 2.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/pagemap.h>
  19#include <linux/slab.h>
  20#include <linux/vmalloc.h>
  21#include <linux/fs.h>
  22#include <linux/mutex.h>
  23#include <linux/init.h>
  24#include <linux/string.h>
  25#include <linux/security.h>
  26#include <linux/major.h>
  27#include <linux/seq_file.h>
  28#include <linux/percpu.h>
  29#include <linux/audit.h>
  30#include <linux/uaccess.h>
  31
  32/* selinuxfs pseudo filesystem for exporting the security policy API.
  33   Based on the proc code and the fs/nfsd/nfsctl.c code. */
  34
  35#include "flask.h"
  36#include "avc.h"
  37#include "avc_ss.h"
  38#include "security.h"
  39#include "objsec.h"
  40#include "conditional.h"
  41
  42/* Policy capability filenames */
  43static char *policycap_names[] = {
  44        "network_peer_controls",
  45        "open_perms"
  46};
  47
  48unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
  49
  50static int __init checkreqprot_setup(char *str)
  51{
  52        unsigned long checkreqprot;
  53        if (!strict_strtoul(str, 0, &checkreqprot))
  54                selinux_checkreqprot = checkreqprot ? 1 : 0;
  55        return 1;
  56}
  57__setup("checkreqprot=", checkreqprot_setup);
  58
  59static DEFINE_MUTEX(sel_mutex);
  60
  61/* global data for booleans */
  62static struct dentry *bool_dir;
  63static int bool_num;
  64static char **bool_pending_names;
  65static int *bool_pending_values;
  66
  67/* global data for classes */
  68static struct dentry *class_dir;
  69static unsigned long last_class_ino;
  70
  71static char policy_opened;
  72
  73/* global data for policy capabilities */
  74static struct dentry *policycap_dir;
  75
  76extern void selnl_notify_setenforce(int val);
  77
  78/* Check whether a task is allowed to use a security operation. */
  79static int task_has_security(struct task_struct *tsk,
  80                             u32 perms)
  81{
  82        const struct task_security_struct *tsec;
  83        u32 sid = 0;
  84
  85        rcu_read_lock();
  86        tsec = __task_cred(tsk)->security;
  87        if (tsec)
  88                sid = tsec->sid;
  89        rcu_read_unlock();
  90        if (!tsec)
  91                return -EACCES;
  92
  93        return avc_has_perm(sid, SECINITSID_SECURITY,
  94                            SECCLASS_SECURITY, perms, NULL);
  95}
  96
  97enum sel_inos {
  98        SEL_ROOT_INO = 2,
  99        SEL_LOAD,       /* load policy */
 100        SEL_ENFORCE,    /* get or set enforcing status */
 101        SEL_CONTEXT,    /* validate context */
 102        SEL_ACCESS,     /* compute access decision */
 103        SEL_CREATE,     /* compute create labeling decision */
 104        SEL_RELABEL,    /* compute relabeling decision */
 105        SEL_USER,       /* compute reachable user contexts */
 106        SEL_POLICYVERS, /* return policy version for this kernel */
 107        SEL_COMMIT_BOOLS, /* commit new boolean values */
 108        SEL_MLS,        /* return if MLS policy is enabled */
 109        SEL_DISABLE,    /* disable SELinux until next reboot */
 110        SEL_MEMBER,     /* compute polyinstantiation membership decision */
 111        SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
 112        SEL_COMPAT_NET, /* whether to use old compat network packet controls */
 113        SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
 114        SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
 115        SEL_STATUS,     /* export current status using mmap() */
 116        SEL_POLICY,     /* allow userspace to read the in kernel policy */
 117        SEL_INO_NEXT,   /* The next inode number to use */
 118};
 119
 120static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 121
 122#define SEL_INITCON_INO_OFFSET          0x01000000
 123#define SEL_BOOL_INO_OFFSET             0x02000000
 124#define SEL_CLASS_INO_OFFSET            0x04000000
 125#define SEL_POLICYCAP_INO_OFFSET        0x08000000
 126#define SEL_INO_MASK                    0x00ffffff
 127
 128#define TMPBUFLEN       12
 129static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
 130                                size_t count, loff_t *ppos)
 131{
 132        char tmpbuf[TMPBUFLEN];
 133        ssize_t length;
 134
 135        length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing);
 136        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 137}
 138
 139#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
 140static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
 141                                 size_t count, loff_t *ppos)
 142
 143{
 144        char *page = NULL;
 145        ssize_t length;
 146        int new_value;
 147
 148        length = -ENOMEM;
 149        if (count >= PAGE_SIZE)
 150                goto out;
 151
 152        /* No partial writes. */
 153        length = EINVAL;
 154        if (*ppos != 0)
 155                goto out;
 156
 157        length = -ENOMEM;
 158        page = (char *)get_zeroed_page(GFP_KERNEL);
 159        if (!page)
 160                goto out;
 161
 162        length = -EFAULT;
 163        if (copy_from_user(page, buf, count))
 164                goto out;
 165
 166        length = -EINVAL;
 167        if (sscanf(page, "%d", &new_value) != 1)
 168                goto out;
 169
 170        if (new_value != selinux_enforcing) {
 171                length = task_has_security(current, SECURITY__SETENFORCE);
 172                if (length)
 173                        goto out;
 174                audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
 175                        "enforcing=%d old_enforcing=%d auid=%u ses=%u",
 176                        new_value, selinux_enforcing,
 177                        audit_get_loginuid(current),
 178                        audit_get_sessionid(current));
 179                selinux_enforcing = new_value;
 180                if (selinux_enforcing)
 181                        avc_ss_reset(0);
 182                selnl_notify_setenforce(selinux_enforcing);
 183                selinux_status_update_setenforce(selinux_enforcing);
 184        }
 185        length = count;
 186out:
 187        free_page((unsigned long) page);
 188        return length;
 189}
 190#else
 191#define sel_write_enforce NULL
 192#endif
 193
 194static const struct file_operations sel_enforce_ops = {
 195        .read           = sel_read_enforce,
 196        .write          = sel_write_enforce,
 197        .llseek         = generic_file_llseek,
 198};
 199
 200static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
 201                                        size_t count, loff_t *ppos)
 202{
 203        char tmpbuf[TMPBUFLEN];
 204        ssize_t length;
 205        ino_t ino = filp->f_path.dentry->d_inode->i_ino;
 206        int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ?
 207                security_get_reject_unknown() : !security_get_allow_unknown();
 208
 209        length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown);
 210        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 211}
 212
 213static const struct file_operations sel_handle_unknown_ops = {
 214        .read           = sel_read_handle_unknown,
 215        .llseek         = generic_file_llseek,
 216};
 217
 218static int sel_open_handle_status(struct inode *inode, struct file *filp)
 219{
 220        struct page    *status = selinux_kernel_status_page();
 221
 222        if (!status)
 223                return -ENOMEM;
 224
 225        filp->private_data = status;
 226
 227        return 0;
 228}
 229
 230static ssize_t sel_read_handle_status(struct file *filp, char __user *buf,
 231                                      size_t count, loff_t *ppos)
 232{
 233        struct page    *status = filp->private_data;
 234
 235        BUG_ON(!status);
 236
 237        return simple_read_from_buffer(buf, count, ppos,
 238                                       page_address(status),
 239                                       sizeof(struct selinux_kernel_status));
 240}
 241
 242static int sel_mmap_handle_status(struct file *filp,
 243                                  struct vm_area_struct *vma)
 244{
 245        struct page    *status = filp->private_data;
 246        unsigned long   size = vma->vm_end - vma->vm_start;
 247
 248        BUG_ON(!status);
 249
 250        /* only allows one page from the head */
 251        if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
 252                return -EIO;
 253        /* disallow writable mapping */
 254        if (vma->vm_flags & VM_WRITE)
 255                return -EPERM;
 256        /* disallow mprotect() turns it into writable */
 257        vma->vm_flags &= ~VM_MAYWRITE;
 258
 259        return remap_pfn_range(vma, vma->vm_start,
 260                               page_to_pfn(status),
 261                               size, vma->vm_page_prot);
 262}
 263
 264static const struct file_operations sel_handle_status_ops = {
 265        .open           = sel_open_handle_status,
 266        .read           = sel_read_handle_status,
 267        .mmap           = sel_mmap_handle_status,
 268        .llseek         = generic_file_llseek,
 269};
 270
 271#ifdef CONFIG_SECURITY_SELINUX_DISABLE
 272static ssize_t sel_write_disable(struct file *file, const char __user *buf,
 273                                 size_t count, loff_t *ppos)
 274
 275{
 276        char *page = NULL;
 277        ssize_t length;
 278        int new_value;
 279        extern int selinux_disable(void);
 280
 281        length = -ENOMEM;
 282        if (count >= PAGE_SIZE)
 283                goto out;;
 284
 285        /* No partial writes. */
 286        length = -EINVAL;
 287        if (*ppos != 0)
 288                goto out;
 289
 290        length = -ENOMEM;
 291        page = (char *)get_zeroed_page(GFP_KERNEL);
 292        if (!page)
 293                goto out;
 294
 295        length = -EFAULT;
 296        if (copy_from_user(page, buf, count))
 297                goto out;
 298
 299        length = -EINVAL;
 300        if (sscanf(page, "%d", &new_value) != 1)
 301                goto out;
 302
 303        if (new_value) {
 304                length = selinux_disable();
 305                if (length)
 306                        goto out;
 307                audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
 308                        "selinux=0 auid=%u ses=%u",
 309                        audit_get_loginuid(current),
 310                        audit_get_sessionid(current));
 311        }
 312
 313        length = count;
 314out:
 315        free_page((unsigned long) page);
 316        return length;
 317}
 318#else
 319#define sel_write_disable NULL
 320#endif
 321
 322static const struct file_operations sel_disable_ops = {
 323        .write          = sel_write_disable,
 324        .llseek         = generic_file_llseek,
 325};
 326
 327static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
 328                                   size_t count, loff_t *ppos)
 329{
 330        char tmpbuf[TMPBUFLEN];
 331        ssize_t length;
 332
 333        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX);
 334        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 335}
 336
 337static const struct file_operations sel_policyvers_ops = {
 338        .read           = sel_read_policyvers,
 339        .llseek         = generic_file_llseek,
 340};
 341
 342/* declaration for sel_write_load */
 343static int sel_make_bools(void);
 344static int sel_make_classes(void);
 345static int sel_make_policycap(void);
 346
 347/* declaration for sel_make_class_dirs */
 348static int sel_make_dir(struct inode *dir, struct dentry *dentry,
 349                        unsigned long *ino);
 350
 351static ssize_t sel_read_mls(struct file *filp, char __user *buf,
 352                                size_t count, loff_t *ppos)
 353{
 354        char tmpbuf[TMPBUFLEN];
 355        ssize_t length;
 356
 357        length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
 358                           security_mls_enabled());
 359        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 360}
 361
 362static const struct file_operations sel_mls_ops = {
 363        .read           = sel_read_mls,
 364        .llseek         = generic_file_llseek,
 365};
 366
 367struct policy_load_memory {
 368        size_t len;
 369        void *data;
 370};
 371
 372static int sel_open_policy(struct inode *inode, struct file *filp)
 373{
 374        struct policy_load_memory *plm = NULL;
 375        int rc;
 376
 377        BUG_ON(filp->private_data);
 378
 379        mutex_lock(&sel_mutex);
 380
 381        rc = task_has_security(current, SECURITY__READ_POLICY);
 382        if (rc)
 383                goto err;
 384
 385        rc = -EBUSY;
 386        if (policy_opened)
 387                goto err;
 388
 389        rc = -ENOMEM;
 390        plm = kzalloc(sizeof(*plm), GFP_KERNEL);
 391        if (!plm)
 392                goto err;
 393
 394        if (i_size_read(inode) != security_policydb_len()) {
 395                mutex_lock(&inode->i_mutex);
 396                i_size_write(inode, security_policydb_len());
 397                mutex_unlock(&inode->i_mutex);
 398        }
 399
 400        rc = security_read_policy(&plm->data, &plm->len);
 401        if (rc)
 402                goto err;
 403
 404        policy_opened = 1;
 405
 406        filp->private_data = plm;
 407
 408        mutex_unlock(&sel_mutex);
 409
 410        return 0;
 411err:
 412        mutex_unlock(&sel_mutex);
 413
 414        if (plm)
 415                vfree(plm->data);
 416        kfree(plm);
 417        return rc;
 418}
 419
 420static int sel_release_policy(struct inode *inode, struct file *filp)
 421{
 422        struct policy_load_memory *plm = filp->private_data;
 423
 424        BUG_ON(!plm);
 425
 426        policy_opened = 0;
 427
 428        vfree(plm->data);
 429        kfree(plm);
 430
 431        return 0;
 432}
 433
 434static ssize_t sel_read_policy(struct file *filp, char __user *buf,
 435                               size_t count, loff_t *ppos)
 436{
 437        struct policy_load_memory *plm = filp->private_data;
 438        int ret;
 439
 440        mutex_lock(&sel_mutex);
 441
 442        ret = task_has_security(current, SECURITY__READ_POLICY);
 443        if (ret)
 444                goto out;
 445
 446        ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len);
 447out:
 448        mutex_unlock(&sel_mutex);
 449        return ret;
 450}
 451
 452static int sel_mmap_policy_fault(struct vm_area_struct *vma,
 453                                 struct vm_fault *vmf)
 454{
 455        struct policy_load_memory *plm = vma->vm_file->private_data;
 456        unsigned long offset;
 457        struct page *page;
 458
 459        if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
 460                return VM_FAULT_SIGBUS;
 461
 462        offset = vmf->pgoff << PAGE_SHIFT;
 463        if (offset >= roundup(plm->len, PAGE_SIZE))
 464                return VM_FAULT_SIGBUS;
 465
 466        page = vmalloc_to_page(plm->data + offset);
 467        get_page(page);
 468
 469        vmf->page = page;
 470
 471        return 0;
 472}
 473
 474static struct vm_operations_struct sel_mmap_policy_ops = {
 475        .fault = sel_mmap_policy_fault,
 476        .page_mkwrite = sel_mmap_policy_fault,
 477};
 478
 479int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
 480{
 481        if (vma->vm_flags & VM_SHARED) {
 482                /* do not allow mprotect to make mapping writable */
 483                vma->vm_flags &= ~VM_MAYWRITE;
 484
 485                if (vma->vm_flags & VM_WRITE)
 486                        return -EACCES;
 487        }
 488
 489        vma->vm_flags |= VM_RESERVED;
 490        vma->vm_ops = &sel_mmap_policy_ops;
 491
 492        return 0;
 493}
 494
 495static const struct file_operations sel_policy_ops = {
 496        .open           = sel_open_policy,
 497        .read           = sel_read_policy,
 498        .mmap           = sel_mmap_policy,
 499        .release        = sel_release_policy,
 500};
 501
 502static ssize_t sel_write_load(struct file *file, const char __user *buf,
 503                              size_t count, loff_t *ppos)
 504
 505{
 506        ssize_t length;
 507        void *data = NULL;
 508
 509        mutex_lock(&sel_mutex);
 510
 511        length = task_has_security(current, SECURITY__LOAD_POLICY);
 512        if (length)
 513                goto out;
 514
 515        /* No partial writes. */
 516        length = -EINVAL;
 517        if (*ppos != 0)
 518                goto out;
 519
 520        length = -EFBIG;
 521        if (count > 64 * 1024 * 1024)
 522                goto out;
 523
 524        length = -ENOMEM;
 525        data = vmalloc(count);
 526        if (!data)
 527                goto out;
 528
 529        length = -EFAULT;
 530        if (copy_from_user(data, buf, count) != 0)
 531                goto out;
 532
 533        length = security_load_policy(data, count);
 534        if (length)
 535                goto out;
 536
 537        length = sel_make_bools();
 538        if (length)
 539                goto out1;
 540
 541        length = sel_make_classes();
 542        if (length)
 543                goto out1;
 544
 545        length = sel_make_policycap();
 546        if (length)
 547                goto out1;
 548
 549        length = count;
 550
 551out1:
 552        audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
 553                "policy loaded auid=%u ses=%u",
 554                audit_get_loginuid(current),
 555                audit_get_sessionid(current));
 556out:
 557        mutex_unlock(&sel_mutex);
 558        vfree(data);
 559        return length;
 560}
 561
 562static const struct file_operations sel_load_ops = {
 563        .write          = sel_write_load,
 564        .llseek         = generic_file_llseek,
 565};
 566
 567static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
 568{
 569        char *canon = NULL;
 570        u32 sid, len;
 571        ssize_t length;
 572
 573        length = task_has_security(current, SECURITY__CHECK_CONTEXT);
 574        if (length)
 575                goto out;
 576
 577        length = security_context_to_sid(buf, size, &sid);
 578        if (length)
 579                goto out;
 580
 581        length = security_sid_to_context(sid, &canon, &len);
 582        if (length)
 583                goto out;
 584
 585        length = -ERANGE;
 586        if (len > SIMPLE_TRANSACTION_LIMIT) {
 587                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
 588                        "payload max\n", __func__, len);
 589                goto out;
 590        }
 591
 592        memcpy(buf, canon, len);
 593        length = len;
 594out:
 595        kfree(canon);
 596        return length;
 597}
 598
 599static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
 600                                     size_t count, loff_t *ppos)
 601{
 602        char tmpbuf[TMPBUFLEN];
 603        ssize_t length;
 604
 605        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot);
 606        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 607}
 608
 609static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
 610                                      size_t count, loff_t *ppos)
 611{
 612        char *page = NULL;
 613        ssize_t length;
 614        unsigned int new_value;
 615
 616        length = task_has_security(current, SECURITY__SETCHECKREQPROT);
 617        if (length)
 618                goto out;
 619
 620        length = -ENOMEM;
 621        if (count >= PAGE_SIZE)
 622                goto out;
 623
 624        /* No partial writes. */
 625        length = -EINVAL;
 626        if (*ppos != 0)
 627                goto out;
 628
 629        length = -ENOMEM;
 630        page = (char *)get_zeroed_page(GFP_KERNEL);
 631        if (!page)
 632                goto out;
 633
 634        length = -EFAULT;
 635        if (copy_from_user(page, buf, count))
 636                goto out;
 637
 638        length = -EINVAL;
 639        if (sscanf(page, "%u", &new_value) != 1)
 640                goto out;
 641
 642        selinux_checkreqprot = new_value ? 1 : 0;
 643        length = count;
 644out:
 645        free_page((unsigned long) page);
 646        return length;
 647}
 648static const struct file_operations sel_checkreqprot_ops = {
 649        .read           = sel_read_checkreqprot,
 650        .write          = sel_write_checkreqprot,
 651        .llseek         = generic_file_llseek,
 652};
 653
 654/*
 655 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
 656 */
 657static ssize_t sel_write_access(struct file *file, char *buf, size_t size);
 658static ssize_t sel_write_create(struct file *file, char *buf, size_t size);
 659static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size);
 660static ssize_t sel_write_user(struct file *file, char *buf, size_t size);
 661static ssize_t sel_write_member(struct file *file, char *buf, size_t size);
 662
 663static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 664        [SEL_ACCESS] = sel_write_access,
 665        [SEL_CREATE] = sel_write_create,
 666        [SEL_RELABEL] = sel_write_relabel,
 667        [SEL_USER] = sel_write_user,
 668        [SEL_MEMBER] = sel_write_member,
 669        [SEL_CONTEXT] = sel_write_context,
 670};
 671
 672static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
 673{
 674        ino_t ino = file->f_path.dentry->d_inode->i_ino;
 675        char *data;
 676        ssize_t rv;
 677
 678        if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
 679                return -EINVAL;
 680
 681        data = simple_transaction_get(file, buf, size);
 682        if (IS_ERR(data))
 683                return PTR_ERR(data);
 684
 685        rv = write_op[ino](file, data, size);
 686        if (rv > 0) {
 687                simple_transaction_set(file, rv);
 688                rv = size;
 689        }
 690        return rv;
 691}
 692
 693static const struct file_operations transaction_ops = {
 694        .write          = selinux_transaction_write,
 695        .read           = simple_transaction_read,
 696        .release        = simple_transaction_release,
 697        .llseek         = generic_file_llseek,
 698};
 699
 700/*
 701 * payload - write methods
 702 * If the method has a response, the response should be put in buf,
 703 * and the length returned.  Otherwise return 0 or and -error.
 704 */
 705
 706static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
 707{
 708        char *scon = NULL, *tcon = NULL;
 709        u32 ssid, tsid;
 710        u16 tclass;
 711        struct av_decision avd;
 712        ssize_t length;
 713
 714        length = task_has_security(current, SECURITY__COMPUTE_AV);
 715        if (length)
 716                goto out;
 717
 718        length = -ENOMEM;
 719        scon = kzalloc(size + 1, GFP_KERNEL);
 720        if (!scon)
 721                goto out;
 722
 723        length = -ENOMEM;
 724        tcon = kzalloc(size + 1, GFP_KERNEL);
 725        if (!tcon)
 726                goto out;
 727
 728        length = -EINVAL;
 729        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 730                goto out;
 731
 732        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 733        if (length)
 734                goto out;
 735
 736        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 737        if (length)
 738                goto out;
 739
 740        security_compute_av_user(ssid, tsid, tclass, &avd);
 741
 742        length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
 743                          "%x %x %x %x %u %x",
 744                          avd.allowed, 0xffffffff,
 745                          avd.auditallow, avd.auditdeny,
 746                          avd.seqno, avd.flags);
 747out:
 748        kfree(tcon);
 749        kfree(scon);
 750        return length;
 751}
 752
 753static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
 754{
 755        char *scon = NULL, *tcon = NULL;
 756        u32 ssid, tsid, newsid;
 757        u16 tclass;
 758        ssize_t length;
 759        char *newcon = NULL;
 760        u32 len;
 761
 762        length = task_has_security(current, SECURITY__COMPUTE_CREATE);
 763        if (length)
 764                goto out;
 765
 766        length = -ENOMEM;
 767        scon = kzalloc(size + 1, GFP_KERNEL);
 768        if (!scon)
 769                goto out;
 770
 771        length = -ENOMEM;
 772        tcon = kzalloc(size + 1, GFP_KERNEL);
 773        if (!tcon)
 774                goto out;
 775
 776        length = -EINVAL;
 777        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 778                goto out;
 779
 780        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 781        if (length)
 782                goto out;
 783
 784        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 785        if (length)
 786                goto out;
 787
 788        length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
 789        if (length)
 790                goto out;
 791
 792        length = security_sid_to_context(newsid, &newcon, &len);
 793        if (length)
 794                goto out;
 795
 796        length = -ERANGE;
 797        if (len > SIMPLE_TRANSACTION_LIMIT) {
 798                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
 799                        "payload max\n", __func__, len);
 800                goto out;
 801        }
 802
 803        memcpy(buf, newcon, len);
 804        length = len;
 805out:
 806        kfree(newcon);
 807        kfree(tcon);
 808        kfree(scon);
 809        return length;
 810}
 811
 812static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
 813{
 814        char *scon = NULL, *tcon = NULL;
 815        u32 ssid, tsid, newsid;
 816        u16 tclass;
 817        ssize_t length;
 818        char *newcon = NULL;
 819        u32 len;
 820
 821        length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
 822        if (length)
 823                goto out;
 824
 825        length = -ENOMEM;
 826        scon = kzalloc(size + 1, GFP_KERNEL);
 827        if (!scon)
 828                goto out;
 829
 830        length = -ENOMEM;
 831        tcon = kzalloc(size + 1, GFP_KERNEL);
 832        if (!tcon)
 833                goto out;
 834
 835        length = -EINVAL;
 836        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 837                goto out;
 838
 839        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 840        if (length)
 841                goto out;
 842
 843        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 844        if (length)
 845                goto out;
 846
 847        length = security_change_sid(ssid, tsid, tclass, &newsid);
 848        if (length)
 849                goto out;
 850
 851        length = security_sid_to_context(newsid, &newcon, &len);
 852        if (length)
 853                goto out;
 854
 855        length = -ERANGE;
 856        if (len > SIMPLE_TRANSACTION_LIMIT)
 857                goto out;
 858
 859        memcpy(buf, newcon, len);
 860        length = len;
 861out:
 862        kfree(newcon);
 863        kfree(tcon);
 864        kfree(scon);
 865        return length;
 866}
 867
 868static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
 869{
 870        char *con = NULL, *user = NULL, *ptr;
 871        u32 sid, *sids = NULL;
 872        ssize_t length;
 873        char *newcon;
 874        int i, rc;
 875        u32 len, nsids;
 876
 877        length = task_has_security(current, SECURITY__COMPUTE_USER);
 878        if (length)
 879                goto out;;
 880
 881        length = -ENOMEM;
 882        con = kzalloc(size + 1, GFP_KERNEL);
 883        if (!con)
 884                goto out;;
 885
 886        length = -ENOMEM;
 887        user = kzalloc(size + 1, GFP_KERNEL);
 888        if (!user)
 889                goto out;
 890
 891        length = -EINVAL;
 892        if (sscanf(buf, "%s %s", con, user) != 2)
 893                goto out;
 894
 895        length = security_context_to_sid(con, strlen(con) + 1, &sid);
 896        if (length)
 897                goto out;
 898
 899        length = security_get_user_sids(sid, user, &sids, &nsids);
 900        if (length)
 901                goto out;
 902
 903        length = sprintf(buf, "%u", nsids) + 1;
 904        ptr = buf + length;
 905        for (i = 0; i < nsids; i++) {
 906                rc = security_sid_to_context(sids[i], &newcon, &len);
 907                if (rc) {
 908                        length = rc;
 909                        goto out;
 910                }
 911                if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
 912                        kfree(newcon);
 913                        length = -ERANGE;
 914                        goto out;
 915                }
 916                memcpy(ptr, newcon, len);
 917                kfree(newcon);
 918                ptr += len;
 919                length += len;
 920        }
 921out:
 922        kfree(sids);
 923        kfree(user);
 924        kfree(con);
 925        return length;
 926}
 927
 928static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
 929{
 930        char *scon = NULL, *tcon = NULL;
 931        u32 ssid, tsid, newsid;
 932        u16 tclass;
 933        ssize_t length;
 934        char *newcon = NULL;
 935        u32 len;
 936
 937        length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
 938        if (length)
 939                goto out;
 940
 941        length = -ENOMEM;
 942        scon = kzalloc(size + 1, GFP_KERNEL);
 943        if (!scon)
 944                goto out;;
 945
 946        length = -ENOMEM;
 947        tcon = kzalloc(size + 1, GFP_KERNEL);
 948        if (!tcon)
 949                goto out;
 950
 951        length = -EINVAL;
 952        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 953                goto out;
 954
 955        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 956        if (length)
 957                goto out;
 958
 959        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 960        if (length)
 961                goto out;
 962
 963        length = security_member_sid(ssid, tsid, tclass, &newsid);
 964        if (length)
 965                goto out;
 966
 967        length = security_sid_to_context(newsid, &newcon, &len);
 968        if (length)
 969                goto out;
 970
 971        length = -ERANGE;
 972        if (len > SIMPLE_TRANSACTION_LIMIT) {
 973                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
 974                        "payload max\n", __func__, len);
 975                goto out;
 976        }
 977
 978        memcpy(buf, newcon, len);
 979        length = len;
 980out:
 981        kfree(newcon);
 982        kfree(tcon);
 983        kfree(scon);
 984        return length;
 985}
 986
 987static struct inode *sel_make_inode(struct super_block *sb, int mode)
 988{
 989        struct inode *ret = new_inode(sb);
 990
 991        if (ret) {
 992                ret->i_mode = mode;
 993                ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
 994        }
 995        return ret;
 996}
 997
 998static ssize_t sel_read_bool(struct file *filep, char __user *buf,
 999                             size_t count, loff_t *ppos)
1000{
1001        char *page = NULL;
1002        ssize_t length;
1003        ssize_t ret;
1004        int cur_enforcing;
1005        struct inode *inode = filep->f_path.dentry->d_inode;
1006        unsigned index = inode->i_ino & SEL_INO_MASK;
1007        const char *name = filep->f_path.dentry->d_name.name;
1008
1009        mutex_lock(&sel_mutex);
1010
1011        ret = -EINVAL;
1012        if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1013                goto out;
1014
1015        ret = -ENOMEM;
1016        page = (char *)get_zeroed_page(GFP_KERNEL);
1017        if (!page)
1018                goto out;
1019
1020        cur_enforcing = security_get_bool_value(index);
1021        if (cur_enforcing < 0) {
1022                ret = cur_enforcing;
1023                goto out;
1024        }
1025        length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
1026                          bool_pending_values[index]);
1027        ret = simple_read_from_buffer(buf, count, ppos, page, length);
1028out:
1029        mutex_unlock(&sel_mutex);
1030        free_page((unsigned long)page);
1031        return ret;
1032}
1033
1034static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1035                              size_t count, loff_t *ppos)
1036{
1037        char *page = NULL;
1038        ssize_t length;
1039        int new_value;
1040        struct inode *inode = filep->f_path.dentry->d_inode;
1041        unsigned index = inode->i_ino & SEL_INO_MASK;
1042        const char *name = filep->f_path.dentry->d_name.name;
1043
1044        mutex_lock(&sel_mutex);
1045
1046        length = task_has_security(current, SECURITY__SETBOOL);
1047        if (length)
1048                goto out;
1049
1050        length = -EINVAL;
1051        if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1052                goto out;
1053
1054        length = -ENOMEM;
1055        if (count >= PAGE_SIZE)
1056                goto out;
1057
1058        /* No partial writes. */
1059        length = -EINVAL;
1060        if (*ppos != 0)
1061                goto out;
1062
1063        length = -ENOMEM;
1064        page = (char *)get_zeroed_page(GFP_KERNEL);
1065        if (!page)
1066                goto out;
1067
1068        length = -EFAULT;
1069        if (copy_from_user(page, buf, count))
1070                goto out;
1071
1072        length = -EINVAL;
1073        if (sscanf(page, "%d", &new_value) != 1)
1074                goto out;
1075
1076        if (new_value)
1077                new_value = 1;
1078
1079        bool_pending_values[index] = new_value;
1080        length = count;
1081
1082out:
1083        mutex_unlock(&sel_mutex);
1084        free_page((unsigned long) page);
1085        return length;
1086}
1087
1088static const struct file_operations sel_bool_ops = {
1089        .read           = sel_read_bool,
1090        .write          = sel_write_bool,
1091        .llseek         = generic_file_llseek,
1092};
1093
1094static ssize_t sel_commit_bools_write(struct file *filep,
1095                                      const char __user *buf,
1096                                      size_t count, loff_t *ppos)
1097{
1098        char *page = NULL;
1099        ssize_t length;
1100        int new_value;
1101
1102        mutex_lock(&sel_mutex);
1103
1104        length = task_has_security(current, SECURITY__SETBOOL);
1105        if (length)
1106                goto out;
1107
1108        length = -ENOMEM;
1109        if (count >= PAGE_SIZE)
1110                goto out;
1111
1112        /* No partial writes. */
1113        length = -EINVAL;
1114        if (*ppos != 0)
1115                goto out;
1116
1117        length = -ENOMEM;
1118        page = (char *)get_zeroed_page(GFP_KERNEL);
1119        if (!page)
1120                goto out;
1121
1122        length = -EFAULT;
1123        if (copy_from_user(page, buf, count))
1124                goto out;
1125
1126        length = -EINVAL;
1127        if (sscanf(page, "%d", &new_value) != 1)
1128                goto out;
1129
1130        length = 0;
1131        if (new_value && bool_pending_values)
1132                length = security_set_bools(bool_num, bool_pending_values);
1133
1134        if (!length)
1135                length = count;
1136
1137out:
1138        mutex_unlock(&sel_mutex);
1139        free_page((unsigned long) page);
1140        return length;
1141}
1142
1143static const struct file_operations sel_commit_bools_ops = {
1144        .write          = sel_commit_bools_write,
1145        .llseek         = generic_file_llseek,
1146};
1147
1148static void sel_remove_entries(struct dentry *de)
1149{
1150        struct list_head *node;
1151
1152        spin_lock(&de->d_lock);
1153        node = de->d_subdirs.next;
1154        while (node != &de->d_subdirs) {
1155                struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1156
1157                spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
1158                list_del_init(node);
1159
1160                if (d->d_inode) {
1161                        dget_dlock(d);
1162                        spin_unlock(&de->d_lock);
1163                        spin_unlock(&d->d_lock);
1164                        d_delete(d);
1165                        simple_unlink(de->d_inode, d);
1166                        dput(d);
1167                        spin_lock(&de->d_lock);
1168                } else
1169                        spin_unlock(&d->d_lock);
1170                node = de->d_subdirs.next;
1171        }
1172
1173        spin_unlock(&de->d_lock);
1174}
1175
1176#define BOOL_DIR_NAME "booleans"
1177
1178static int sel_make_bools(void)
1179{
1180        int i, ret;
1181        ssize_t len;
1182        struct dentry *dentry = NULL;
1183        struct dentry *dir = bool_dir;
1184        struct inode *inode = NULL;
1185        struct inode_security_struct *isec;
1186        char **names = NULL, *page;
1187        int num;
1188        int *values = NULL;
1189        u32 sid;
1190
1191        /* remove any existing files */
1192        for (i = 0; i < bool_num; i++)
1193                kfree(bool_pending_names[i]);
1194        kfree(bool_pending_names);
1195        kfree(bool_pending_values);
1196        bool_pending_names = NULL;
1197        bool_pending_values = NULL;
1198
1199        sel_remove_entries(dir);
1200
1201        ret = -ENOMEM;
1202        page = (char *)get_zeroed_page(GFP_KERNEL);
1203        if (!page)
1204                goto out;
1205
1206        ret = security_get_bools(&num, &names, &values);
1207        if (ret)
1208                goto out;
1209
1210        for (i = 0; i < num; i++) {
1211                ret = -ENOMEM;
1212                dentry = d_alloc_name(dir, names[i]);
1213                if (!dentry)
1214                        goto out;
1215
1216                ret = -ENOMEM;
1217                inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1218                if (!inode)
1219                        goto out;
1220
1221                ret = -EINVAL;
1222                len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1223                if (len < 0)
1224                        goto out;
1225
1226                ret = -ENAMETOOLONG;
1227                if (len >= PAGE_SIZE)
1228                        goto out;
1229
1230                isec = (struct inode_security_struct *)inode->i_security;
1231                ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1232                if (ret)
1233                        goto out;
1234
1235                isec->sid = sid;
1236                isec->initialized = 1;
1237                inode->i_fop = &sel_bool_ops;
1238                inode->i_ino = i|SEL_BOOL_INO_OFFSET;
1239                d_add(dentry, inode);
1240        }
1241        bool_num = num;
1242        bool_pending_names = names;
1243        bool_pending_values = values;
1244
1245        free_page((unsigned long)page);
1246        return 0;
1247out:
1248        free_page((unsigned long)page);
1249
1250        if (names) {
1251                for (i = 0; i < num; i++)
1252                        kfree(names[i]);
1253                kfree(names);
1254        }
1255        kfree(values);
1256        sel_remove_entries(dir);
1257
1258        return ret;
1259}
1260
1261#define NULL_FILE_NAME "null"
1262
1263struct dentry *selinux_null;
1264
1265static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1266                                            size_t count, loff_t *ppos)
1267{
1268        char tmpbuf[TMPBUFLEN];
1269        ssize_t length;
1270
1271        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold);
1272        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1273}
1274
1275static ssize_t sel_write_avc_cache_threshold(struct file *file,
1276                                             const char __user *buf,
1277                                             size_t count, loff_t *ppos)
1278
1279{
1280        char *page = NULL;
1281        ssize_t ret;
1282        int new_value;
1283
1284        ret = task_has_security(current, SECURITY__SETSECPARAM);
1285        if (ret)
1286                goto out;
1287
1288        ret = -ENOMEM;
1289        if (count >= PAGE_SIZE)
1290                goto out;
1291
1292        /* No partial writes. */
1293        ret = -EINVAL;
1294        if (*ppos != 0)
1295                goto out;
1296
1297        ret = -ENOMEM;
1298        page = (char *)get_zeroed_page(GFP_KERNEL);
1299        if (!page)
1300                goto out;
1301
1302        ret = -EFAULT;
1303        if (copy_from_user(page, buf, count))
1304                goto out;
1305
1306        ret = -EINVAL;
1307        if (sscanf(page, "%u", &new_value) != 1)
1308                goto out;
1309
1310        avc_cache_threshold = new_value;
1311
1312        ret = count;
1313out:
1314        free_page((unsigned long)page);
1315        return ret;
1316}
1317
1318static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1319                                       size_t count, loff_t *ppos)
1320{
1321        char *page;
1322        ssize_t length;
1323
1324        page = (char *)__get_free_page(GFP_KERNEL);
1325        if (!page)
1326                return -ENOMEM;
1327
1328        length = avc_get_hash_stats(page);
1329        if (length >= 0)
1330                length = simple_read_from_buffer(buf, count, ppos, page, length);
1331        free_page((unsigned long)page);
1332
1333        return length;
1334}
1335
1336static const struct file_operations sel_avc_cache_threshold_ops = {
1337        .read           = sel_read_avc_cache_threshold,
1338        .write          = sel_write_avc_cache_threshold,
1339        .llseek         = generic_file_llseek,
1340};
1341
1342static const struct file_operations sel_avc_hash_stats_ops = {
1343        .read           = sel_read_avc_hash_stats,
1344        .llseek         = generic_file_llseek,
1345};
1346
1347#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1348static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
1349{
1350        int cpu;
1351
1352        for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) {
1353                if (!cpu_possible(cpu))
1354                        continue;
1355                *idx = cpu + 1;
1356                return &per_cpu(avc_cache_stats, cpu);
1357        }
1358        return NULL;
1359}
1360
1361static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
1362{
1363        loff_t n = *pos - 1;
1364
1365        if (*pos == 0)
1366                return SEQ_START_TOKEN;
1367
1368        return sel_avc_get_stat_idx(&n);
1369}
1370
1371static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1372{
1373        return sel_avc_get_stat_idx(pos);
1374}
1375
1376static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1377{
1378        struct avc_cache_stats *st = v;
1379
1380        if (v == SEQ_START_TOKEN)
1381                seq_printf(seq, "lookups hits misses allocations reclaims "
1382                           "frees\n");
1383        else
1384                seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups,
1385                           st->hits, st->misses, st->allocations,
1386                           st->reclaims, st->frees);
1387        return 0;
1388}
1389
1390static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
1391{ }
1392
1393static const struct seq_operations sel_avc_cache_stats_seq_ops = {
1394        .start          = sel_avc_stats_seq_start,
1395        .next           = sel_avc_stats_seq_next,
1396        .show           = sel_avc_stats_seq_show,
1397        .stop           = sel_avc_stats_seq_stop,
1398};
1399
1400static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
1401{
1402        return seq_open(file, &sel_avc_cache_stats_seq_ops);
1403}
1404
1405static const struct file_operations sel_avc_cache_stats_ops = {
1406        .open           = sel_open_avc_cache_stats,
1407        .read           = seq_read,
1408        .llseek         = seq_lseek,
1409        .release        = seq_release,
1410};
1411#endif
1412
1413static int sel_make_avc_files(struct dentry *dir)
1414{
1415        int i;
1416        static struct tree_descr files[] = {
1417                { "cache_threshold",
1418                  &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
1419                { "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
1420#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1421                { "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
1422#endif
1423        };
1424
1425        for (i = 0; i < ARRAY_SIZE(files); i++) {
1426                struct inode *inode;
1427                struct dentry *dentry;
1428
1429                dentry = d_alloc_name(dir, files[i].name);
1430                if (!dentry)
1431                        return -ENOMEM;
1432
1433                inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1434                if (!inode)
1435                        return -ENOMEM;
1436
1437                inode->i_fop = files[i].ops;
1438                inode->i_ino = ++sel_last_ino;
1439                d_add(dentry, inode);
1440        }
1441
1442        return 0;
1443}
1444
1445static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1446                                size_t count, loff_t *ppos)
1447{
1448        struct inode *inode;
1449        char *con;
1450        u32 sid, len;
1451        ssize_t ret;
1452
1453        inode = file->f_path.dentry->d_inode;
1454        sid = inode->i_ino&SEL_INO_MASK;
1455        ret = security_sid_to_context(sid, &con, &len);
1456        if (ret)
1457                return ret;
1458
1459        ret = simple_read_from_buffer(buf, count, ppos, con, len);
1460        kfree(con);
1461        return ret;
1462}
1463
1464static const struct file_operations sel_initcon_ops = {
1465        .read           = sel_read_initcon,
1466        .llseek         = generic_file_llseek,
1467};
1468
1469static int sel_make_initcon_files(struct dentry *dir)
1470{
1471        int i;
1472
1473        for (i = 1; i <= SECINITSID_NUM; i++) {
1474                struct inode *inode;
1475                struct dentry *dentry;
1476                dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1477                if (!dentry)
1478                        return -ENOMEM;
1479
1480                inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1481                if (!inode)
1482                        return -ENOMEM;
1483
1484                inode->i_fop = &sel_initcon_ops;
1485                inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1486                d_add(dentry, inode);
1487        }
1488
1489        return 0;
1490}
1491
1492static inline unsigned int sel_div(unsigned long a, unsigned long b)
1493{
1494        return a / b - (a % b < 0);
1495}
1496
1497static inline unsigned long sel_class_to_ino(u16 class)
1498{
1499        return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
1500}
1501
1502static inline u16 sel_ino_to_class(unsigned long ino)
1503{
1504        return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
1505}
1506
1507static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
1508{
1509        return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
1510}
1511
1512static inline u32 sel_ino_to_perm(unsigned long ino)
1513{
1514        return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
1515}
1516
1517static ssize_t sel_read_class(struct file *file, char __user *buf,
1518                                size_t count, loff_t *ppos)
1519{
1520        ssize_t rc, len;
1521        char *page;
1522        unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1523
1524        page = (char *)__get_free_page(GFP_KERNEL);
1525        if (!page)
1526                return -ENOMEM;
1527
1528        len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1529        rc = simple_read_from_buffer(buf, count, ppos, page, len);
1530        free_page((unsigned long)page);
1531
1532        return rc;
1533}
1534
1535static const struct file_operations sel_class_ops = {
1536        .read           = sel_read_class,
1537        .llseek         = generic_file_llseek,
1538};
1539
1540static ssize_t sel_read_perm(struct file *file, char __user *buf,
1541                                size_t count, loff_t *ppos)
1542{
1543        ssize_t rc, len;
1544        char *page;
1545        unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1546
1547        page = (char *)__get_free_page(GFP_KERNEL);
1548        if (!page)
1549                return -ENOMEM;
1550
1551        len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1552        rc = simple_read_from_buffer(buf, count, ppos, page, len);
1553        free_page((unsigned long)page);
1554
1555        return rc;
1556}
1557
1558static const struct file_operations sel_perm_ops = {
1559        .read           = sel_read_perm,
1560        .llseek         = generic_file_llseek,
1561};
1562
1563static ssize_t sel_read_policycap(struct file *file, char __user *buf,
1564                                  size_t count, loff_t *ppos)
1565{
1566        int value;
1567        char tmpbuf[TMPBUFLEN];
1568        ssize_t length;
1569        unsigned long i_ino = file->f_path.dentry->d_inode->i_ino;
1570
1571        value = security_policycap_supported(i_ino & SEL_INO_MASK);
1572        length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
1573
1574        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1575}
1576
1577static const struct file_operations sel_policycap_ops = {
1578        .read           = sel_read_policycap,
1579        .llseek         = generic_file_llseek,
1580};
1581
1582static int sel_make_perm_files(char *objclass, int classvalue,
1583                                struct dentry *dir)
1584{
1585        int i, rc, nperms;
1586        char **perms;
1587
1588        rc = security_get_permissions(objclass, &perms, &nperms);
1589        if (rc)
1590                return rc;
1591
1592        for (i = 0; i < nperms; i++) {
1593                struct inode *inode;
1594                struct dentry *dentry;
1595
1596                rc = -ENOMEM;
1597                dentry = d_alloc_name(dir, perms[i]);
1598                if (!dentry)
1599                        goto out;
1600
1601                rc = -ENOMEM;
1602                inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1603                if (!inode)
1604                        goto out;
1605
1606                inode->i_fop = &sel_perm_ops;
1607                /* i+1 since perm values are 1-indexed */
1608                inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1609                d_add(dentry, inode);
1610        }
1611        rc = 0;
1612out:
1613        for (i = 0; i < nperms; i++)
1614                kfree(perms[i]);
1615        kfree(perms);
1616        return rc;
1617}
1618
1619static int sel_make_class_dir_entries(char *classname, int index,
1620                                        struct dentry *dir)
1621{
1622        struct dentry *dentry = NULL;
1623        struct inode *inode = NULL;
1624        int rc;
1625
1626        dentry = d_alloc_name(dir, "index");
1627        if (!dentry)
1628                return -ENOMEM;
1629
1630        inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1631        if (!inode)
1632                return -ENOMEM;
1633
1634        inode->i_fop = &sel_class_ops;
1635        inode->i_ino = sel_class_to_ino(index);
1636        d_add(dentry, inode);
1637
1638        dentry = d_alloc_name(dir, "perms");
1639        if (!dentry)
1640                return -ENOMEM;
1641
1642        rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1643        if (rc)
1644                return rc;
1645
1646        rc = sel_make_perm_files(classname, index, dentry);
1647
1648        return rc;
1649}
1650
1651static void sel_remove_classes(void)
1652{
1653        struct list_head *class_node;
1654
1655        list_for_each(class_node, &class_dir->d_subdirs) {
1656                struct dentry *class_subdir = list_entry(class_node,
1657                                        struct dentry, d_u.d_child);
1658                struct list_head *class_subdir_node;
1659
1660                list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
1661                        struct dentry *d = list_entry(class_subdir_node,
1662                                                struct dentry, d_u.d_child);
1663
1664                        if (d->d_inode)
1665                                if (d->d_inode->i_mode & S_IFDIR)
1666                                        sel_remove_entries(d);
1667                }
1668
1669                sel_remove_entries(class_subdir);
1670        }
1671
1672        sel_remove_entries(class_dir);
1673}
1674
1675static int sel_make_classes(void)
1676{
1677        int rc, nclasses, i;
1678        char **classes;
1679
1680        /* delete any existing entries */
1681        sel_remove_classes();
1682
1683        rc = security_get_classes(&classes, &nclasses);
1684        if (rc)
1685                return rc;
1686
1687        /* +2 since classes are 1-indexed */
1688        last_class_ino = sel_class_to_ino(nclasses + 2);
1689
1690        for (i = 0; i < nclasses; i++) {
1691                struct dentry *class_name_dir;
1692
1693                rc = -ENOMEM;
1694                class_name_dir = d_alloc_name(class_dir, classes[i]);
1695                if (!class_name_dir)
1696                        goto out;
1697
1698                rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1699                                &last_class_ino);
1700                if (rc)
1701                        goto out;
1702
1703                /* i+1 since class values are 1-indexed */
1704                rc = sel_make_class_dir_entries(classes[i], i + 1,
1705                                class_name_dir);
1706                if (rc)
1707                        goto out;
1708        }
1709        rc = 0;
1710out:
1711        for (i = 0; i < nclasses; i++)
1712                kfree(classes[i]);
1713        kfree(classes);
1714        return rc;
1715}
1716
1717static int sel_make_policycap(void)
1718{
1719        unsigned int iter;
1720        struct dentry *dentry = NULL;
1721        struct inode *inode = NULL;
1722
1723        sel_remove_entries(policycap_dir);
1724
1725        for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
1726                if (iter < ARRAY_SIZE(policycap_names))
1727                        dentry = d_alloc_name(policycap_dir,
1728                                              policycap_names[iter]);
1729                else
1730                        dentry = d_alloc_name(policycap_dir, "unknown");
1731
1732                if (dentry == NULL)
1733                        return -ENOMEM;
1734
1735                inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
1736                if (inode == NULL)
1737                        return -ENOMEM;
1738
1739                inode->i_fop = &sel_policycap_ops;
1740                inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
1741                d_add(dentry, inode);
1742        }
1743
1744        return 0;
1745}
1746
1747static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1748                        unsigned long *ino)
1749{
1750        struct inode *inode;
1751
1752        inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1753        if (!inode)
1754                return -ENOMEM;
1755
1756        inode->i_op = &simple_dir_inode_operations;
1757        inode->i_fop = &simple_dir_operations;
1758        inode->i_ino = ++(*ino);
1759        /* directory inodes start off with i_nlink == 2 (for "." entry) */
1760        inc_nlink(inode);
1761        d_add(dentry, inode);
1762        /* bump link count on parent directory, too */
1763        inc_nlink(dir);
1764
1765        return 0;
1766}
1767
1768static int sel_fill_super(struct super_block *sb, void *data, int silent)
1769{
1770        int ret;
1771        struct dentry *dentry;
1772        struct inode *inode, *root_inode;
1773        struct inode_security_struct *isec;
1774
1775        static struct tree_descr selinux_files[] = {
1776                [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1777                [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1778                [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1779                [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1780                [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1781                [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
1782                [SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
1783                [SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO},
1784                [SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
1785                [SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
1786                [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1787                [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1788                [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1789                [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1790                [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1791                [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
1792                [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
1793                /* last one */ {""}
1794        };
1795        ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1796        if (ret)
1797                goto err;
1798
1799        root_inode = sb->s_root->d_inode;
1800
1801        ret = -ENOMEM;
1802        dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1803        if (!dentry)
1804                goto err;
1805
1806        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1807        if (ret)
1808                goto err;
1809
1810        bool_dir = dentry;
1811
1812        ret = -ENOMEM;
1813        dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1814        if (!dentry)
1815                goto err;
1816
1817        ret = -ENOMEM;
1818        inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1819        if (!inode)
1820                goto err;
1821
1822        inode->i_ino = ++sel_last_ino;
1823        isec = (struct inode_security_struct *)inode->i_security;
1824        isec->sid = SECINITSID_DEVNULL;
1825        isec->sclass = SECCLASS_CHR_FILE;
1826        isec->initialized = 1;
1827
1828        init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
1829        d_add(dentry, inode);
1830        selinux_null = dentry;
1831
1832        ret = -ENOMEM;
1833        dentry = d_alloc_name(sb->s_root, "avc");
1834        if (!dentry)
1835                goto err;
1836
1837        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1838        if (ret)
1839                goto err;
1840
1841        ret = sel_make_avc_files(dentry);
1842        if (ret)
1843                goto err;
1844
1845        ret = -ENOMEM;
1846        dentry = d_alloc_name(sb->s_root, "initial_contexts");
1847        if (!dentry)
1848                goto err;
1849
1850        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1851        if (ret)
1852                goto err;
1853
1854        ret = sel_make_initcon_files(dentry);
1855        if (ret)
1856                goto err;
1857
1858        ret = -ENOMEM;
1859        dentry = d_alloc_name(sb->s_root, "class");
1860        if (!dentry)
1861                goto err;
1862
1863        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1864        if (ret)
1865                goto err;
1866
1867        class_dir = dentry;
1868
1869        ret = -ENOMEM;
1870        dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1871        if (!dentry)
1872                goto err;
1873
1874        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1875        if (ret)
1876                goto err;
1877
1878        policycap_dir = dentry;
1879
1880        return 0;
1881err:
1882        printk(KERN_ERR "SELinux: %s:  failed while creating inodes\n",
1883                __func__);
1884        return ret;
1885}
1886
1887static struct dentry *sel_mount(struct file_system_type *fs_type,
1888                      int flags, const char *dev_name, void *data)
1889{
1890        return mount_single(fs_type, flags, data, sel_fill_super);
1891}
1892
1893static struct file_system_type sel_fs_type = {
1894        .name           = "selinuxfs",
1895        .mount          = sel_mount,
1896        .kill_sb        = kill_litter_super,
1897};
1898
1899struct vfsmount *selinuxfs_mount;
1900
1901static int __init init_sel_fs(void)
1902{
1903        int err;
1904
1905        if (!selinux_enabled)
1906                return 0;
1907        err = register_filesystem(&sel_fs_type);
1908        if (err)
1909                return err;
1910
1911        selinuxfs_mount = kern_mount(&sel_fs_type);
1912        if (IS_ERR(selinuxfs_mount)) {
1913                printk(KERN_ERR "selinuxfs:  could not mount!\n");
1914                err = PTR_ERR(selinuxfs_mount);
1915                selinuxfs_mount = NULL;
1916        }
1917
1918        return err;
1919}
1920
1921__initcall(init_sel_fs);
1922
1923#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1924void exit_sel_fs(void)
1925{
1926        unregister_filesystem(&sel_fs_type);
1927}
1928#endif
1929