/*
 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
 *
 *	This program is free software; you can redistribute it and/or modify
 *  	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, version 2.
 *
 * Authors:
 * 	Casey Schaufler <casey@schaufler-ca.com>
 * 	Ahmed S. Darwish <darwish.07@gmail.com>
 *
 * Special thanks to the authors of selinuxfs.
 *
 *	Karl MacMillan <kmacmillan@tresys.com>
 *	James Morris <jmorris@redhat.com>
 *
 */

#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/security.h>
#include <linux/mutex.h>
#include <net/netlabel.h>
#include <net/cipso_ipv4.h>
#include <linux/seq_file.h>
#include <linux/ctype.h>
#include "smack.h"

/*
 * smackfs pseudo filesystem.
 */

enum smk_inos {
	SMK_ROOT_INO	= 2,
	SMK_LOAD	= 3,	/* load policy */
	SMK_CIPSO	= 4,	/* load label -> CIPSO mapping */
	SMK_DOI		= 5,	/* CIPSO DOI */
	SMK_DIRECT	= 6,	/* CIPSO level indicating direct label */
	SMK_AMBIENT	= 7,	/* internet ambient label */
	SMK_NLTYPE	= 8,	/* label scheme to use by default */
};

/*
 * List locks
 */
static DEFINE_MUTEX(smack_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);

/*
 * This is the "ambient" label for network traffic.
 * If it isn't somehow marked, use this.
 * It can be reset via smackfs/ambient
 */
char *smack_net_ambient = smack_known_floor.smk_known;

/*
 * This is the default packet marking scheme for network traffic.
 * It can be reset via smackfs/nltype
 */
int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4;

/*
 * This is the level in a CIPSO header that indicates a
 * smack label is contained directly in the category set.
 * It can be reset via smackfs/direct
 */
int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT;

static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
struct smk_list_entry *smack_list;

#define	SEQ_READ_FINISHED	1

/*
 * Disable concurrent writing open() operations
 */
static struct semaphore smack_write_sem;

/*
 * Values for parsing cipso rules
 * SMK_DIGITLEN: Length of a digit field in a rule.
 * SMK_CIPSOMEN: Minimum possible cipso rule length.
 */
#define SMK_DIGITLEN 4
#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN)

/*
 * Seq_file read operations for /smack/load
 */

static void *load_seq_start(struct seq_file *s, loff_t *pos)
{
	if (*pos == SEQ_READ_FINISHED)
		return NULL;

	return smack_list;
}

static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
	struct smk_list_entry *skp = ((struct smk_list_entry *) v)->smk_next;

	if (skp == NULL)
		*pos = SEQ_READ_FINISHED;

	return skp;
}

static int load_seq_show(struct seq_file *s, void *v)
{
	struct smk_list_entry *slp = (struct smk_list_entry *) v;
	struct smack_rule *srp = &slp->smk_rule;

	seq_printf(s, "%s %s", (char *)srp->smk_subject,
		   (char *)srp->smk_object);

	seq_putc(s, ' ');

	if (srp->smk_access & MAY_READ)
		seq_putc(s, 'r');
	if (srp->smk_access & MAY_WRITE)
		seq_putc(s, 'w');
	if (srp->smk_access & MAY_EXEC)
		seq_putc(s, 'x');
	if (srp->smk_access & MAY_APPEND)
		seq_putc(s, 'a');
	if (srp->smk_access == 0)
		seq_putc(s, '-');

	seq_putc(s, '\n');

	return 0;
}

static void load_seq_stop(struct seq_file *s, void *v)
{
	/* No-op */
}

static struct seq_operations load_seq_ops = {
	.start = load_seq_start,
	.next  = load_seq_next,
	.show  = load_seq_show,
	.stop  = load_seq_stop,
};

/**
 * smk_open_load - open() for /smack/load
 * @inode: inode structure representing file
 * @file: "load" file pointer
 *
 * For reading, use load_seq_* seq_file reading operations.
 */
static int smk_open_load(struct inode *inode, struct file *file)
{
	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
		return seq_open(file, &load_seq_ops);

	if (down_interruptible(&smack_write_sem))
		return -ERESTARTSYS;

	return 0;
}

/**
 * smk_release_load - release() for /smack/load
 * @inode: inode structure representing file
 * @file: "load" file pointer
 *
 * For a reading session, use the seq_file release
 * implementation.
 * Otherwise, we are at the end of a writing session so
 * clean everything up.
 */
static int smk_release_load(struct inode *inode, struct file *file)
{
	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
		return seq_release(inode, file);

	up(&smack_write_sem);
	return 0;
}

/**
 * smk_set_access - add a rule to the rule list
 * @srp: the new rule to add
 *
 * Looks through the current subject/object/access list for
 * the subject/object pair and replaces the access that was
 * there. If the pair isn't found add it with the specified
 * access.
 */
static void smk_set_access(struct smack_rule *srp)
{
	struct smk_list_entry *sp;
	struct smk_list_entry *newp;

	mutex_lock(&smack_list_lock);

	for (sp = smack_list; sp != NULL; sp = sp->smk_next)
		if (sp->smk_rule.smk_subject == srp->smk_subject &&
		    sp->smk_rule.smk_object == srp->smk_object) {
			sp->smk_rule.smk_access = srp->smk_access;
			break;
		}

	if (sp == NULL) {
		newp = kzalloc(sizeof(struct smk_list_entry), GFP_KERNEL);
		newp->smk_rule = *srp;
		newp->smk_next = smack_list;
		smack_list = newp;
	}

	mutex_unlock(&smack_list_lock);

	return;
}

/**
 * smk_write_load - write() for /smack/load
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start - must be 0
 *
 * Get one smack access rule from above.
 * The format is exactly:
 *     char subject[SMK_LABELLEN]
 *     char object[SMK_LABELLEN]
 *     char access[SMK_ACCESSKINDS]
 *
 *     Anything following is commentary and ignored.
 *
 * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes.
 */
#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS)

static ssize_t smk_write_load(struct file *file, const char __user *buf,
			      size_t count, loff_t *ppos)
{
	struct smack_rule rule;
	char *data;
	int rc = -EINVAL;

	/*
	 * Must have privilege.
	 * No partial writes.
	 * Enough data must be present.
	 */
	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;
	if (*ppos != 0)
		return -EINVAL;
	if (count < MINIMUM_LOAD)
		return -EINVAL;

	data = kzalloc(count, GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	if (copy_from_user(data, buf, count) != 0) {
		rc = -EFAULT;
		goto out;
	}

	rule.smk_subject = smk_import(data, 0);
	if (rule.smk_subject == NULL)
		goto out;

	rule.smk_object = smk_import(data + SMK_LABELLEN, 0);
	if (rule.smk_object == NULL)
		goto out;

	rule.smk_access = 0;

	switch (data[SMK_LABELLEN + SMK_LABELLEN]) {
	case '-':
		break;
	case 'r':
	case 'R':
		rule.smk_access |= MAY_READ;
		break;
	default:
		goto out;
	}

	switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) {
	case '-':
		break;
	case 'w':
	case 'W':
		rule.smk_access |= MAY_WRITE;
		break;
	default:
		goto out;
	}

	switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) {
	case '-':
		break;
	case 'x':
	case 'X':
		rule.smk_access |= MAY_EXEC;
		break;
	default:
		goto out;
	}

	switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) {
	case '-':
		break;
	case 'a':
	case 'A':
		rule.smk_access |= MAY_READ;
		break;
	default:
		goto out;
	}

	smk_set_access(&rule);
	rc = count;

out:
	kfree(data);
	return rc;
}

static const struct file_operations smk_load_ops = {
	.open           = smk_open_load,
	.read		= seq_read,
	.llseek         = seq_lseek,
	.write		= smk_write_load,
	.release        = smk_release_load,
};

/**
 * smk_cipso_doi - initialize the CIPSO domain
 */
void smk_cipso_doi(void)
{
	int rc;
	struct cipso_v4_doi *doip;
	struct netlbl_audit audit_info;

	rc = netlbl_cfg_map_del(NULL, &audit_info);
	if (rc != 0)
		printk(KERN_WARNING "%s:%d remove rc = %d\n",
		       __func__, __LINE__, rc);

	doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
	if (doip == NULL)
		panic("smack:  Failed to initialize cipso DOI.\n");
	doip->map.std = NULL;
	doip->doi = smk_cipso_doi_value;
	doip->type = CIPSO_V4_MAP_PASS;
	doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
	for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
		doip->tags[rc] = CIPSO_V4_TAG_INVALID;

	rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info);
	if (rc != 0)
		printk(KERN_WARNING "%s:%d add rc = %d\n",
		       __func__, __LINE__, rc);
}

/*
 * Seq_file read operations for /smack/cipso
 */

static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
{
	if (*pos == SEQ_READ_FINISHED)
		return NULL;

	return smack_known;
}

static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
	struct smack_known *skp = ((struct smack_known *) v)->smk_next;

	/*
	 * Omit labels with no associated cipso value
	 */
	while (skp != NULL && !skp->smk_cipso)
		skp = skp->smk_next;

	if (skp == NULL)
		*pos = SEQ_READ_FINISHED;

	return skp;
}

/*
 * Print cipso labels in format:
 * label level[/cat[,cat]]
 */
static int cipso_seq_show(struct seq_file *s, void *v)
{
	struct smack_known *skp = (struct smack_known *) v;
	struct smack_cipso *scp = skp->smk_cipso;
	char *cbp;
	char sep = '/';
	int cat = 1;
	int i;
	unsigned char m;

	if (scp == NULL)
		return 0;

	seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level);

	cbp = scp->smk_catset;
	for (i = 0; i < SMK_LABELLEN; i++)
		for (m = 0x80; m != 0; m >>= 1) {
			if (m & cbp[i]) {
				seq_printf(s, "%c%d", sep, cat);
				sep = ',';
			}
			cat++;
		}

	seq_putc(s, '\n');

	return 0;
}

static void cipso_seq_stop(struct seq_file *s, void *v)
{
	/* No-op */
}

static struct seq_operations cipso_seq_ops = {
	.start = cipso_seq_start,
	.stop  = cipso_seq_stop,
	.next  = cipso_seq_next,
	.show  = cipso_seq_show,
};

/**
 * smk_open_cipso - open() for /smack/cipso
 * @inode: inode structure representing file
 * @file: "cipso" file pointer
 *
 * Connect our cipso_seq_* operations with /smack/cipso
 * file_operations
 */
static int smk_open_cipso(struct inode *inode, struct file *file)
{
	return seq_open(file, &cipso_seq_ops);
}

/**
 * smk_write_cipso - write() for /smack/cipso
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Accepts only one cipso rule per write call.
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
			       size_t count, loff_t *ppos)
{
	struct smack_known *skp;
	struct smack_cipso *scp = NULL;
	char mapcatset[SMK_LABELLEN];
	int maplevel;
	int cat;
	int catlen;
	ssize_t rc = -EINVAL;
	char *data = NULL;
	char *rule;
	int ret;
	int i;

	/*
	 * Must have privilege.
	 * No partial writes.
	 * Enough data must be present.
	 */
	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;
	if (*ppos != 0)
		return -EINVAL;
	if (count <= SMK_CIPSOMIN)
		return -EINVAL;

	data = kzalloc(count + 1, GFP_KERNEL);
	if (data == NULL)
		return -ENOMEM;

	if (copy_from_user(data, buf, count) != 0) {
		rc = -EFAULT;
		goto unlockedout;
	}

	data[count] = '\0';
	rule = data;
	/*
	 * Only allow one writer at a time. Writes should be
	 * quite rare and small in any case.
	 */
	mutex_lock(&smack_cipso_lock);

	skp = smk_import_entry(rule, 0);
	if (skp == NULL)
		goto out;

	rule += SMK_LABELLEN;;
	ret = sscanf(rule, "%d", &maplevel);
	if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL)
		goto out;

	rule += SMK_DIGITLEN;
	ret = sscanf(rule, "%d", &catlen);
	if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
		goto out;

	if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
		goto out;

	memset(mapcatset, 0, sizeof(mapcatset));

	for (i = 0; i < catlen; i++) {
		rule += SMK_DIGITLEN;
		ret = sscanf(rule, "%d", &cat);
		if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL)
			goto out;

		smack_catset_bit(cat, mapcatset);
	}

	if (skp->smk_cipso == NULL) {
		scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL);
		if (scp == NULL) {
			rc = -ENOMEM;
			goto out;
		}
	}

	spin_lock_bh(&skp->smk_cipsolock);

	if (scp == NULL)
		scp = skp->smk_cipso;
	else
		skp->smk_cipso = scp;

	scp->smk_level = maplevel;
	memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset));

	spin_unlock_bh(&skp->smk_cipsolock);

	rc = count;
out:
	mutex_unlock(&smack_cipso_lock);
unlockedout:
	kfree(data);
	return rc;
}

static const struct file_operations smk_cipso_ops = {
	.open           = smk_open_cipso,
	.read		= seq_read,
	.llseek         = seq_lseek,
	.write		= smk_write_cipso,
	.release        = seq_release,
};

/**
 * smk_read_doi - read() for /smack/doi
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @count: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t smk_read_doi(struct file *filp, char __user *buf,
			    size_t count, loff_t *ppos)
{
	char temp[80];
	ssize_t rc;

	if (*ppos != 0)
		return 0;

	sprintf(temp, "%d", smk_cipso_doi_value);
	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));

	return rc;
}

/**
 * smk_write_doi - write() for /smack/doi
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t smk_write_doi(struct file *file, const char __user *buf,
			     size_t count, loff_t *ppos)
{
	char temp[80];
	int i;

	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;

	if (count >= sizeof(temp) || count == 0)
		return -EINVAL;

	if (copy_from_user(temp, buf, count) != 0)
		return -EFAULT;

	temp[count] = '\0';

	if (sscanf(temp, "%d", &i) != 1)
		return -EINVAL;

	smk_cipso_doi_value = i;

	smk_cipso_doi();

	return count;
}

static const struct file_operations smk_doi_ops = {
	.read		= smk_read_doi,
	.write		= smk_write_doi,
};

/**
 * smk_read_direct - read() for /smack/direct
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @count: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t smk_read_direct(struct file *filp, char __user *buf,
			       size_t count, loff_t *ppos)
{
	char temp[80];
	ssize_t rc;

	if (*ppos != 0)
		return 0;

	sprintf(temp, "%d", smack_cipso_direct);
	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));

	return rc;
}

/**
 * smk_write_direct - write() for /smack/direct
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t smk_write_direct(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	char temp[80];
	int i;

	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;

	if (count >= sizeof(temp) || count == 0)
		return -EINVAL;

	if (copy_from_user(temp, buf, count) != 0)
		return -EFAULT;

	temp[count] = '\0';

	if (sscanf(temp, "%d", &i) != 1)
		return -EINVAL;

	smack_cipso_direct = i;

	return count;
}

static const struct file_operations smk_direct_ops = {
	.read		= smk_read_direct,
	.write		= smk_write_direct,
};

/**
 * smk_read_ambient - read() for /smack/ambient
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @cn: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t smk_read_ambient(struct file *filp, char __user *buf,
				size_t cn, loff_t *ppos)
{
	ssize_t rc;
	char out[SMK_LABELLEN];
	int asize;

	if (*ppos != 0)
		return 0;
	/*
	 * Being careful to avoid a problem in the case where
	 * smack_net_ambient gets changed in midstream.
	 * Since smack_net_ambient is always set with a value
	 * from the label list, including initially, and those
	 * never get freed, the worst case is that the pointer
	 * gets changed just after this strncpy, in which case
	 * the value passed up is incorrect. Locking around
	 * smack_net_ambient wouldn't be any better than this
	 * copy scheme as by the time the caller got to look
	 * at the ambient value it would have cleared the lock
	 * and been changed.
	 */
	strncpy(out, smack_net_ambient, SMK_LABELLEN);
	asize = strlen(out) + 1;

	if (cn < asize)
		return -EINVAL;

	rc = simple_read_from_buffer(buf, cn, ppos, out, asize);

	return rc;
}

/**
 * smk_write_ambient - write() for /smack/ambient
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
				 size_t count, loff_t *ppos)
{
	char in[SMK_LABELLEN];
	char *smack;

	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;

	if (count >= SMK_LABELLEN)
		return -EINVAL;

	if (copy_from_user(in, buf, count) != 0)
		return -EFAULT;

	smack = smk_import(in, count);
	if (smack == NULL)
		return -EINVAL;

	smack_net_ambient = smack;

	return count;
}

static const struct file_operations smk_ambient_ops = {
	.read		= smk_read_ambient,
	.write		= smk_write_ambient,
};

struct option_names {
	int	o_number;
	char	*o_name;
	char	*o_alias;
};

static struct option_names netlbl_choices[] = {
	{ NETLBL_NLTYPE_RIPSO,
		NETLBL_NLTYPE_RIPSO_NAME,	"ripso" },
	{ NETLBL_NLTYPE_CIPSOV4,
		NETLBL_NLTYPE_CIPSOV4_NAME,	"cipsov4" },
	{ NETLBL_NLTYPE_CIPSOV4,
		NETLBL_NLTYPE_CIPSOV4_NAME,	"cipso" },
	{ NETLBL_NLTYPE_CIPSOV6,
		NETLBL_NLTYPE_CIPSOV6_NAME,	"cipsov6" },
	{ NETLBL_NLTYPE_UNLABELED,
		NETLBL_NLTYPE_UNLABELED_NAME,	"unlabeled" },
};

/**
 * smk_read_nltype - read() for /smack/nltype
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @count: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t smk_read_nltype(struct file *filp, char __user *buf,
			       size_t count, loff_t *ppos)
{
	char bound[40];
	ssize_t rc;
	int i;

	if (count < SMK_LABELLEN)
		return -EINVAL;

	if (*ppos != 0)
		return 0;

	sprintf(bound, "unknown");

	for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
		if (smack_net_nltype == netlbl_choices[i].o_number) {
			sprintf(bound, "%s", netlbl_choices[i].o_name);
			break;
		}

	rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound));

	return rc;
}

/**
 * smk_write_nltype - write() for /smack/nltype
 * @filp: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t smk_write_nltype(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	char bound[40];
	char *cp;
	int i;

	if (!capable(CAP_MAC_ADMIN))
		return -EPERM;

	if (count >= 40)
		return -EINVAL;

	if (copy_from_user(bound, buf, count) != 0)
		return -EFAULT;

	bound[count] = '\0';
	cp = strchr(bound, ' ');
	if (cp != NULL)
		*cp = '\0';
	cp = strchr(bound, '\n');
	if (cp != NULL)
		*cp = '\0';

	for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++)
		if (strcmp(bound, netlbl_choices[i].o_name) == 0 ||
		    strcmp(bound, netlbl_choices[i].o_alias) == 0) {
			smack_net_nltype = netlbl_choices[i].o_number;
			return count;
		}
	/*
	 * Not a valid choice.
	 */
	return -EINVAL;
}

static const struct file_operations smk_nltype_ops = {
	.read		= smk_read_nltype,
	.write		= smk_write_nltype,
};

/**
 * smk_fill_super - fill the /smackfs superblock
 * @sb: the empty superblock
 * @data: unused
 * @silent: unused
 *
 * Fill in the well known entries for /smack
 *
 * Returns 0 on success, an error code on failure
 */
static int smk_fill_super(struct super_block *sb, void *data, int silent)
{
	int rc;
	struct inode *root_inode;

	static struct tree_descr smack_files[] = {
		[SMK_LOAD]	=
			{"load", &smk_load_ops, S_IRUGO|S_IWUSR},
		[SMK_CIPSO]	=
			{"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR},
		[SMK_DOI]	=
			{"doi", &smk_doi_ops, S_IRUGO|S_IWUSR},
		[SMK_DIRECT]	=
			{"direct", &smk_direct_ops, S_IRUGO|S_IWUSR},
		[SMK_AMBIENT]	=
			{"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR},
		[SMK_NLTYPE]	=
			{"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR},
		/* last one */ {""}
	};

	rc = simple_fill_super(sb, SMACK_MAGIC, smack_files);
	if (rc != 0) {
		printk(KERN_ERR "%s failed %d while creating inodes\n",
			__func__, rc);
		return rc;
	}

	root_inode = sb->s_root->d_inode;
	root_inode->i_security = new_inode_smack(smack_known_floor.smk_known);

	return 0;
}

/**
 * smk_get_sb - get the smackfs superblock
 * @fs_type: passed along without comment
 * @flags: passed along without comment
 * @dev_name: passed along without comment
 * @data: passed along without comment
 * @mnt: passed along without comment
 *
 * Just passes everything along.
 *
 * Returns what the lower level code does.
 */
static int smk_get_sb(struct file_system_type *fs_type,
		      int flags, const char *dev_name, void *data,
		      struct vfsmount *mnt)
{
	return get_sb_single(fs_type, flags, data, smk_fill_super, mnt);
}

static struct file_system_type smk_fs_type = {
	.name		= "smackfs",
	.get_sb		= smk_get_sb,
	.kill_sb	= kill_litter_super,
};

static struct vfsmount *smackfs_mount;

/**
 * init_smk_fs - get the smackfs superblock
 *
 * register the smackfs
 *
 * Returns 0 unless the registration fails.
 */
static int __init init_smk_fs(void)
{
	int err;

	err = register_filesystem(&smk_fs_type);
	if (!err) {
		smackfs_mount = kern_mount(&smk_fs_type);
		if (IS_ERR(smackfs_mount)) {
			printk(KERN_ERR "smackfs:  could not mount!\n");
			err = PTR_ERR(smackfs_mount);
			smackfs_mount = NULL;
		}
	}

	sema_init(&smack_write_sem, 1);
	smk_cipso_doi();

	return err;
}

__initcall(init_smk_fs);
