Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00f84f3f authored by Casey Schaufler's avatar Casey Schaufler
Browse files

Smack: Make the syslog control configurable

The syslog control requires that the calling proccess
have the floor ("_") Smack label. Tizen does not run any
processes except for kernel helpers with the floor label.
This changes allows the admin to configure a specific
label for syslog. The default value is the star ("*")
label, effectively removing the restriction. The value
can be set using smackfs/syslog for anyone who wants
a more restrictive behavior.

Targeted for git://git.gitorious.org/smack-next/kernel.git



Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
parent 19760ad0
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -241,7 +241,8 @@ u32 smack_to_secid(const char *);
extern int smack_cipso_direct;
extern int smack_cipso_mapped;
extern struct smack_known *smack_net_ambient;
extern char *smack_onlycap;
extern struct smack_known *smack_onlycap;
extern struct smack_known *smack_syslog_label;
extern const char *smack_cipso_option;

extern struct smack_known smack_known_floor;
@@ -312,7 +313,7 @@ static inline int smack_privileged(int cap)

	if (!capable(cap))
		return 0;
	if (smack_onlycap == NULL || smack_onlycap == skp->smk_known)
	if (smack_onlycap == NULL || smack_onlycap == skp)
		return 1;
	return 0;
}
+1 −3
Original line number Diff line number Diff line
@@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
 * smack_syslog - Smack approval on syslog
 * @type: message type
 *
 * Require that the task has the floor label
 *
 * Returns 0 on success, error code otherwise.
 */
static int smack_syslog(int typefrom_file)
@@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file)
	if (smack_privileged(CAP_MAC_OVERRIDE))
		return 0;

	 if (skp != &smack_known_floor)
	 if (smack_syslog_label != NULL && smack_syslog_label != skp)
		rc = -EACCES;

	return rc;
+95 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum smk_inos {
	SMK_CIPSO2	= 17,	/* load long label -> CIPSO mapping */
	SMK_REVOKE_SUBJ	= 18,	/* set rules with subject label to '-' */
	SMK_CHANGE_RULE	= 19,	/* change or add rules (long labels) */
	SMK_SYSLOG	= 20,	/* change syslog label) */
};

/*
@@ -59,6 +60,7 @@ enum smk_inos {
 */
static DEFINE_MUTEX(smack_cipso_lock);
static DEFINE_MUTEX(smack_ambient_lock);
static DEFINE_MUTEX(smack_syslog_lock);
static DEFINE_MUTEX(smk_netlbladdr_lock);

/*
@@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
 * everyone. It is expected that the hat (^) label
 * will be used if any label is used.
 */
char *smack_onlycap;
struct smack_known *smack_onlycap;

/*
 * If this value is set restrict syslog use to the label specified.
 * It can be reset via smackfs/syslog
 */
struct smack_known *smack_syslog_label;

/*
 * Certain IP addresses may be designated as single label hosts.
@@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = {
};

/**
 * smk_read_onlycap - read() for /smack/onlycap
 * smk_read_onlycap - read() for smackfs/onlycap
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @cn: maximum to send along
@@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
		return 0;

	if (smack_onlycap != NULL)
		smack = smack_onlycap;
		smack = smack_onlycap->smk_known;

	asize = strlen(smack) + 1;

@@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf,
}

/**
 * smk_write_onlycap - write() for /smack/onlycap
 * smk_write_onlycap - write() for smackfs/onlycap
 * @file: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
@@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
	 * explicitly for clarity. The smk_access() implementation
	 * would use smk_access(smack_onlycap, MAY_WRITE)
	 */
	if (smack_onlycap != NULL && smack_onlycap != skp->smk_known)
	if (smack_onlycap != NULL && smack_onlycap != skp)
		return -EPERM;

	data = kzalloc(count, GFP_KERNEL);
@@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
	if (copy_from_user(data, buf, count) != 0)
		rc = -EFAULT;
	else
		smack_onlycap = smk_import(data, count);
		smack_onlycap = smk_import_entry(data, count);

	kfree(data);
	return rc;
@@ -2159,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = {
};

/**
 * smk_fill_super - fill the /smackfs superblock
 * smk_read_syslog - read() for smackfs/syslog
 * @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_syslog(struct file *filp, char __user *buf,
				size_t cn, loff_t *ppos)
{
	struct smack_known *skp;
	ssize_t rc = -EINVAL;
	int asize;

	if (*ppos != 0)
		return 0;

	if (smack_syslog_label == NULL)
		skp = &smack_known_star;
	else
		skp = smack_syslog_label;

	asize = strlen(skp->smk_known) + 1;

	if (cn >= asize)
		rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known,
						asize);

	return rc;
}

/**
 * smk_write_syslog - write() for smackfs/syslog
 * @file: 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_syslog(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	char *data;
	struct smack_known *skp;
	int rc = count;

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

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

	if (copy_from_user(data, buf, count) != 0)
		rc = -EFAULT;
	else {
		skp = smk_import_entry(data, count);
		if (skp == NULL)
			rc = -EINVAL;
		else
			smack_syslog_label = smk_import_entry(data, count);
	}

	kfree(data);
	return rc;
}

static const struct file_operations smk_syslog_ops = {
	.read		= smk_read_syslog,
	.write		= smk_write_syslog,
	.llseek		= default_llseek,
};


/**
 * smk_fill_super - fill the smackfs superblock
 * @sb: the empty superblock
 * @data: unused
 * @silent: unused
 *
 * Fill in the well known entries for /smack
 * Fill in the well known entries for the smack filesystem
 *
 * Returns 0 on success, an error code on failure
 */
@@ -2209,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
			S_IRUGO|S_IWUSR},
		[SMK_CHANGE_RULE] = {
			"change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR},
		[SMK_SYSLOG] = {
			"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
		/* last one */
			{""}
	};