[PATCH 2/3] Smack: remove global master list of rules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The global rule list was optimized and changed into two-level list some
time ago. But the master list remained, serving as data source for reading
/smack/load and /smack/load2. It contained all the same information as the
new two-level list, duplicating all global rules.

This patch removes the master list. Appropriate seq_file functions have been
rewritten.

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

Signed-off-by: Rafal Krypa <r.krypa@xxxxxxxxxxx>
---
 security/smack/smackfs.c |  101 +++++++++++++++++++++++++---------------------
 1 file changed, 54 insertions(+), 47 deletions(-)

diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 0fadceb..5337270 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -55,7 +55,6 @@ enum smk_inos {
 /*
  * List locks
  */
-static DEFINE_MUTEX(smack_list_lock);
 static DEFINE_MUTEX(smack_cipso_lock);
 static DEFINE_MUTEX(smack_ambient_lock);
 static DEFINE_MUTEX(smk_netlbladdr_lock);
@@ -99,17 +98,13 @@ char *smack_onlycap;
 
 LIST_HEAD(smk_netlbladdr_list);
 
-/*
- * Rule lists are maintained for each label.
- * This master list is just for reading /smack/load and /smack/load2.
- */
-struct smack_master_list {
-	struct list_head	list;
-	struct smack_rule	*smk_rule;
+struct smack_seq_iter {
+	struct list_head *known_list;
+	struct list_head *rule_list;
+	struct smack_known *skp;
+	struct smack_rule *srp;
 };
 
-LIST_HEAD(smack_rule_list);
-
 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 
 const char *smack_cipso_option = SMACK_CIPSO_OPTION;
@@ -372,13 +367,11 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
 					struct list_head *rule_list,
 					struct mutex *rule_lock, int format)
 {
-	struct smack_master_list *smlp;
 	struct smack_known *skp;
 	struct smack_rule *rule;
 	char *data;
 	int datalen;
 	int rc = -EINVAL;
-	int load = 0;
 
 	/*
 	 * No partial writes.
@@ -431,30 +424,14 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
 
 
 	if (rule_list == NULL) {
-		load = 1;
 		skp = smk_find_entry(rule->smk_subject);
 		rule_list = &skp->smk_rules;
 		rule_lock = &skp->smk_rules_lock;
 	}
 
 	rc = count;
-	/*
-	 * If this is a global as opposed to self and a new rule
-	 * it needs to get added for reporting.
-	 * smk_set_access returns true if there was already a rule
-	 * for the subject/object pair, and false if it was new.
-	 */
-	if (!smk_set_access(rule, rule_list, rule_lock)) {
-		if (load) {
-			smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
-			if (smlp != NULL) {
-				smlp->smk_rule = rule;
-				list_add_rcu(&smlp->list, &smack_rule_list);
-			} else
-				rc = -ENOMEM;
-		}
+	if (!smk_set_access(rule, rule_list, rule_lock))
 		goto out;
-	}
 
 out_free_rule:
 	kfree(rule);
@@ -534,32 +511,64 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
  * Seq_file read operations for /smack/load
  */
 
-static void *load2_seq_start(struct seq_file *s, loff_t *pos)
+static void *load_seq_start(struct seq_file *s, loff_t *pos)
 {
-	return smk_seq_start(s, pos, &smack_rule_list);
+	int i = *pos;
+	struct smack_seq_iter *it;
+
+	it = kmalloc(sizeof(*it), GFP_KERNEL);
+	s->private = it;
+	if (it == NULL)
+		return NULL;
+
+	rcu_read_lock();
+	it->known_list = &smack_known_list;
+	list_for_each_entry_rcu(it->skp, it->known_list, list) {
+		it->rule_list = &it->skp->smk_rules;
+		list_for_each_entry_rcu(it->srp, it->rule_list, list)
+			if (i-- == 0)
+				return it;
+	}
+
+	return NULL;
+}
+
+static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+	struct smack_seq_iter *it = v;
+
+	list_for_each_entry_continue_rcu(it->srp, it->rule_list, list)
+		return it;
+
+	list_for_each_entry_continue_rcu(it->skp, it->known_list, list) {
+		it->rule_list = &it->skp->smk_rules;
+		list_for_each_entry_rcu(it->srp, it->rule_list, list)
+			return it;
+	}
+
+	return NULL;
 }
 
-static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
+static void load_seq_stop(struct seq_file *s, void *v)
 {
-	return smk_seq_next(s, v, pos, &smack_rule_list);
+	kfree(s->private);
+	rcu_read_unlock();
 }
 
 static int load_seq_show(struct seq_file *s, void *v)
 {
-	struct list_head *list = v;
-	struct smack_master_list *smlp =
-		 list_entry_rcu(list, struct smack_master_list, list);
+	struct smack_seq_iter *it = v;
 
-	smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN);
+	smk_rule_show(s, it->srp, SMK_LABELLEN);
 
 	return 0;
 }
 
 static const struct seq_operations load_seq_ops = {
-	.start = load2_seq_start,
-	.next  = load2_seq_next,
+	.start = load_seq_start,
+	.next  = load_seq_next,
 	.show  = load_seq_show,
-	.stop  = smk_seq_stop,
+	.stop  = load_seq_stop,
 };
 
 /**
@@ -1832,20 +1841,18 @@ static const struct file_operations smk_access_ops = {
 
 static int load2_seq_show(struct seq_file *s, void *v)
 {
-	struct list_head *list = v;
-	struct smack_master_list *smlp =
-		 list_entry_rcu(list, struct smack_master_list, list);
+	struct smack_seq_iter *it = v;
 
-	smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL);
+	smk_rule_show(s, it->srp, SMK_LONGLABEL);
 
 	return 0;
 }
 
 static const struct seq_operations load2_seq_ops = {
-	.start = load2_seq_start,
-	.next  = load2_seq_next,
+	.start = load_seq_start,
+	.next  = load_seq_next,
 	.show  = load2_seq_show,
-	.stop  = smk_seq_stop,
+	.stop  = load_seq_stop,
 };
 
 /**
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux