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