From: etienne <etienne.basset@numericable.fr>
To: Casey Schaufler <casey@schaufler-ca.com>, Paul Moore <paul.moore@hp.com>
Cc: LSM <linux-security-module@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
paulmck@linux.vnet.ibm.com
Subject: [PATCH][SMACK][RFC] convert smack_netlbladdrs to standard list V2
Date: Sun, 22 Feb 2009 22:22:08 +0100 [thread overview]
Message-ID: <49A1C200.80609@numericable.fr> (raw)
hello,
please find below my seond try to convert smack_netlbladdrs to standard list
(patch on top of .29rc5 + [PATCH] SMACK netlabel fixes v2)
I tested it and found no regression, no hangs etc...
change since v1 : use rcu variants for list manipulation (thanks Tetsuo Handa a Paul McKenney)
Please let me know if there are problems
Etienne
Signed-off-by: <etienne.basset@numericable.fr>
---
diff --git a/security/smack/smack.h b/security/smack/smack.h
index b79582e..2db35d7 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -18,6 +18,8 @@
#include <linux/security.h>
#include <linux/in.h>
#include <net/netlabel.h>
+#include <linux/list.h>
+#include <linux/rculist.h>
/*
* Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
@@ -69,6 +71,7 @@ struct smack_rule {
*/
struct smk_list_entry {
struct smk_list_entry *smk_next;
+ struct list_head list;
struct smack_rule smk_rule;
};
@@ -85,7 +88,7 @@ struct smack_cipso {
* An entry in the table identifying hosts.
*/
struct smk_netlbladdr {
- struct smk_netlbladdr *smk_next;
+ struct list_head list;
struct sockaddr_in smk_host; /* network address */
struct in_addr smk_mask; /* network mask */
char *smk_label; /* label */
@@ -113,6 +116,7 @@ struct smk_netlbladdr {
* the cipso direct mapping in used internally.
*/
struct smack_known {
+ struct list_head list;
struct smack_known *smk_next;
char smk_known[SMK_LABELLEN];
u32 smk_secid;
@@ -215,7 +219,9 @@ extern struct smack_known smack_known_star;
extern struct smack_known smack_known_web;
extern struct smk_list_entry *smack_list;
-extern struct smk_netlbladdr *smack_netlbladdrs;
+extern struct list_head smack_know_list;
+extern struct list_head smack_rule_list;
+extern struct list_head smk_netlbladdr_list;
extern struct security_operations smack_ops;
/*
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index e7ded13..65a4a8a 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1509,8 +1509,8 @@ static char *smack_host_label(struct sockaddr_in *sip)
if (siap->s_addr == 0)
return NULL;
-
- for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(snp, &smk_netlbladdr_list, list) {
/*
* we break after finding the first match because
* the list is sorted from longest to shortest mask
@@ -1518,10 +1518,11 @@ static char *smack_host_label(struct sockaddr_in *sip)
*/
if ((&snp->smk_host.sin_addr)->s_addr ==
(siap->s_addr & (&snp->smk_mask)->s_addr)) {
+ rcu_read_unlock();
return snp->smk_label;
}
}
-
+ rcu_read_unlock();
return NULL;
}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 51f0efc..7494808 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -80,7 +80,8 @@ char *smack_onlycap;
* Packets are sent there unlabeled, but only from tasks that
* can write to the specified label.
*/
-struct smk_netlbladdr *smack_netlbladdrs;
+
+LIST_HEAD(smk_netlbladdr_list);
static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT;
struct smk_list_entry *smack_list;
@@ -637,18 +638,21 @@ static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos)
{
if (*pos == SEQ_READ_FINISHED)
return NULL;
-
- return smack_netlbladdrs;
+ if (list_empty(&smk_netlbladdr_list))
+ return NULL;
+ return &smk_netlbladdr_list;
}
static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
- struct smk_netlbladdr *skp = ((struct smk_netlbladdr *) v)->smk_next;
-
- if (skp == NULL)
+ struct list_head *list = v;
+
+ if (list_is_last(list->next, &smk_netlbladdr_list)) {
*pos = SEQ_READ_FINISHED;
+ return NULL;
+ }
- return skp;
+ return list->next;
}
#define BEBITS (sizeof(__be32) * 8)
@@ -657,7 +661,8 @@ static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
*/
static int netlbladdr_seq_show(struct seq_file *s, void *v)
{
- struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v;
+ struct list_head *list = v;
+ struct smk_netlbladdr *skp = container_of(list->next, struct smk_netlbladdr, list);
unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
int maskn;
u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
@@ -701,33 +706,37 @@ static int smk_open_netlbladdr(struct inode *inode, struct file *file)
*
* This helper insert netlabel in the smack_netlbladdrs list
* sorted by netmask length (longest to smallest)
+ * locked by &smk_netlbladdr_lock in smk_write_netlbladdr
+ *
*/
static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
{
- struct smk_netlbladdr *m;
+ struct smk_netlbladdr *m, *m_next;
- if (smack_netlbladdrs == NULL) {
- smack_netlbladdrs = new;
- return;
- }
+ if (list_empty(&smk_netlbladdr_list)) {
+ list_add_rcu(&new->list, &smk_netlbladdr_list);
+ return;
+ }
/* the comparison '>' is a bit hacky, but works */
- if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) {
- new->smk_next = smack_netlbladdrs;
- smack_netlbladdrs = new;
- return;
- }
- for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) {
- if (m->smk_next == NULL) {
- m->smk_next = new;
- return;
- }
- if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) {
- new->smk_next = m->smk_next;
- m->smk_next = new;
- return;
- }
- }
+ m = container_of(rcu_dereference(smk_netlbladdr_list.next), struct smk_netlbladdr, list);
+
+ if (new->smk_mask.s_addr > m->smk_mask.s_addr) {
+ list_add_rcu(&new->list, &smk_netlbladdr_list);
+ return;
+ }
+
+ list_for_each_entry_rcu(m, &smk_netlbladdr_list, list) {
+ if (list_is_last(&m->list, &smk_netlbladdr_list)) {
+ list_add_rcu(&new->list, &m->list);
+ return;
+ }
+ m_next = container_of(rcu_dereference(m->list.next), struct smk_netlbladdr, list);
+ if (new->smk_mask.s_addr > m_next->smk_mask.s_addr) {
+ list_add_rcu(&new->list, &m->list);
+ return;
+ }
+ }
}
@@ -754,6 +763,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
struct netlbl_audit audit_info;
struct in_addr mask;
unsigned int m;
+ int found;
u32 mask_bits = (1<<31);
__be32 nsa;
u32 temp_mask;
@@ -807,14 +817,18 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
nsa = newname.sin_addr.s_addr;
/* try to find if the prefix is already in the list */
- for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next)
+ found = 0;
+ list_for_each_entry_rcu(skp, &smk_netlbladdr_list, list) {
if (skp->smk_host.sin_addr.s_addr == nsa &&
- skp->smk_mask.s_addr == mask.s_addr)
- break;
+ skp->smk_mask.s_addr == mask.s_addr) {
+ found = 1;
+ break;
+ }
+ }
smk_netlabel_audit_set(&audit_info);
- if (skp == NULL) {
+ if (!found) {
skp = kzalloc(sizeof(*skp), GFP_KERNEL);
if (skp == NULL)
rc = -ENOMEM;
reply other threads:[~2009-02-22 21:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49A1C200.80609@numericable.fr \
--to=etienne.basset@numericable.fr \
--cc=casey@schaufler-ca.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=paul.moore@hp.com \
--cc=paulmck@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.