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

Commit 0e94ae17 authored by Jarkko Sakkinen's avatar Jarkko Sakkinen Committed by Casey Schaufler
Browse files

Smack: allow to access /smack/access as normal user



Allow query access as a normal user removing the need
for CAP_MAC_ADMIN. Give RW access to /smack/access
for UGO. Do not import smack labels in access check.

Signed-off-by: default avatarJarkko Sakkinen <jarkko.j.sakkinen@gmail.com>
Signed-off-by: default avatarCasey Schaufler <cschaufler@cschaufler-intel.(none)>
parent d86b2b61
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -208,6 +208,7 @@ int smk_curacc(char *, u32, struct smk_audit_info *);
int smack_to_cipso(const char *, struct smack_cipso *);
int smack_to_cipso(const char *, struct smack_cipso *);
char *smack_from_cipso(u32, char *);
char *smack_from_cipso(u32, char *);
char *smack_from_secid(const u32);
char *smack_from_secid(const u32);
void smk_parse_smack(const char *string, int len, char *smack);
char *smk_import(const char *, int);
char *smk_import(const char *, int);
struct smack_known *smk_import_entry(const char *, int);
struct smack_known *smk_import_entry(const char *, int);
struct smack_known *smk_find_entry(const char *);
struct smack_known *smk_find_entry(const char *);
+19 −8
Original line number Original line Diff line number Diff line
@@ -353,17 +353,13 @@ struct smack_known *smk_find_entry(const char *string)
}
}


/**
/**
 * smk_import_entry - import a label, return the list entry
 * smk_parse_smack - parse smack label from a text string
 * @string: a text string that might be a Smack label
 * @string: a text string that might contain a Smack label
 * @len: the maximum size, or zero if it is NULL terminated.
 * @len: the maximum size, or zero if it is NULL terminated.
 *
 * @smack: parsed smack label, or NULL if parse error
 * Returns a pointer to the entry in the label list that
 * matches the passed string, adding it if necessary.
 */
 */
struct smack_known *smk_import_entry(const char *string, int len)
void smk_parse_smack(const char *string, int len, char *smack)
{
{
	struct smack_known *skp;
	char smack[SMK_LABELLEN];
	int found;
	int found;
	int i;
	int i;


@@ -381,7 +377,22 @@ struct smack_known *smk_import_entry(const char *string, int len)
		} else
		} else
			smack[i] = string[i];
			smack[i] = string[i];
	}
	}
}

/**
 * smk_import_entry - import a label, return the list entry
 * @string: a text string that might be a Smack label
 * @len: the maximum size, or zero if it is NULL terminated.
 *
 * Returns a pointer to the entry in the label list that
 * matches the passed string, adding it if necessary.
 */
struct smack_known *smk_import_entry(const char *string, int len)
{
	struct smack_known *skp;
	char smack[SMK_LABELLEN];


	smk_parse_smack(string, len, smack);
	if (smack[0] == '\0')
	if (smack[0] == '\0')
		return NULL;
		return NULL;


+30 −15
Original line number Original line Diff line number Diff line
@@ -191,12 +191,17 @@ static int smk_set_access(struct smack_rule *srp, struct list_head *rule_list,
}
}


/**
/**
 * smk_parse_rule - parse subject, object and access type
 * smk_parse_rule - parse Smack rule from load string
 * @data: string to be parsed whose size is SMK_LOADLEN
 * @data: string to be parsed whose size is SMK_LOADLEN
 * @rule: parsed entities are stored in here
 * @rule: Smack rule
 * @import: if non-zero, import labels
 */
 */
static int smk_parse_rule(const char *data, struct smack_rule *rule)
static int smk_parse_rule(const char *data, struct smack_rule *rule, int import)
{
{
	char smack[SMK_LABELLEN];
	struct smack_known *skp;

	if (import) {
		rule->smk_subject = smk_import(data, 0);
		rule->smk_subject = smk_import(data, 0);
		if (rule->smk_subject == NULL)
		if (rule->smk_subject == NULL)
			return -1;
			return -1;
@@ -204,6 +209,19 @@ static int smk_parse_rule(const char *data, struct smack_rule *rule)
		rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
		rule->smk_object = smk_import(data + SMK_LABELLEN, 0);
		if (rule->smk_object == NULL)
		if (rule->smk_object == NULL)
			return -1;
			return -1;
	} else {
		smk_parse_smack(data, 0, smack);
		skp = smk_find_entry(smack);
		if (skp == NULL)
			return -1;
		rule->smk_subject = skp->smk_known;

		smk_parse_smack(data + SMK_LABELLEN, 0, smack);
		skp = smk_find_entry(smack);
		if (skp == NULL)
			return -1;
		rule->smk_object = skp->smk_known;
	}


	rule->smk_access = 0;
	rule->smk_access = 0;


@@ -327,7 +345,7 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
		goto out;
		goto out;
	}
	}


	if (smk_parse_rule(data, rule))
	if (smk_parse_rule(data, rule, 1))
		goto out_free_rule;
		goto out_free_rule;


	if (rule_list == NULL) {
	if (rule_list == NULL) {
@@ -1499,14 +1517,11 @@ static ssize_t smk_write_access(struct file *file, const char __user *buf,
	char *data;
	char *data;
	int res;
	int res;


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

	data = simple_transaction_get(file, buf, count);
	data = simple_transaction_get(file, buf, count);
	if (IS_ERR(data))
	if (IS_ERR(data))
		return PTR_ERR(data);
		return PTR_ERR(data);


	if (count < SMK_LOADLEN || smk_parse_rule(data, &rule))
	if (count < SMK_LOADLEN || smk_parse_rule(data, &rule, 0))
		return -EINVAL;
		return -EINVAL;


	res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
	res = smk_access(rule.smk_subject, rule.smk_object, rule.smk_access,
@@ -1560,7 +1575,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
		[SMK_LOAD_SELF] = {
		[SMK_LOAD_SELF] = {
			"load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
			"load-self", &smk_load_self_ops, S_IRUGO|S_IWUGO},
		[SMK_ACCESSES] = {
		[SMK_ACCESSES] = {
			"access", &smk_access_ops, S_IRUGO|S_IWUSR},
			"access", &smk_access_ops, S_IRUGO|S_IWUGO},
		/* last one */
		/* last one */
			{""}
			{""}
	};
	};