Commit 40809565 authored by Casey Schaufler's avatar Casey Schaufler Committed by Casey Schaufler

Smack: smackfs cipso seq read repair

Commit 272cd7a8 introduced
a change to the way rule lists are handled and reported in
the smackfs filesystem. One of the issues addressed had to
do with the termination of read requests on /smack/load.
This change introduced a error in /smack/cipso, which shares
some of the same list processing code.

This patch updates all the file access list handling in
smackfs to use the code introduced for /smack/load.
Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
parent 0e94ae17
...@@ -102,9 +102,6 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; ...@@ -102,9 +102,6 @@ static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
const char *smack_cipso_option = SMACK_CIPSO_OPTION; const char *smack_cipso_option = SMACK_CIPSO_OPTION;
#define SEQ_READ_FINISHED ((loff_t)-1)
/* /*
* Values for parsing cipso rules * Values for parsing cipso rules
* SMK_DIGITLEN: Length of a digit field in a rule. * SMK_DIGITLEN: Length of a digit field in a rule.
...@@ -357,10 +354,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf, ...@@ -357,10 +354,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
rc = count; rc = count;
/* /*
* If this is "load" as opposed to "load-self" and a new rule
* it needs to get added for reporting.
* smk_set_access returns true if there was already a rule * smk_set_access returns true if there was already a rule
* for the subject/object pair, and false if it was new. * for the subject/object pair, and false if it was new.
*/ */
if (!smk_set_access(rule, rule_list, rule_lock)) { if (load && !smk_set_access(rule, rule_list, rule_lock)) {
smlp = kzalloc(sizeof(*smlp), GFP_KERNEL); smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
if (smlp != NULL) { if (smlp != NULL) {
smlp->smk_rule = rule; smlp->smk_rule = rule;
...@@ -377,12 +376,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf, ...@@ -377,12 +376,12 @@ static ssize_t smk_write_load_list(struct file *file, const char __user *buf,
return rc; return rc;
} }
/* /*
* Seq_file read operations for /smack/load * Core logic for smackfs seq list operations.
*/ */
static void *load_seq_start(struct seq_file *s, loff_t *pos) static void *smk_seq_start(struct seq_file *s, loff_t *pos,
struct list_head *head)
{ {
struct list_head *list; struct list_head *list;
...@@ -390,7 +389,7 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos) ...@@ -390,7 +389,7 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
* This is 0 the first time through. * This is 0 the first time through.
*/ */
if (s->index == 0) if (s->index == 0)
s->private = &smack_rule_list; s->private = head;
if (s->private == NULL) if (s->private == NULL)
return NULL; return NULL;
...@@ -404,11 +403,12 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos) ...@@ -404,11 +403,12 @@ static void *load_seq_start(struct seq_file *s, loff_t *pos)
return list; return list;
} }
static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) static void *smk_seq_next(struct seq_file *s, void *v, loff_t *pos,
struct list_head *head)
{ {
struct list_head *list = v; struct list_head *list = v;
if (list_is_last(list, &smack_rule_list)) { if (list_is_last(list, head)) {
s->private = NULL; s->private = NULL;
return NULL; return NULL;
} }
...@@ -416,6 +416,25 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) ...@@ -416,6 +416,25 @@ static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
return list->next; return list->next;
} }
static void smk_seq_stop(struct seq_file *s, void *v)
{
/* No-op */
}
/*
* Seq_file read operations for /smack/load
*/
static void *load_seq_start(struct seq_file *s, loff_t *pos)
{
return smk_seq_start(s, pos, &smack_rule_list);
}
static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
return smk_seq_next(s, v, pos, &smack_rule_list);
}
static int load_seq_show(struct seq_file *s, void *v) static int load_seq_show(struct seq_file *s, void *v)
{ {
struct list_head *list = v; struct list_head *list = v;
...@@ -446,16 +465,11 @@ static int load_seq_show(struct seq_file *s, void *v) ...@@ -446,16 +465,11 @@ static int load_seq_show(struct seq_file *s, void *v)
return 0; return 0;
} }
static void load_seq_stop(struct seq_file *s, void *v)
{
/* No-op */
}
static const struct seq_operations load_seq_ops = { static const struct seq_operations load_seq_ops = {
.start = load_seq_start, .start = load_seq_start,
.next = load_seq_next, .next = load_seq_next,
.show = load_seq_show, .show = load_seq_show,
.stop = load_seq_stop, .stop = smk_seq_stop,
}; };
/** /**
...@@ -574,28 +588,12 @@ static void smk_unlbl_ambient(char *oldambient) ...@@ -574,28 +588,12 @@ static void smk_unlbl_ambient(char *oldambient)
static void *cipso_seq_start(struct seq_file *s, loff_t *pos) static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
{ {
if (*pos == SEQ_READ_FINISHED) return smk_seq_start(s, pos, &smack_known_list);
return NULL;
if (list_empty(&smack_known_list))
return NULL;
return smack_known_list.next;
} }
static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
{ {
struct list_head *list = v; return smk_seq_next(s, v, pos, &smack_known_list);
/*
* labels with no associated cipso value wont be printed
* in cipso_seq_show
*/
if (list_is_last(list, &smack_known_list)) {
*pos = SEQ_READ_FINISHED;
return NULL;
}
return list->next;
} }
/* /*
...@@ -634,16 +632,11 @@ static int cipso_seq_show(struct seq_file *s, void *v) ...@@ -634,16 +632,11 @@ static int cipso_seq_show(struct seq_file *s, void *v)
return 0; return 0;
} }
static void cipso_seq_stop(struct seq_file *s, void *v)
{
/* No-op */
}
static const struct seq_operations cipso_seq_ops = { static const struct seq_operations cipso_seq_ops = {
.start = cipso_seq_start, .start = cipso_seq_start,
.stop = cipso_seq_stop,
.next = cipso_seq_next, .next = cipso_seq_next,
.show = cipso_seq_show, .show = cipso_seq_show,
.stop = smk_seq_stop,
}; };
/** /**
...@@ -788,23 +781,12 @@ static const struct file_operations smk_cipso_ops = { ...@@ -788,23 +781,12 @@ static const struct file_operations smk_cipso_ops = {
static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
{ {
if (*pos == SEQ_READ_FINISHED) return smk_seq_start(s, pos, &smk_netlbladdr_list);
return NULL;
if (list_empty(&smk_netlbladdr_list))
return NULL;
return smk_netlbladdr_list.next;
} }
static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
{ {
struct list_head *list = v; return smk_seq_next(s, v, pos, &smk_netlbladdr_list);
if (list_is_last(list, &smk_netlbladdr_list)) {
*pos = SEQ_READ_FINISHED;
return NULL;
}
return list->next;
} }
#define BEBITS (sizeof(__be32) * 8) #define BEBITS (sizeof(__be32) * 8)
...@@ -828,16 +810,11 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v) ...@@ -828,16 +810,11 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
return 0; return 0;
} }
static void netlbladdr_seq_stop(struct seq_file *s, void *v)
{
/* No-op */
}
static const struct seq_operations netlbladdr_seq_ops = { static const struct seq_operations netlbladdr_seq_ops = {
.start = netlbladdr_seq_start, .start = netlbladdr_seq_start,
.stop = netlbladdr_seq_stop,
.next = netlbladdr_seq_next, .next = netlbladdr_seq_next,
.show = netlbladdr_seq_show, .show = netlbladdr_seq_show,
.stop = smk_seq_stop,
}; };
/** /**
...@@ -1405,23 +1382,14 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos) ...@@ -1405,23 +1382,14 @@ static void *load_self_seq_start(struct seq_file *s, loff_t *pos)
{ {
struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security();
if (*pos == SEQ_READ_FINISHED) return smk_seq_start(s, pos, &tsp->smk_rules);
return NULL;
if (list_empty(&tsp->smk_rules))
return NULL;
return tsp->smk_rules.next;
} }
static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos) static void *load_self_seq_next(struct seq_file *s, void *v, loff_t *pos)
{ {
struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security();
struct list_head *list = v;
if (list_is_last(list, &tsp->smk_rules)) { return smk_seq_next(s, v, pos, &tsp->smk_rules);
*pos = SEQ_READ_FINISHED;
return NULL;
}
return list->next;
} }
static int load_self_seq_show(struct seq_file *s, void *v) static int load_self_seq_show(struct seq_file *s, void *v)
...@@ -1453,16 +1421,11 @@ static int load_self_seq_show(struct seq_file *s, void *v) ...@@ -1453,16 +1421,11 @@ static int load_self_seq_show(struct seq_file *s, void *v)
return 0; return 0;
} }
static void load_self_seq_stop(struct seq_file *s, void *v)
{
/* No-op */
}
static const struct seq_operations load_self_seq_ops = { static const struct seq_operations load_self_seq_ops = {
.start = load_self_seq_start, .start = load_self_seq_start,
.next = load_self_seq_next, .next = load_self_seq_next,
.show = load_self_seq_show, .show = load_self_seq_show,
.stop = load_self_seq_stop, .stop = smk_seq_stop,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment