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