lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 22 Feb 2009 22:50:13 +0100
From:	etienne <etienne.basset@...ericable.fr>
To:	Casey Schaufler <casey@...aufler-ca.com>,
	Paul Moore <paul.moore@...com>
CC:	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	LSM <linux-security-module@...r.kernel.org>,
	paulmck@...ux.vnet.ibm.com
Subject: [PATCH][SMACK] convert smack_known list to a standard linux list.

hello,

this patch on top of [PATCH][SMACK] convert smack rule list to linux list V2
converts "smack_known" to a regular linux list. (rcu variant)


regards,
Etienne

Signed-off-by: <etienne.basset@...ericable.fr>
---
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 0dcb907..64164f8 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -109,7 +109,6 @@ struct smk_netlbladdr {
  */
 struct smack_known {
 	struct list_head	list;
-	struct smack_known	*smk_next;
 	char			smk_known[SMK_LABELLEN];
 	u32			smk_secid;
 	struct smack_cipso	*smk_cipso;
@@ -202,7 +201,6 @@ extern int smack_cipso_direct;
 extern char *smack_net_ambient;
 extern char *smack_onlycap;
 
-extern struct smack_known *smack_known;
 extern struct smack_known smack_known_floor;
 extern struct smack_known smack_known_hat;
 extern struct smack_known smack_known_huh;
@@ -210,7 +208,7 @@ extern struct smack_known smack_known_invalid;
 extern struct smack_known smack_known_star;
 extern struct smack_known smack_known_web;
 
-extern struct list_head smack_know_list;
+extern struct list_head smack_known_list;
 extern struct list_head smack_rule_list;
 extern struct list_head smk_netlbladdr_list;
 
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index b184280..b16086f 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -16,48 +16,42 @@
 #include "smack.h"
 
 struct smack_known smack_known_huh = {
-	.smk_next	= NULL,
 	.smk_known	= "?",
 	.smk_secid	= 2,
 	.smk_cipso	= NULL,
 };
 
 struct smack_known smack_known_hat = {
-	.smk_next	= &smack_known_huh,
 	.smk_known	= "^",
 	.smk_secid	= 3,
 	.smk_cipso	= NULL,
 };
 
 struct smack_known smack_known_star = {
-	.smk_next	= &smack_known_hat,
 	.smk_known	= "*",
 	.smk_secid	= 4,
 	.smk_cipso	= NULL,
 };
 
 struct smack_known smack_known_floor = {
-	.smk_next	= &smack_known_star,
 	.smk_known	= "_",
 	.smk_secid	= 5,
 	.smk_cipso	= NULL,
 };
 
 struct smack_known smack_known_invalid = {
-	.smk_next	= &smack_known_floor,
 	.smk_known	= "",
 	.smk_secid	= 6,
 	.smk_cipso	= NULL,
 };
 
 struct smack_known smack_known_web = {
-	.smk_next	= &smack_known_invalid,
 	.smk_known	= "@",
 	.smk_secid	= 7,
 	.smk_cipso	= NULL,
 };
 
-struct smack_known *smack_known = &smack_known_web;
+LIST_HEAD(smack_known_list);
 
 /*
  * The initial value needs to be bigger than any of the
@@ -227,14 +221,17 @@ struct smack_known *smk_import_entry(const char *string, int len)
 
 	mutex_lock(&smack_known_lock);
 
-	for (skp = smack_known; skp != NULL; skp = skp->smk_next)
-		if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0)
+	found = 0;
+	list_for_each_entry_rcu(skp, &smack_known_list, list) {
+		if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
+			found = 1;
 			break;
+		}
+	}
 
-	if (skp == NULL) {
+	if (found == 0) {
 		skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL);
 		if (skp != NULL) {
-			skp->smk_next = smack_known;
 			strncpy(skp->smk_known, smack, SMK_MAXLEN);
 			skp->smk_secid = smack_next_secid++;
 			skp->smk_cipso = NULL;
@@ -244,7 +241,7 @@ struct smack_known *smk_import_entry(const char *string, int len)
 			 * filled before putting it on the list.
 			 */
 			smp_mb();
-			smack_known = skp;
+			list_add(&skp->list, &smack_known_list);
 		}
 	}
 
@@ -282,14 +279,19 @@ char *smack_from_secid(const u32 secid)
 {
 	struct smack_known *skp;
 
-	for (skp = smack_known; skp != NULL; skp = skp->smk_next)
-		if (skp->smk_secid == secid)
+	rcu_read_lock();
+	list_for_each_entry_rcu(skp, &smack_known_list, list) {
+		if (skp->smk_secid == secid) {
+			rcu_read_unlock();
 			return skp->smk_known;
+		}
+	}
 
 	/*
 	 * If we got this far someone asked for the translation
 	 * of a secid that is not on the list.
 	 */
+	rcu_read_unlock();
 	return smack_known_invalid.smk_known;
 }
 
@@ -304,9 +306,14 @@ u32 smack_to_secid(const char *smack)
 {
 	struct smack_known *skp;
 
-	for (skp = smack_known; skp != NULL; skp = skp->smk_next)
-		if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0)
+	rcu_read_lock();
+	list_for_each_entry_rcu(skp, &smack_known_list, list) {
+		if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) {
+			rcu_read_unlock();
 			return skp->smk_secid;
+		}
+	}
+	rcu_read_unlock();
 	return 0;
 }
 
@@ -331,7 +338,8 @@ void smack_from_cipso(u32 level, char *cp, char *result)
 	struct smack_known *kp;
 	char *final = NULL;
 
-	for (kp = smack_known; final == NULL && kp != NULL; kp = kp->smk_next) {
+	rcu_read_lock();
+	list_for_each_entry(kp, &smack_known_list, list) {
 		if (kp->smk_cipso == NULL)
 			continue;
 
@@ -343,6 +351,7 @@ void smack_from_cipso(u32 level, char *cp, char *result)
 
 		spin_unlock_bh(&kp->smk_cipsolock);
 	}
+	rcu_read_unlock();
 	if (final == NULL)
 		final = smack_known_huh.smk_known;
 	strncpy(result, final, SMK_MAXLEN);
@@ -359,13 +368,19 @@ void smack_from_cipso(u32 level, char *cp, char *result)
 int smack_to_cipso(const char *smack, struct smack_cipso *cp)
 {
 	struct smack_known *kp;
+	int found = 0;
 
-	for (kp = smack_known; kp != NULL; kp = kp->smk_next)
+	rcu_read_lock();
+	list_for_each_entry_rcu(kp, &smack_known_list, list) {
 		if (kp->smk_known == smack ||
-		    strcmp(kp->smk_known, smack) == 0)
+		    strcmp(kp->smk_known, smack) == 0) {
+			found = 1;
 			break;
+		}
+	}
+	rcu_read_unlock();
 
-	if (kp == NULL || kp->smk_cipso == NULL)
+	if (found == 0 || kp->smk_cipso == NULL)
 		return -ENOENT;
 
 	memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso));
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 65a4a8a..e6f89d6 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2935,6 +2935,17 @@ struct security_operations smack_ops = {
 	.release_secctx = 		smack_release_secctx,
 };
 
+
+static __init init_smack_know_list(void)
+{
+	list_add(&smack_known_huh.list, &smack_known_list);
+	list_add(&smack_known_hat.list, &smack_known_list);
+	list_add(&smack_known_star.list, &smack_known_list);
+	list_add(&smack_known_floor.list, &smack_known_list);
+	list_add(&smack_known_invalid.list, &smack_known_list);
+	list_add(&smack_known_web.list, &smack_known_list);
+}
+
 /**
  * smack_init - initialize the smack system
  *
@@ -2955,6 +2966,8 @@ static __init int smack_init(void)
 	cred = (struct cred *) current->cred;
 	cred->security = &smack_known_floor.smk_known;
 
+	/* initilize the smack_know_list */
+	init_smack_know_list();
 	/*
 	 * Initialize locks
 	 */
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 771e452..665e2cc 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -84,7 +84,6 @@ char *smack_onlycap;
 LIST_HEAD(smk_netlbladdr_list);
 LIST_HEAD(smack_rule_list);
 
-
 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
 
 #define	SEQ_READ_FINISHED	1
@@ -436,24 +435,26 @@ static void *cipso_seq_start(struct seq_file *s, loff_t *pos)
 {
 	if (*pos == SEQ_READ_FINISHED)
 		return NULL;
+	if (list_empty(&smack_known_list))
+		return NULL;
 
-	return smack_known;
+	return &smack_known_list;
 }
 
 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-	struct smack_known *skp = ((struct smack_known *) v)->smk_next;
+	struct list_head  *list = v;
 
 	/*
-	 * Omit labels with no associated cipso value
+	 * labels with no associated cipso value wont be printed
+	 * in cipso_seq_show
 	 */
-	while (skp != NULL && !skp->smk_cipso)
-		skp = skp->smk_next;
-
-	if (skp == NULL)
+	if (list_is_last(list->next, &smack_known_list)) {
 		*pos = SEQ_READ_FINISHED;
+		return NULL;
+	}
 
-	return skp;
+	return list->next;
 }
 
 /*
@@ -462,7 +463,8 @@ static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos)
  */
 static int cipso_seq_show(struct seq_file *s, void *v)
 {
-	struct smack_known *skp = (struct smack_known *) v;
+	struct list_head  *list = v;
+	struct smack_known *skp = container_of(list->next, struct smack_known, list);
 	struct smack_cipso *scp = skp->smk_cipso;
 	char *cbp;
 	char sep = '/';
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ