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
  44/* Policy capability filenames */
  45static char *policycap_names[] = {
  46        "network_peer_controls",
  47        "open_perms"
  48};
  49
  50unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
  51
  52static int __init checkreqprot_setup(char *str)
  53{
  54        unsigned long checkreqprot;
  55        if (!strict_strtoul(str, 0, &checkreqprot))
  56                selinux_checkreqprot = checkreqprot ? 1 : 0;
  57        return 1;
  58}
  59__setup("checkreqprot=", checkreqprot_setup);
  60
  61static DEFINE_MUTEX(sel_mutex);
  62
  63/* global data for booleans */
  64static struct dentry *bool_dir;
  65static int bool_num;
  66static char **bool_pending_names;
  67static int *bool_pending_values;
  68
  69/* global data for classes */
  70static struct dentry *class_dir;
  71static unsigned long last_class_ino;
  72
  73static char policy_opened;
  74
  75/* global data for policy capabilities */
  76static struct dentry *policycap_dir;
  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
 280        length = -ENOMEM;
 281        if (count >= PAGE_SIZE)
 282                goto out;
 283
 284        /* No partial writes. */
 285        length = -EINVAL;
 286        if (*ppos != 0)
 287                goto out;
 288
 289        length = -ENOMEM;
 290        page = (char *)get_zeroed_page(GFP_KERNEL);
 291        if (!page)
 292                goto out;
 293
 294        length = -EFAULT;
 295        if (copy_from_user(page, buf, count))
 296                goto out;
 297
 298        length = -EINVAL;
 299        if (sscanf(page, "%d", &new_value) != 1)
 300                goto out;
 301
 302        if (new_value) {
 303                length = selinux_disable();
 304                if (length)
 305                        goto out;
 306                audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
 307                        "selinux=0 auid=%u ses=%u",
 308                        audit_get_loginuid(current),
 309                        audit_get_sessionid(current));
 310        }
 311
 312        length = count;
 313out:
 314        free_page((unsigned long) page);
 315        return length;
 316}
 317#else
 318#define sel_write_disable NULL
 319#endif
 320
 321static const struct file_operations sel_disable_ops = {
 322        .write          = sel_write_disable,
 323        .llseek         = generic_file_llseek,
 324};
 325
 326static ssize_t sel_read_policyvers(struct file *filp, char __user *buf,
 327                                   size_t count, loff_t *ppos)
 328{
 329        char tmpbuf[TMPBUFLEN];
 330        ssize_t length;
 331
 332        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX);
 333        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 334}
 335
 336static const struct file_operations sel_policyvers_ops = {
 337        .read           = sel_read_policyvers,
 338        .llseek         = generic_file_llseek,
 339};
 340
 341/* declaration for sel_write_load */
 342static int sel_make_bools(void);
 343static int sel_make_classes(void);
 344static int sel_make_policycap(void);
 345
 346/* declaration for sel_make_class_dirs */
 347static int sel_make_dir(struct inode *dir, struct dentry *dentry,
 348                        unsigned long *ino);
 349
 350static ssize_t sel_read_mls(struct file *filp, char __user *buf,
 351                                size_t count, loff_t *ppos)
 352{
 353        char tmpbuf[TMPBUFLEN];
 354        ssize_t length;
 355
 356        length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
 357                           security_mls_enabled());
 358        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 359}
 360
 361static const struct file_operations sel_mls_ops = {
 362        .read           = sel_read_mls,
 363        .llseek         = generic_file_llseek,
 364};
 365
 366struct policy_load_memory {
 367        size_t len;
 368        void *data;
 369};
 370
 371static int sel_open_policy(struct inode *inode, struct file *filp)
 372{
 373        struct policy_load_memory *plm = NULL;
 374        int rc;
 375
 376        BUG_ON(filp->private_data);
 377
 378        mutex_lock(&sel_mutex);
 379
 380        rc = task_has_security(current, SECURITY__READ_POLICY);
 381        if (rc)
 382                goto err;
 383
 384        rc = -EBUSY;
 385        if (policy_opened)
 386                goto err;
 387
 388        rc = -ENOMEM;
 389        plm = kzalloc(sizeof(*plm), GFP_KERNEL);
 390        if (!plm)
 391                goto err;
 392
 393        if (i_size_read(inode) != security_policydb_len()) {
 394                mutex_lock(&inode->i_mutex);
 395                i_size_write(inode, security_policydb_len());
 396                mutex_unlock(&inode->i_mutex);
 397        }
 398
 399        rc = security_read_policy(&plm->data, &plm->len);
 400        if (rc)
 401                goto err;
 402
 403        policy_opened = 1;
 404
 405        filp->private_data = plm;
 406
 407        mutex_unlock(&sel_mutex);
 408
 409        return 0;
 410err:
 411        mutex_unlock(&sel_mutex);
 412
 413        if (plm)
 414                vfree(plm->data);
 415        kfree(plm);
 416        return rc;
 417}
 418
 419static int sel_release_policy(struct inode *inode, struct file *filp)
 420{
 421        struct policy_load_memory *plm = filp->private_data;
 422
 423        BUG_ON(!plm);
 424
 425        policy_opened = 0;
 426
 427        vfree(plm->data);
 428        kfree(plm);
 429
 430        return 0;
 431}
 432
 433static ssize_t sel_read_policy(struct file *filp, char __user *buf,
 434                               size_t count, loff_t *ppos)
 435{
 436        struct policy_load_memory *plm = filp->private_data;
 437        int ret;
 438
 439        mutex_lock(&sel_mutex);
 440
 441        ret = task_has_security(current, SECURITY__READ_POLICY);
 442        if (ret)
 443                goto out;
 444
 445        ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len);
 446out:
 447        mutex_unlock(&sel_mutex);
 448        return ret;
 449}
 450
 451static int sel_mmap_policy_fault(struct vm_area_struct *vma,
 452                                 struct vm_fault *vmf)
 453{
 454        struct policy_load_memory *plm = vma->vm_file->private_data;
 455        unsigned long offset;
 456        struct page *page;
 457
 458        if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
 459                return VM_FAULT_SIGBUS;
 460
 461        offset = vmf->pgoff << PAGE_SHIFT;
 462        if (offset >= roundup(plm->len, PAGE_SIZE))
 463                return VM_FAULT_SIGBUS;
 464
 465        page = vmalloc_to_page(plm->data + offset);
 466        get_page(page);
 467
 468        vmf->page = page;
 469
 470        return 0;
 471}
 472
 473static struct vm_operations_struct sel_mmap_policy_ops = {
 474        .fault = sel_mmap_policy_fault,
 475        .page_mkwrite = sel_mmap_policy_fault,
 476};
 477
 478static int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
 479{
 480        if (vma->vm_flags & VM_SHARED) {
 481                /* do not allow mprotect to make mapping writable */
 482                vma->vm_flags &= ~VM_MAYWRITE;
 483
 484                if (vma->vm_flags & VM_WRITE)
 485                        return -EACCES;
 486        }
 487
 488        vma->vm_flags |= VM_RESERVED;
 489        vma->vm_ops = &sel_mmap_policy_ops;
 490
 491        return 0;
 492}
 493
 494static const struct file_operations sel_policy_ops = {
 495        .open           = sel_open_policy,
 496        .read           = sel_read_policy,
 497        .mmap           = sel_mmap_policy,
 498        .release        = sel_release_policy,
 499};
 500
 501static ssize_t sel_write_load(struct file *file, const char __user *buf,
 502                              size_t count, loff_t *ppos)
 503
 504{
 505        ssize_t length;
 506        void *data = NULL;
 507
 508        mutex_lock(&sel_mutex);
 509
 510        length = task_has_security(current, SECURITY__LOAD_POLICY);
 511        if (length)
 512                goto out;
 513
 514        /* No partial writes. */
 515        length = -EINVAL;
 516        if (*ppos != 0)
 517                goto out;
 518
 519        length = -EFBIG;
 520        if (count > 64 * 1024 * 1024)
 521                goto out;
 522
 523        length = -ENOMEM;
 524        data = vmalloc(count);
 525        if (!data)
 526                goto out;
 527
 528        length = -EFAULT;
 529        if (copy_from_user(data, buf, count) != 0)
 530                goto out;
 531
 532        length = security_load_policy(data, count);
 533        if (length)
 534                goto out;
 535
 536        length = sel_make_bools();
 537        if (length)
 538                goto out1;
 539
 540        length = sel_make_classes();
 541        if (length)
 542                goto out1;
 543
 544        length = sel_make_policycap();
 545        if (length)
 546                goto out1;
 547
 548        length = count;
 549
 550out1:
 551        audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
 552                "policy loaded auid=%u ses=%u",
 553                audit_get_loginuid(current),
 554                audit_get_sessionid(current));
 555out:
 556        mutex_unlock(&sel_mutex);
 557        vfree(data);
 558        return length;
 559}
 560
 561static const struct file_operations sel_load_ops = {
 562        .write          = sel_write_load,
 563        .llseek         = generic_file_llseek,
 564};
 565
 566static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
 567{
 568        char *canon = NULL;
 569        u32 sid, len;
 570        ssize_t length;
 571
 572        length = task_has_security(current, SECURITY__CHECK_CONTEXT);
 573        if (length)
 574                goto out;
 575
 576        length = security_context_to_sid(buf, size, &sid);
 577        if (length)
 578                goto out;
 579
 580        length = security_sid_to_context(sid, &canon, &len);
 581        if (length)
 582                goto out;
 583
 584        length = -ERANGE;
 585        if (len > SIMPLE_TRANSACTION_LIMIT) {
 586                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
 587                        "payload max\n", __func__, len);
 588                goto out;
 589        }
 590
 591        memcpy(buf, canon, len);
 592        length = len;
 593out:
 594        kfree(canon);
 595        return length;
 596}
 597
 598static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
 599                                     size_t count, loff_t *ppos)
 600{
 601        char tmpbuf[TMPBUFLEN];
 602        ssize_t length;
 603
 604        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot);
 605        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
 606}
 607
 608static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
 609                                      size_t count, loff_t *ppos)
 610{
 611        char *page = NULL;
 612        ssize_t length;
 613        unsigned int new_value;
 614
 615        length = task_has_security(current, SECURITY__SETCHECKREQPROT);
 616        if (length)
 617                goto out;
 618
 619        length = -ENOMEM;
 620        if (count >= PAGE_SIZE)
 621                goto out;
 622
 623        /* No partial writes. */
 624        length = -EINVAL;
 625        if (*ppos != 0)
 626                goto out;
 627
 628        length = -ENOMEM;
 629        page = (char *)get_zeroed_page(GFP_KERNEL);
 630        if (!page)
 631                goto out;
 632
 633        length = -EFAULT;
 634        if (copy_from_user(page, buf, count))
 635                goto out;
 636
 637        length = -EINVAL;
 638        if (sscanf(page, "%u", &new_value) != 1)
 639                goto out;
 640
 641        selinux_checkreqprot = new_value ? 1 : 0;
 642        length = count;
 643out:
 644        free_page((unsigned long) page);
 645        return length;
 646}
 647static const struct file_operations sel_checkreqprot_ops = {
 648        .read           = sel_read_checkreqprot,
 649        .write          = sel_write_checkreqprot,
 650        .llseek         = generic_file_llseek,
 651};
 652
 653/*
 654 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
 655 */
 656static ssize_t sel_write_access(struct file *file, char *buf, size_t size);
 657static ssize_t sel_write_create(struct file *file, char *buf, size_t size);
 658static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size);
 659static ssize_t sel_write_user(struct file *file, char *buf, size_t size);
 660static ssize_t sel_write_member(struct file *file, char *buf, size_t size);
 661
 662static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 663        [SEL_ACCESS] = sel_write_access,
 664        [SEL_CREATE] = sel_write_create,
 665        [SEL_RELABEL] = sel_write_relabel,
 666        [SEL_USER] = sel_write_user,
 667        [SEL_MEMBER] = sel_write_member,
 668        [SEL_CONTEXT] = sel_write_context,
 669};
 670
 671static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
 672{
 673        ino_t ino = file->f_path.dentry->d_inode->i_ino;
 674        char *data;
 675        ssize_t rv;
 676
 677        if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
 678                return -EINVAL;
 679
 680        data = simple_transaction_get(file, buf, size);
 681        if (IS_ERR(data))
 682                return PTR_ERR(data);
 683
 684        rv = write_op[ino](file, data, size);
 685        if (rv > 0) {
 686                simple_transaction_set(file, rv);
 687                rv = size;
 688        }
 689        return rv;
 690}
 691
 692static const struct file_operations transaction_ops = {
 693        .write          = selinux_transaction_write,
 694        .read           = simple_transaction_read,
 695        .release        = simple_transaction_release,
 696        .llseek         = generic_file_llseek,
 697};
 698
 699/*
 700 * payload - write methods
 701 * If the method has a response, the response should be put in buf,
 702 * and the length returned.  Otherwise return 0 or and -error.
 703 */
 704
 705static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
 706{
 707        char *scon = NULL, *tcon = NULL;
 708        u32 ssid, tsid;
 709        u16 tclass;
 710        struct av_decision avd;
 711        ssize_t length;
 712
 713        length = task_has_security(current, SECURITY__COMPUTE_AV);
 714        if (length)
 715                goto out;
 716
 717        length = -ENOMEM;
 718        scon = kzalloc(size + 1, GFP_KERNEL);
 719        if (!scon)
 720                goto out;
 721
 722        length = -ENOMEM;
 723        tcon = kzalloc(size + 1, GFP_KERNEL);
 724        if (!tcon)
 725                goto out;
 726
 727        length = -EINVAL;
 728        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 729                goto out;
 730
 731        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 732        if (length)
 733                goto out;
 734
 735        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 736        if (length)
 737                goto out;
 738
 739        security_compute_av_user(ssid, tsid, tclass, &avd);
 740
 741        length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
 742                          "%x %x %x %x %u %x",
 743                          avd.allowed, 0xffffffff,
 744                          avd.auditallow, avd.auditdeny,
 745                          avd.seqno, avd.flags);
 746out:
 747        kfree(tcon);
 748        kfree(scon);
 749        return length;
 750}
 751
 752static inline int hexcode_to_int(int code) {
 753        if (code == '\0' || !isxdigit(code))
 754                return -1;
 755        if (isdigit(code))
 756                return code - '0';
 757        return tolower(code) - 'a' + 10;
 758}
 759
 760static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
 761{
 762        char *scon = NULL, *tcon = NULL;
 763        char *namebuf = NULL, *objname = NULL;
 764        u32 ssid, tsid, newsid;
 765        u16 tclass;
 766        ssize_t length;
 767        char *newcon = NULL;
 768        u32 len;
 769        int nargs;
 770
 771        length = task_has_security(current, SECURITY__COMPUTE_CREATE);
 772        if (length)
 773                goto out;
 774
 775        length = -ENOMEM;
 776        scon = kzalloc(size + 1, GFP_KERNEL);
 777        if (!scon)
 778                goto out;
 779
 780        length = -ENOMEM;
 781        tcon = kzalloc(size + 1, GFP_KERNEL);
 782        if (!tcon)
 783                goto out;
 784
 785        length = -ENOMEM;
 786        namebuf = kzalloc(size + 1, GFP_KERNEL);
 787        if (!namebuf)
 788                goto out;
 789
 790        length = -EINVAL;
 791        nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
 792        if (nargs < 3 || nargs > 4)
 793                goto out;
 794        if (nargs == 4) {
 795                /*
 796                 * If and when the name of new object to be queried contains
 797                 * either whitespace or multibyte characters, they shall be
 798                 * encoded based on the percentage-encoding rule.
 799                 * If not encoded, the sscanf logic picks up only left-half
 800                 * of the supplied name; splitted by a whitespace unexpectedly.
 801                 */
 802                char   *r, *w;
 803                int     c1, c2;
 804
 805                r = w = namebuf;
 806                do {
 807                        c1 = *r++;
 808                        if (c1 == '+')
 809                                c1 = ' ';
 810                        else if (c1 == '%') {
 811                                if ((c1 = hexcode_to_int(*r++)) < 0)
 812                                        goto out;
 813                                if ((c2 = hexcode_to_int(*r++)) < 0)
 814                                        goto out;
 815                                c1 = (c1 << 4) | c2;
 816                        }
 817                        *w++ = c1;
 818                } while (c1 != '\0');
 819
 820                objname = namebuf;
 821        }
 822
 823        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 824        if (length)
 825                goto out;
 826
 827        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 828        if (length)
 829                goto out;
 830
 831        length = security_transition_sid_user(ssid, tsid, tclass,
 832                                              objname, &newsid);
 833        if (length)
 834                goto out;
 835
 836        length = security_sid_to_context(newsid, &newcon, &len);
 837        if (length)
 838                goto out;
 839
 840        length = -ERANGE;
 841        if (len > SIMPLE_TRANSACTION_LIMIT) {
 842                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
 843                        "payload max\n", __func__, len);
 844                goto out;
 845        }
 846
 847        memcpy(buf, newcon, len);
 848        length = len;
 849out:
 850        kfree(newcon);
 851        kfree(namebuf);
 852        kfree(tcon);
 853        kfree(scon);
 854        return length;
 855}
 856
 857static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
 858{
 859        char *scon = NULL, *tcon = NULL;
 860        u32 ssid, tsid, newsid;
 861        u16 tclass;
 862        ssize_t length;
 863        char *newcon = NULL;
 864        u32 len;
 865
 866        length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
 867        if (length)
 868                goto out;
 869
 870        length = -ENOMEM;
 871        scon = kzalloc(size + 1, GFP_KERNEL);
 872        if (!scon)
 873                goto out;
 874
 875        length = -ENOMEM;
 876        tcon = kzalloc(size + 1, GFP_KERNEL);
 877        if (!tcon)
 878                goto out;
 879
 880        length = -EINVAL;
 881        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 882                goto out;
 883
 884        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
 885        if (length)
 886                goto out;
 887
 888        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
 889        if (length)
 890                goto out;
 891
 892        length = security_change_sid(ssid, tsid, tclass, &newsid);
 893        if (length)
 894                goto out;
 895
 896        length = security_sid_to_context(newsid, &newcon, &len);
 897        if (length)
 898                goto out;
 899
 900        length = -ERANGE;
 901        if (len > SIMPLE_TRANSACTION_LIMIT)
 902                goto out;
 903
 904        memcpy(buf, newcon, len);
 905        length = len;
 906out:
 907        kfree(newcon);
 908        kfree(tcon);
 909        kfree(scon);
 910        return length;
 911}
 912
 913static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
 914{
 915        char *con = NULL, *user = NULL, *ptr;
 916        u32 sid, *sids = NULL;
 917        ssize_t length;
 918        char *newcon;
 919        int i, rc;
 920        u32 len, nsids;
 921
 922        length = task_has_security(current, SECURITY__COMPUTE_USER);
 923        if (length)
 924                goto out;
 925
 926        length = -ENOMEM;
 927        con = kzalloc(size + 1, GFP_KERNEL);
 928        if (!con)
 929                goto out;
 930
 931        length = -ENOMEM;
 932        user = kzalloc(size + 1, GFP_KERNEL);
 933        if (!user)
 934                goto out;
 935
 936        length = -EINVAL;
 937        if (sscanf(buf, "%s %s", con, user) != 2)
 938                goto out;
 939
 940        length = security_context_to_sid(con, strlen(con) + 1, &sid);
 941        if (length)
 942                goto out;
 943
 944        length = security_get_user_sids(sid, user, &sids, &nsids);
 945        if (length)
 946                goto out;
 947
 948        length = sprintf(buf, "%u", nsids) + 1;
 949        ptr = buf + length;
 950        for (i = 0; i < nsids; i++) {
 951                rc = security_sid_to_context(sids[i], &newcon, &len);
 952                if (rc) {
 953                        length = rc;
 954                        goto out;
 955                }
 956                if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
 957                        kfree(newcon);
 958                        length = -ERANGE;
 959                        goto out;
 960                }
 961                memcpy(ptr, newcon, len);
 962                kfree(newcon);
 963                ptr += len;
 964                length += len;
 965        }
 966out:
 967        kfree(sids);
 968        kfree(user);
 969        kfree(con);
 970        return length;
 971}
 972
 973static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
 974{
 975        char *scon = NULL, *tcon = NULL;
 976        u32 ssid, tsid, newsid;
 977        u16 tclass;
 978        ssize_t length;
 979        char *newcon = NULL;
 980        u32 len;
 981
 982        length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
 983        if (length)
 984                goto out;
 985
 986        length = -ENOMEM;
 987        scon = kzalloc(size + 1, GFP_KERNEL);
 988        if (!scon)
 989                goto out;
 990
 991        length = -ENOMEM;
 992        tcon = kzalloc(size + 1, GFP_KERNEL);
 993        if (!tcon)
 994                goto out;
 995
 996        length = -EINVAL;
 997        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 998                goto out;
 999
1000        length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
1001        if (length)
1002                goto out;
1003
1004        length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
1005        if (length)
1006                goto out;
1007
1008        length = security_member_sid(ssid, tsid, tclass, &newsid);
1009        if (length)
1010                goto out;
1011
1012        length = security_sid_to_context(newsid, &newcon, &len);
1013        if (length)
1014                goto out;
1015
1016        length = -ERANGE;
1017        if (len > SIMPLE_TRANSACTION_LIMIT) {
1018                printk(KERN_ERR "SELinux: %s:  context size (%u) exceeds "
1019                        "payload max\n", __func__, len);
1020                goto out;
1021        }
1022
1023        memcpy(buf, newcon, len);
1024        length = len;
1025out:
1026        kfree(newcon);
1027        kfree(tcon);
1028        kfree(scon);
1029        return length;
1030}
1031
1032static struct inode *sel_make_inode(struct super_block *sb, int mode)
1033{
1034        struct inode *ret = new_inode(sb);
1035
1036        if (ret) {
1037                ret->i_mode = mode;
1038                ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
1039        }
1040        return ret;
1041}
1042
1043static ssize_t sel_read_bool(struct file *filep, char __user *buf,
1044                             size_t count, loff_t *ppos)
1045{
1046        char *page = NULL;
1047        ssize_t length;
1048        ssize_t ret;
1049        int cur_enforcing;
1050        struct inode *inode = filep->f_path.dentry->d_inode;
1051        unsigned index = inode->i_ino & SEL_INO_MASK;
1052        const char *name = filep->f_path.dentry->d_name.name;
1053
1054        mutex_lock(&sel_mutex);
1055
1056        ret = -EINVAL;
1057        if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1058                goto out;
1059
1060        ret = -ENOMEM;
1061        page = (char *)get_zeroed_page(GFP_KERNEL);
1062        if (!page)
1063                goto out;
1064
1065        cur_enforcing = security_get_bool_value(index);
1066        if (cur_enforcing < 0) {
1067                ret = cur_enforcing;
1068                goto out;
1069        }
1070        length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
1071                          bool_pending_values[index]);
1072        ret = simple_read_from_buffer(buf, count, ppos, page, length);
1073out:
1074        mutex_unlock(&sel_mutex);
1075        free_page((unsigned long)page);
1076        return ret;
1077}
1078
1079static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1080                              size_t count, loff_t *ppos)
1081{
1082        char *page = NULL;
1083        ssize_t length;
1084        int new_value;
1085        struct inode *inode = filep->f_path.dentry->d_inode;
1086        unsigned index = inode->i_ino & SEL_INO_MASK;
1087        const char *name = filep->f_path.dentry->d_name.name;
1088
1089        mutex_lock(&sel_mutex);
1090
1091        length = task_has_security(current, SECURITY__SETBOOL);
1092        if (length)
1093                goto out;
1094
1095        length = -EINVAL;
1096        if (index >= bool_num || strcmp(name, bool_pending_names[index]))
1097                goto out;
1098
1099        length = -ENOMEM;
1100        if (count >= PAGE_SIZE)
1101                goto out;
1102
1103        /* No partial writes. */
1104        length = -EINVAL;
1105        if (*ppos != 0)
1106                goto out;
1107
1108        length = -ENOMEM;
1109        page = (char *)get_zeroed_page(GFP_KERNEL);
1110        if (!page)
1111                goto out;
1112
1113        length = -EFAULT;
1114        if (copy_from_user(page, buf, count))
1115                goto out;
1116
1117        length = -EINVAL;
1118        if (sscanf(page, "%d", &new_value) != 1)
1119                goto out;
1120
1121        if (new_value)
1122                new_value = 1;
1123
1124        bool_pending_values[index] = new_value;
1125        length = count;
1126
1127out:
1128        mutex_unlock(&sel_mutex);
1129        free_page((unsigned long) page);
1130        return length;
1131}
1132
1133static const struct file_operations sel_bool_ops = {
1134        .read           = sel_read_bool,
1135        .write          = sel_write_bool,
1136        .llseek         = generic_file_llseek,
1137};
1138
1139static ssize_t sel_commit_bools_write(struct file *filep,
1140                                      const char __user *buf,
1141                                      size_t count, loff_t *ppos)
1142{
1143        char *page = NULL;
1144        ssize_t length;
1145        int new_value;
1146
1147        mutex_lock(&sel_mutex);
1148
1149        length = task_has_security(current, SECURITY__SETBOOL);
1150        if (length)
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        length = -ENOMEM;
1163        page = (char *)get_zeroed_page(GFP_KERNEL);
1164        if (!page)
1165                goto out;
1166
1167        length = -EFAULT;
1168        if (copy_from_user(page, buf, count))
1169                goto out;
1170
1171        length = -EINVAL;
1172        if (sscanf(page, "%d", &new_value) != 1)
1173                goto out;
1174
1175        length = 0;
1176        if (new_value && bool_pending_values)
1177                length = security_set_bools(bool_num, bool_pending_values);
1178
1179        if (!length)
1180                length = count;
1181
1182out:
1183        mutex_unlock(&sel_mutex);
1184        free_page((unsigned long) page);
1185        return length;
1186}
1187
1188static const struct file_operations sel_commit_bools_ops = {
1189        .write          = sel_commit_bools_write,
1190        .llseek         = generic_file_llseek,
1191};
1192
1193static void sel_remove_entries(struct dentry *de)
1194{
1195        struct list_head *node;
1196
1197        spin_lock(&de->d_lock);
1198        node = de->d_subdirs.next;
1199        while (node != &de->d_subdirs) {
1200                struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1201
1202                spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
1203                list_del_init(node);
1204
1205                if (d->d_inode) {
1206                        dget_dlock(d);
1207                        spin_unlock(&de->d_lock);
1208                        spin_unlock(&d->d_lock);
1209                        d_delete(d);
1210                        simple_unlink(de->d_inode, d);
1211                        dput(d);
1212                        spin_lock(&de->d_lock);
1213                } else
1214                        spin_unlock(&d->d_lock);
1215                node = de->d_subdirs.next;
1216        }
1217
1218        spin_unlock(&de->d_lock);
1219}
1220
1221#define BOOL_DIR_NAME "booleans"
1222
1223static int sel_make_bools(void)
1224{
1225        int i, ret;
1226        ssize_t len;
1227        struct dentry *dentry = NULL;
1228        struct dentry *dir = bool_dir;
1229        struct inode *inode = NULL;
1230        struct inode_security_struct *isec;
1231        char **names = NULL, *page;
1232        int num;
1233        int *values = NULL;
1234        u32 sid;
1235
1236        /* remove any existing files */
1237        for (i = 0; i < bool_num; i++)
1238                kfree(bool_pending_names[i]);
1239        kfree(bool_pending_names);
1240        kfree(bool_pending_values);
1241        bool_pending_names = NULL;
1242        bool_pending_values = NULL;
1243
1244        sel_remove_entries(dir);
1245
1246        ret = -ENOMEM;
1247        page = (char *)get_zeroed_page(GFP_KERNEL);
1248        if (!page)
1249                goto out;
1250
1251        ret = security_get_bools(&num, &names, &values);
1252        if (ret)
1253                goto out;
1254
1255        for (i = 0; i < num; i++) {
1256                ret = -ENOMEM;
1257                dentry = d_alloc_name(dir, names[i]);
1258                if (!dentry)
1259                        goto out;
1260
1261                ret = -ENOMEM;
1262                inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1263                if (!inode)
1264                        goto out;
1265
1266                ret = -EINVAL;
1267                len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1268                if (len < 0)
1269                        goto out;
1270
1271                ret = -ENAMETOOLONG;
1272                if (len >= PAGE_SIZE)
1273                        goto out;
1274
1275                isec = (struct inode_security_struct *)inode->i_security;
1276                ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1277                if (ret)
1278                        goto out;
1279
1280                isec->sid = sid;
1281                isec->initialized = 1;
1282                inode->i_fop = &sel_bool_ops;
1283                inode->i_ino = i|SEL_BOOL_INO_OFFSET;
1284                d_add(dentry, inode);
1285        }
1286        bool_num = num;
1287        bool_pending_names = names;
1288        bool_pending_values = values;
1289
1290        free_page((unsigned long)page);
1291        return 0;
1292out:
1293        free_page((unsigned long)page);
1294
1295        if (names) {
1296                for (i = 0; i < num; i++)
1297                        kfree(names[i]);
1298                kfree(names);
1299        }
1300        kfree(values);
1301        sel_remove_entries(dir);
1302
1303        return ret;
1304}
1305
1306#define NULL_FILE_NAME "null"
1307
1308struct dentry *selinux_null;
1309
1310static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf,
1311                                            size_t count, loff_t *ppos)
1312{
1313        char tmpbuf[TMPBUFLEN];
1314        ssize_t length;
1315
1316        length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold);
1317        return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
1318}
1319
1320static ssize_t sel_write_avc_cache_threshold(struct file *file,
1321                                             const char __user *buf,
1322                                             size_t count, loff_t *ppos)
1323
1324{
1325        char *page = NULL;
1326        ssize_t ret;
1327        int new_value;
1328
1329        ret = task_has_security(current, SECURITY__SETSECPARAM);
1330        if (ret)
1331                goto out;
1332
1333        ret = -ENOMEM;
1334        if (count >= PAGE_SIZE)
1335                goto out;
1336
1337        /* No partial writes. */
1338        ret = -EINVAL;
1339        if (*ppos != 0)
1340                goto out;
1341
1342        ret = -ENOMEM;
1343        page = (char *)get_zeroed_page(GFP_KERNEL);
1344        if (!page)
1345                goto out;
1346
1347        ret = -EFAULT;
1348        if (copy_from_user(page, buf, count))
1349                goto out;
1350
1351        ret = -EINVAL;
1352        if (sscanf(page, "%u", &new_value) != 1)
1353                goto out;
1354
1355        avc_cache_threshold = new_value;
1356
1357        ret = count;
1358out:
1359        free_page((unsigned long)page);
1360        return ret;
1361}
1362
1363static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1364                                       size_t count, loff_t *ppos)
1365{
1366        char *page;
1367        ssize_t length;
1368
1369        page = (char *)__get_free_page(GFP_KERNEL);
1370        if (!page)
1371                return -ENOMEM;
1372
1373        length = avc_get_hash_stats(page);
1374        if (length >= 0)
1375                length = simple_read_from_buffer(buf, count, ppos, page, length);
1376        free_page((unsigned long)page);
1377
1378        return length;
1379}
1380
1381static const struct file_operations sel_avc_cache_threshold_ops = {
1382        .read           = sel_read_avc_cache_threshold,
1383        .write          = sel_write_avc_cache_threshold,
1384        .llseek         = generic_file_llseek,
1385};
1386
1387static const struct file_operations sel_avc_hash_stats_ops = {
1388        .read           = sel_read_avc_hash_stats,
1389        .llseek         = generic_file_llseek,
1390};
1391
1392#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1393static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx)
1394{
1395        int cpu;
1396
1397        for (cpu = *idx; cpu < nr_cpu_ids; ++cpu) {
1398                if (!cpu_possible(cpu))
1399                        continue;
1400                *idx = cpu + 1;
1401                return &per_cpu(avc_cache_stats, cpu);
1402        }
1403        return NULL;
1404}
1405
1406static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos)
1407{
1408        loff_t n = *pos - 1;
1409
1410        if (*pos == 0)
1411                return SEQ_START_TOKEN;
1412
1413        return sel_avc_get_stat_idx(&n);
1414}
1415
1416static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1417{
1418        return sel_avc_get_stat_idx(pos);
1419}
1420
1421static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1422{
1423        struct avc_cache_stats *st = v;
1424
1425        if (v == SEQ_START_TOKEN)
1426                seq_printf(seq, "lookups hits misses allocations reclaims "
1427                           "frees\n");
1428        else {
1429                unsigned int lookups = st->lookups;
1430                unsigned int misses = st->misses;
1431                unsigned int hits = lookups - misses;
1432                seq_printf(seq, "%u %u %u %u %u %u\n", lookups,
1433                           hits, misses, st->allocations,
1434                           st->reclaims, st->frees);
1435        }
1436        return 0;
1437}
1438
1439static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v)
1440{ }
1441
1442static const struct seq_operations sel_avc_cache_stats_seq_ops = {
1443        .start          = sel_avc_stats_seq_start,
1444        .next           = sel_avc_stats_seq_next,
1445        .show           = sel_avc_stats_seq_show,
1446        .stop           = sel_avc_stats_seq_stop,
1447};
1448
1449static int sel_open_avc_cache_stats(struct inode *inode, struct file *file)
1450{
1451        return seq_open(file, &sel_avc_cache_stats_seq_ops);
1452}
1453
1454static const struct file_operations sel_avc_cache_stats_ops = {
1455        .open           = sel_open_avc_cache_stats,
1456        .read           = seq_read,
1457        .llseek         = seq_lseek,
1458        .release        = seq_release,
1459};
1460#endif
1461
1462static int sel_make_avc_files(struct dentry *dir)
1463{
1464        int i;
1465        static struct tree_descr files[] = {
1466                { "cache_threshold",
1467                  &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
1468                { "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
1469#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
1470                { "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO },
1471#endif
1472        };
1473
1474        for (i = 0; i < ARRAY_SIZE(files); i++) {
1475                struct inode *inode;
1476                struct dentry *dentry;
1477
1478                dentry = d_alloc_name(dir, files[i].name);
1479                if (!dentry)
1480                        return -ENOMEM;
1481
1482                inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1483                if (!inode)
1484                        return -ENOMEM;
1485
1486                inode->i_fop = files[i].ops;
1487                inode->i_ino = ++sel_last_ino;
1488                d_add(dentry, inode);
1489        }
1490
1491        return 0;
1492}
1493
1494static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1495                                size_t count, loff_t *ppos)
1496{
1497        struct inode *inode;
1498        char *con;
1499        u32 sid, len;
1500        ssize_t ret;
1501
1502        inode = file->f_path.dentry->d_inode;
1503        sid = inode->i_ino&SEL_INO_MASK;
1504        ret = security_sid_to_context(sid, &con, &len);
1505        if (ret)
1506                return ret;
1507
1508        ret = simple_read_from_buffer(buf, count, ppos, con, len);
1509        kfree(con);
1510        return ret;
1511}
1512
1513static const struct file_operations sel_initcon_ops = {
1514        .read           = sel_read_initcon,
1515        .llseek         = generic_file_llseek,
1516};
1517
1518static int sel_make_initcon_files(struct dentry *dir)
1519{
1520        int i;
1521
1522        for (i = 1; i <= SECINITSID_NUM; i++) {
1523                struct inode *inode;
1524                struct dentry *dentry;
1525                dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1526                if (!dentry)
1527                        return -ENOMEM;
1528
1529                inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1530                if (!inode)
1531                        return -ENOMEM;
1532
1533                inode->i_fop = &sel_initcon_ops;
1534                inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1535                d_add(dentry, inode);
1536        }
1537
1538        return 0;
1539}
1540
1541static inline unsigned int sel_div(unsigned long a, unsigned long b)
1542{
1543        return a / b - (a % b < 0);
1544}
1545
1546static inline unsigned long sel_class_to_ino(u16 class)
1547{
1548        return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
1549}
1550
1551static inline u16 sel_ino_to_class(unsigned long ino)
1552{
1553        return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
1554}
1555
1556static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
1557{
1558        return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
1559}
1560
1561static inline u32 sel_ino_to_perm(unsigned long ino)
1562{
1563        return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
1564}
1565
1566static ssize_t sel_read_class(struct file *file, char __user *buf,
1567                                size_t count, loff_t *ppos)
1568{
1569        ssize_t rc, len;
1570        char *page;
1571        unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1572
1573        page = (char *)__get_free_page(GFP_KERNEL);
1574        if (!page)
1575                return -ENOMEM;
1576
1577        len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1578        rc = simple_read_from_buffer(buf, count, ppos, page, len);
1579        free_page((unsigned long)page);
1580
1581        return rc;
1582}
1583
1584static const struct file_operations sel_class_ops = {
1585        .read           = sel_read_class,
1586        .llseek         = generic_file_llseek,
1587};
1588
1589static ssize_t sel_read_perm(struct file *file, char __user *buf,
1590                                size_t count, loff_t *ppos)
1591{
1592        ssize_t rc, len;
1593        char *page;
1594        unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1595
1596        page = (char *)__get_free_page(GFP_KERNEL);
1597        if (!page)
1598                return -ENOMEM;
1599
1600        len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1601        rc = simple_read_from_buffer(buf, count, ppos, page, len);
1602        free_page((unsigned long)page);
1603
1604        return rc;
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->f_path.dentry->d_inode->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 = d_alloc_name(dir, "perms");
1688        if (!dentry)
1689                return -ENOMEM;
1690
1691        rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1692        if (rc)
1693                return rc;
1694
1695        rc = sel_make_perm_files(classname, index, dentry);
1696
1697        return rc;
1698}
1699
1700static void sel_remove_classes(void)
1701{
1702        struct list_head *class_node;
1703
1704        list_for_each(class_node, &class_dir->d_subdirs) {
1705                struct dentry *class_subdir = list_entry(class_node,
1706                                        struct dentry, d_u.d_child);
1707                struct list_head *class_subdir_node;
1708
1709                list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
1710                        struct dentry *d = list_entry(class_subdir_node,
1711                                                struct dentry, d_u.d_child);
1712
1713                        if (d->d_inode)
1714                                if (d->d_inode->i_mode & S_IFDIR)
1715                                        sel_remove_entries(d);
1716                }
1717
1718                sel_remove_entries(class_subdir);
1719        }
1720
1721        sel_remove_entries(class_dir);
1722}
1723
1724static int sel_make_classes(void)
1725{
1726        int rc, nclasses, i;
1727        char **classes;
1728
1729        /* delete any existing entries */
1730        sel_remove_classes();
1731
1732        rc = security_get_classes(&classes, &nclasses);
1733        if (rc)
1734                return rc;
1735
1736        /* +2 since classes are 1-indexed */
1737        last_class_ino = sel_class_to_ino(nclasses + 2);
1738
1739        for (i = 0; i < nclasses; i++) {
1740                struct dentry *class_name_dir;
1741
1742                rc = -ENOMEM;
1743                class_name_dir = d_alloc_name(class_dir, classes[i]);
1744                if (!class_name_dir)
1745                        goto out;
1746
1747                rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1748                                &last_class_ino);
1749                if (rc)
1750                        goto out;
1751
1752                /* i+1 since class values are 1-indexed */
1753                rc = sel_make_class_dir_entries(classes[i], i + 1,
1754                                class_name_dir);
1755                if (rc)
1756                        goto out;
1757        }
1758        rc = 0;
1759out:
1760        for (i = 0; i < nclasses; i++)
1761                kfree(classes[i]);
1762        kfree(classes);
1763        return rc;
1764}
1765
1766static int sel_make_policycap(void)
1767{
1768        unsigned int iter;
1769        struct dentry *dentry = NULL;
1770        struct inode *inode = NULL;
1771
1772        sel_remove_entries(policycap_dir);
1773
1774        for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
1775                if (iter < ARRAY_SIZE(policycap_names))
1776                        dentry = d_alloc_name(policycap_dir,
1777                                              policycap_names[iter]);
1778                else
1779                        dentry = d_alloc_name(policycap_dir, "unknown");
1780
1781                if (dentry == NULL)
1782                        return -ENOMEM;
1783
1784                inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
1785                if (inode == NULL)
1786                        return -ENOMEM;
1787
1788                inode->i_fop = &sel_policycap_ops;
1789                inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
1790                d_add(dentry, inode);
1791        }
1792
1793        return 0;
1794}
1795
1796static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1797                        unsigned long *ino)
1798{
1799        struct inode *inode;
1800
1801        inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1802        if (!inode)
1803                return -ENOMEM;
1804
1805        inode->i_op = &simple_dir_inode_operations;
1806        inode->i_fop = &simple_dir_operations;
1807        inode->i_ino = ++(*ino);
1808        /* directory inodes start off with i_nlink == 2 (for "." entry) */
1809        inc_nlink(inode);
1810        d_add(dentry, inode);
1811        /* bump link count on parent directory, too */
1812        inc_nlink(dir);
1813
1814        return 0;
1815}
1816
1817static int sel_fill_super(struct super_block *sb, void *data, int silent)
1818{
1819        int ret;
1820        struct dentry *dentry;
1821        struct inode *inode, *root_inode;
1822        struct inode_security_struct *isec;
1823
1824        static struct tree_descr selinux_files[] = {
1825                [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
1826                [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
1827                [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
1828                [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
1829                [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
1830                [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
1831                [SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO},
1832                [SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO},
1833                [SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR},
1834                [SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO},
1835                [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1836                [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1837                [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1838                [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1839                [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1840                [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
1841                [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
1842                /* last one */ {""}
1843        };
1844        ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
1845        if (ret)
1846                goto err;
1847
1848        root_inode = sb->s_root->d_inode;
1849
1850        ret = -ENOMEM;
1851        dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1852        if (!dentry)
1853                goto err;
1854
1855        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1856        if (ret)
1857                goto err;
1858
1859        bool_dir = dentry;
1860
1861        ret = -ENOMEM;
1862        dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1863        if (!dentry)
1864                goto err;
1865
1866        ret = -ENOMEM;
1867        inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1868        if (!inode)
1869                goto err;
1870
1871        inode->i_ino = ++sel_last_ino;
1872        isec = (struct inode_security_struct *)inode->i_security;
1873        isec->sid = SECINITSID_DEVNULL;
1874        isec->sclass = SECCLASS_CHR_FILE;
1875        isec->initialized = 1;
1876
1877        init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3));
1878        d_add(dentry, inode);
1879        selinux_null = dentry;
1880
1881        ret = -ENOMEM;
1882        dentry = d_alloc_name(sb->s_root, "avc");
1883        if (!dentry)
1884                goto err;
1885
1886        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1887        if (ret)
1888                goto err;
1889
1890        ret = sel_make_avc_files(dentry);
1891        if (ret)
1892                goto err;
1893
1894        ret = -ENOMEM;
1895        dentry = d_alloc_name(sb->s_root, "initial_contexts");
1896        if (!dentry)
1897                goto err;
1898
1899        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1900        if (ret)
1901                goto err;
1902
1903        ret = sel_make_initcon_files(dentry);
1904        if (ret)
1905                goto err;
1906
1907        ret = -ENOMEM;
1908        dentry = d_alloc_name(sb->s_root, "class");
1909        if (!dentry)
1910                goto err;
1911
1912        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1913        if (ret)
1914                goto err;
1915
1916        class_dir = dentry;
1917
1918        ret = -ENOMEM;
1919        dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1920        if (!dentry)
1921                goto err;
1922
1923        ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1924        if (ret)
1925                goto err;
1926
1927        policycap_dir = dentry;
1928
1929        return 0;
1930err:
1931        printk(KERN_ERR "SELinux: %s:  failed while creating inodes\n",
1932                __func__);
1933        return ret;
1934}
1935
1936static struct dentry *sel_mount(struct file_system_type *fs_type,
1937                      int flags, const char *dev_name, void *data)
1938{
1939        return mount_single(fs_type, flags, data, sel_fill_super);
1940}
1941
1942static struct file_system_type sel_fs_type = {
1943        .name           = "selinuxfs",
1944        .mount          = sel_mount,
1945        .kill_sb        = kill_litter_super,
1946};
1947
1948struct vfsmount *selinuxfs_mount;
1949static struct kobject *selinuxfs_kobj;
1950
1951static int __init init_sel_fs(void)
1952{
1953        int err;
1954
1955        if (!selinux_enabled)
1956                return 0;
1957
1958        selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
1959        if (!selinuxfs_kobj)
1960                return -ENOMEM;
1961
1962        err = register_filesystem(&sel_fs_type);
1963        if (err) {
1964                kobject_put(selinuxfs_kobj);
1965                return err;
1966        }
1967
1968        selinuxfs_mount = kern_mount(&sel_fs_type);
1969        if (IS_ERR(selinuxfs_mount)) {
1970                printk(KERN_ERR "selinuxfs:  could not mount!\n");
1971                err = PTR_ERR(selinuxfs_mount);
1972                selinuxfs_mount = NULL;
1973        }
1974
1975        return err;
1976}
1977
1978__initcall(init_sel_fs);
1979
1980#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1981void exit_sel_fs(void)
1982{
1983        kobject_put(selinuxfs_kobj);
1984        kern_unmount(selinuxfs_mount);
1985        unregister_filesystem(&sel_fs_type);
1986}
1987#endif
1988
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.