All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-21 15:38 [PATCH 0/4] selinux: add object class discovery Christopher J. PeBenito
@ 2007-05-21 15:38 ` Christopher J. PeBenito
  2007-05-21 17:02   ` James Morris
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-21 15:38 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux, Christopher J. PeBenito

From: Christopher J. PeBenito <cpebenito@tresys.com>

Add support to the SELinux security server for obtaining a list of classes,
and for obtaining a list of permissions for a specified class.

Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

---
 security/selinux/include/security.h |    3 +
 security/selinux/ss/services.c      |   93 +++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index b94378a..731a173 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -87,6 +87,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
 
 int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
+int security_get_classes(char ***classes, int *nclasses);
+int security_get_permissions(char *class, char ***perms, int *nperms);
+
 #define SECURITY_FS_USE_XATTR		1 /* use xattr */
 #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
 #define SECURITY_FS_USE_TASK		3 /* use task SIDs, e.g. pipefs/sockfs */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 40660ff..4196c66 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1996,6 +1996,99 @@ out:
 	return rc;
 }
 
+static int get_classes_callback(void *k, void *d, void *args)
+{
+	struct class_datum *datum = d;
+	char *name = k, **classes = args;
+	int value = datum->value - 1;
+
+	classes[value] = kstrdup(name,GFP_KERNEL);
+
+	if (classes[value] == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int security_get_classes(char ***classes, int *nclasses)
+{
+	int rc = -ENOMEM;
+
+	POLICY_RDLOCK;
+
+	*nclasses = policydb.p_classes.nprim;
+	*classes = kzalloc(*nclasses*sizeof(*classes),GFP_KERNEL);
+	if (!*classes)
+		goto out;
+
+	rc = hashtab_map(policydb.p_classes.table,get_classes_callback,*classes);
+	if (rc < 0) {
+		int i;
+		for (i = 0; i < *nclasses; i++)
+			kfree((*classes)[i]);
+		kfree(*classes);
+	}
+	
+out:
+	POLICY_RDUNLOCK;
+	return rc;
+}
+
+static int get_permissions_callback(void *k, void *d, void *args)
+{
+	struct perm_datum *datum = d;
+	char *name = k, **perms = args;
+	int value = datum->value - 1;
+
+	perms[value] = kstrdup(name,GFP_KERNEL);
+
+	if (perms[value] == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int security_get_permissions(char *class, char ***perms, int *nperms)
+{
+	int rc = -ENOMEM, i;
+	struct class_datum *match;
+
+	POLICY_RDLOCK;
+
+	match = hashtab_search(policydb.p_classes.table,class);
+	if (match == NULL) {
+		printk(KERN_ERR "%s:  unrecognized class %s\n",__FUNCTION__,class);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	*nperms = match->permissions.nprim;
+	*perms = kzalloc(*nperms*sizeof(*perms),GFP_KERNEL);
+	if (!*perms)
+		goto out;
+
+	if (match->comdatum) {
+		rc = hashtab_map(match->comdatum->permissions.table,get_permissions_callback,*perms);
+		if (rc < 0)
+			goto err;
+	}
+
+	rc = hashtab_map(match->permissions.table,get_permissions_callback,*perms);
+	if (rc < 0)
+		goto err;
+
+out:
+	POLICY_RDUNLOCK;
+	return rc;
+
+err:
+	POLICY_RDUNLOCK;
+	for (i = 0; i < *nperms; i++)
+		kfree((*perms)[i]);
+	kfree(*perms);
+	return rc;
+}
+
 struct selinux_audit_rule {
 	u32 au_seqno;
 	struct context au_ctxt;
-- 
1.5.1.4


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-21 15:38 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
@ 2007-05-21 17:02   ` James Morris
  2007-05-21 18:44     ` Christopher J. PeBenito
  0 siblings, 1 reply; 12+ messages in thread
From: James Morris @ 2007-05-21 17:02 UTC (permalink / raw)
  To: Christopher J. PeBenito; +Cc: sds, jmorris, eparis, selinux

On Mon, 21 May 2007, Christopher J. PeBenito wrote:

>  int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
>  
> +int security_get_classes(char ***classes, int *nclasses);
> +int security_get_permissions(char *class, char ***perms, int *nperms);
> +
>  #define SECURITY_FS_USE_XATTR		1 /* use xattr */
>  #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
>  #define SECURITY_FS_USE_TASK		3 /* use task SIDs, e.g. pipefs/sockfs */
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 40660ff..4196c66 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -1996,6 +1996,99 @@ out:
>  	return rc;
>  }
>  
> +static int get_classes_callback(void *k, void *d, void *args)
> +{
> +	struct class_datum *datum = d;
> +	char *name = k, **classes = args;
> +	int value = datum->value - 1;
> +
> +	classes[value] = kstrdup(name,GFP_KERNEL);

Coding style: spaces after commas (needs to be fixed throughout).

> +

Probably don't need this blank line.

> +	if (classes[value] == NULL)
> +		return -ENOMEM;

I'd suggest

	if (!foo)

to remain consistent.

> +
> +	return 0;
> +}
> +
> +int security_get_classes(char ***classes, int *nclasses)
> +{
> +	int rc = -ENOMEM;
> +
> +	POLICY_RDLOCK;
> +
> +	*nclasses = policydb.p_classes.nprim;
> +	*classes = kzalloc(*nclasses*sizeof(*classes),GFP_KERNEL);

Use kcalloc().

Needs to be GFP_ATOMIC because you're holding a spinlock.

> +	if (!*classes)
> +		goto out;
> +
> +	rc = hashtab_map(policydb.p_classes.table,get_classes_callback,*classes);
> +	if (rc < 0) {
> +		int i;
> +		for (i = 0; i < *nclasses; i++)
> +			kfree((*classes)[i]);
> +		kfree(*classes);
> +	}
> +	
> +out:
> +	POLICY_RDUNLOCK;
> +	return rc;
> +}
> +
> +static int get_permissions_callback(void *k, void *d, void *args)
> +{
> +	struct perm_datum *datum = d;
> +	char *name = k, **perms = args;
> +	int value = datum->value - 1;
> +
> +	perms[value] = kstrdup(name,GFP_KERNEL);

Ditto.

(Have you tested this with all of the lock debugging enabled ?)

> +
> +	if (perms[value] == NULL)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +int security_get_permissions(char *class, char ***perms, int *nperms)
> +{
> +	int rc = -ENOMEM, i;
> +	struct class_datum *match;
> +
> +	POLICY_RDLOCK;
> +
> +	match = hashtab_search(policydb.p_classes.table,class);
> +	if (match == NULL) {
> +		printk(KERN_ERR "%s:  unrecognized class %s\n",__FUNCTION__,class);
> +		rc = -EINVAL;
> +		goto out;
> +	}
> +
> +	*nperms = match->permissions.nprim;
> +	*perms = kzalloc(*nperms*sizeof(*perms),GFP_KERNEL);

Ditto.

> +	if (!*perms)
> +		goto out;
> +
> +	if (match->comdatum) {
> +		rc = hashtab_map(match->comdatum->permissions.table,get_permissions_callback,*perms);
> +		if (rc < 0)
> +			goto err;
> +	}
> +
> +	rc = hashtab_map(match->permissions.table,get_permissions_callback,*perms);
> +	if (rc < 0)
> +		goto err;
> +
> +out:
> +	POLICY_RDUNLOCK;
> +	return rc;
> +
> +err:
> +	POLICY_RDUNLOCK;
> +	for (i = 0; i < *nperms; i++)
> +		kfree((*perms)[i]);
> +	kfree(*perms);
> +	return rc;
> +}
> +
>  struct selinux_audit_rule {
>  	u32 au_seqno;
>  	struct context au_ctxt;
> 

-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-21 17:02   ` James Morris
@ 2007-05-21 18:44     ` Christopher J. PeBenito
  0 siblings, 0 replies; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-21 18:44 UTC (permalink / raw)
  To: James Morris; +Cc: sds, jmorris, eparis, selinux

On Mon, 2007-05-21 at 13:02 -0400, James Morris wrote:
> On Mon, 21 May 2007, Christopher J. PeBenito wrote:
> > +int security_get_classes(char ***classes, int *nclasses)
> > +{
> > +	int rc = -ENOMEM;
> > +
> > +	POLICY_RDLOCK;
> > +
> > +	*nclasses = policydb.p_classes.nprim;
> > +	*classes = kzalloc(*nclasses*sizeof(*classes),GFP_KERNEL);
> 
> Use kcalloc().
> 
> Needs to be GFP_ATOMIC because you're holding a spinlock.
[...]
> (Have you tested this with all of the lock debugging enabled ?)

Nope, my mistake.  I'm a kernel coding newbie :)

-- 
Chris PeBenito
Tresys Technology, LLC
(410) 290-1411 x150


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* selinux: add object class discovery v2
@ 2007-05-23 13:12 Christopher J. PeBenito
  2007-05-23 13:12 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
  2007-05-23 13:24 ` selinux: add object class discovery v2 James Morris
  0 siblings, 2 replies; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 13:12 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux

Add support to SELinux for userland to discover object classes and their
permissions.  This patch set adds a class directory to the root of selinuxfs
and a tree of object classes and permissions, with the value for each of the
respective component.

-- 
Chris PeBenito
Tresys Technology, LLC
(410) 290-1411 x150

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-23 13:12 selinux: add object class discovery v2 Christopher J. PeBenito
@ 2007-05-23 13:12 ` Christopher J. PeBenito
  2007-05-23 13:12   ` [PATCH 2/4] selinux: rename sel_remove_bools() for more general usage Christopher J. PeBenito
  2007-05-23 15:42   ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy James Antill
  2007-05-23 13:24 ` selinux: add object class discovery v2 James Morris
  1 sibling, 2 replies; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 13:12 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux, Christopher J. PeBenito

From: Christopher J. PeBenito <cpebenito@tresys.com>

Add support to the SELinux security server for obtaining a list of classes,
and for obtaining a list of permissions for a specified class.

Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

---
 security/selinux/include/security.h |    3 +
 security/selinux/ss/services.c      |   95 +++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index b94378a..731a173 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -87,6 +87,9 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
 
 int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
+int security_get_classes(char ***classes, int *nclasses);
+int security_get_permissions(char *class, char ***perms, int *nperms);
+
 #define SECURITY_FS_USE_XATTR		1 /* use xattr */
 #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
 #define SECURITY_FS_USE_TASK		3 /* use task SIDs, e.g. pipefs/sockfs */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 40660ff..a1909bf 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1996,6 +1996,101 @@ out:
 	return rc;
 }
 
+static int get_classes_callback(void *k, void *d, void *args)
+{
+	struct class_datum *datum = d;
+	char *name = k, **classes = args;
+	int value = datum->value - 1;
+
+	classes[value] = kstrdup(name, GFP_ATOMIC);
+	if (!classes[value])
+		return -ENOMEM;
+
+	return 0;
+}
+
+int security_get_classes(char ***classes, int *nclasses)
+{
+	int rc = -ENOMEM;
+
+	POLICY_RDLOCK;
+
+	*nclasses = policydb.p_classes.nprim;
+	*classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC);
+	if (!*classes)
+		goto out;
+
+	rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
+			*classes);
+	if (rc < 0) {
+		int i;
+		for (i = 0; i < *nclasses; i++)
+			kfree((*classes)[i]);
+		kfree(*classes);
+	}
+	
+out:
+	POLICY_RDUNLOCK;
+	return rc;
+}
+
+static int get_permissions_callback(void *k, void *d, void *args)
+{
+	struct perm_datum *datum = d;
+	char *name = k, **perms = args;
+	int value = datum->value - 1;
+
+	perms[value] = kstrdup(name, GFP_ATOMIC);
+	if (!perms[value])
+		return -ENOMEM;
+
+	return 0;
+}
+
+int security_get_permissions(char *class, char ***perms, int *nperms)
+{
+	int rc = -ENOMEM, i;
+	struct class_datum *match;
+
+	POLICY_RDLOCK;
+
+	match = hashtab_search(policydb.p_classes.table, class);
+	if (!match) {
+		printk(KERN_ERR "%s:  unrecognized class %s\n",
+			__FUNCTION__, class);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	*nperms = match->permissions.nprim;
+	*perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
+	if (!*perms)
+		goto out;
+
+	if (match->comdatum) {
+		rc = hashtab_map(match->comdatum->permissions.table,
+				get_permissions_callback, *perms);
+		if (rc < 0)
+			goto err;
+	}
+
+	rc = hashtab_map(match->permissions.table, get_permissions_callback,
+			*perms);
+	if (rc < 0)
+		goto err;
+
+out:
+	POLICY_RDUNLOCK;
+	return rc;
+
+err:
+	POLICY_RDUNLOCK;
+	for (i = 0; i < *nperms; i++)
+		kfree((*perms)[i]);
+	kfree(*perms);
+	return rc;
+}
+
 struct selinux_audit_rule {
 	u32 au_seqno;
 	struct context au_ctxt;
-- 
1.5.1.6


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/4] selinux: rename sel_remove_bools() for more general usage.
  2007-05-23 13:12 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
@ 2007-05-23 13:12   ` Christopher J. PeBenito
  2007-05-23 13:12     ` [PATCH 3/4] selinux: change sel_make_dir() to specify inode counter Christopher J. PeBenito
  2007-05-23 15:42   ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy James Antill
  1 sibling, 1 reply; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 13:12 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux, Christopher J. PeBenito

From: Christopher J. PeBenito <cpebenito@tresys.com>

sel_remove_bools() will also be used by the object class discovery, rename
it for more general use.

Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

---
 security/selinux/selinuxfs.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 98af83f..9c7b6ef 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -940,9 +940,8 @@ static const struct file_operations sel_commit_bools_ops = {
 	.write          = sel_commit_bools_write,
 };
 
-/* delete booleans - partial revoke() from
- * fs/proc/generic.c proc_kill_inodes */
-static void sel_remove_bools(struct dentry *de)
+/* partial revoke() from fs/proc/generic.c proc_kill_inodes */
+static void sel_remove_entries(struct dentry *de)
 {
 	struct list_head *p, *node;
 	struct super_block *sb = de->d_sb;
@@ -998,7 +997,7 @@ static int sel_make_bools(void)
 	kfree(bool_pending_values);
 	bool_pending_values = NULL;
 
-	sel_remove_bools(dir);
+	sel_remove_entries(dir);
 
 	if (!(page = (char*)get_zeroed_page(GFP_KERNEL)))
 		return -ENOMEM;
@@ -1048,7 +1047,7 @@ out:
 	return ret;
 err:
 	kfree(values);
-	sel_remove_bools(dir);
+	sel_remove_entries(dir);
 	ret = -ENOMEM;
 	goto out;
 }
-- 
1.5.1.6


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] selinux: change sel_make_dir() to specify inode counter.
  2007-05-23 13:12   ` [PATCH 2/4] selinux: rename sel_remove_bools() for more general usage Christopher J. PeBenito
@ 2007-05-23 13:12     ` Christopher J. PeBenito
  2007-05-23 13:12       ` [PATCH 4/4] selinux: add selinuxfs structure for object class discovery Christopher J. PeBenito
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 13:12 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux, Christopher J. PeBenito

From: Christopher J. PeBenito <cpebenito@tresys.com>

Specify the inode counter explicitly in sel_make_dir(), rather than always
using sel_last_ino.

Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

---
 security/selinux/selinuxfs.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 9c7b6ef..95051b1 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1293,7 +1293,8 @@ out:
 	return ret;
 }
 
-static int sel_make_dir(struct inode *dir, struct dentry *dentry)
+static int sel_make_dir(struct inode *dir, struct dentry *dentry,
+			unsigned long *ino)
 {
 	int ret = 0;
 	struct inode *inode;
@@ -1305,7 +1306,7 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry)
 	}
 	inode->i_op = &simple_dir_inode_operations;
 	inode->i_fop = &simple_dir_operations;
-	inode->i_ino = ++sel_last_ino;
+	inode->i_ino = ++(*ino);
 	/* directory inodes start off with i_nlink == 2 (for "." entry) */
 	inc_nlink(inode);
 	d_add(dentry, inode);
@@ -1351,7 +1352,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 		goto err;
 	}
 
-	ret = sel_make_dir(root_inode, dentry);
+	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
 	if (ret)
 		goto err;
 
@@ -1384,7 +1385,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 		goto err;
 	}
 
-	ret = sel_make_dir(root_inode, dentry);
+	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
 	if (ret)
 		goto err;
 
@@ -1398,7 +1399,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 		goto err;
 	}
 
-	ret = sel_make_dir(root_inode, dentry);
+	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
 	if (ret)
 		goto err;
 
-- 
1.5.1.6


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] selinux: add selinuxfs structure for object class discovery
  2007-05-23 13:12     ` [PATCH 3/4] selinux: change sel_make_dir() to specify inode counter Christopher J. PeBenito
@ 2007-05-23 13:12       ` Christopher J. PeBenito
  2007-05-30 15:06         ` Stephen Smalley
  0 siblings, 1 reply; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 13:12 UTC (permalink / raw)
  To: sds, jmorris, eparis; +Cc: selinux, Christopher J. PeBenito

From: Christopher J. PeBenito <cpebenito@tresys.com>

The structure is as follows (relative to selinuxfs root):

/class/file/index
/class/file/perms/read
/class/file/perms/write
...

Each class is allocated 33 inodes, 1 for the class index and 32 for
permissions.  Relative to SEL_CLASS_INO_OFFSET, the inode of the index file
DIV 33 is the class number.  The inode of the permission file % 33 is the
index of the permission for that class.

Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

---
 security/selinux/include/security.h |    1 +
 security/selinux/selinuxfs.c        |  249 +++++++++++++++++++++++++++++++++++
 2 files changed, 250 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 731a173..83bdd4d 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -41,6 +41,7 @@ extern int selinux_mls_enabled;
 
 int security_load_policy(void * data, size_t len);
 
+#define SEL_VEC_MAX 32
 struct av_decision {
 	u32 allowed;
 	u32 decided;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 95051b1..8be9706 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -67,6 +67,10 @@ static struct dentry *bool_dir = NULL;
 static int bool_num = 0;
 static int *bool_pending_values = NULL;
 
+/* global data for classes */
+static struct dentry *class_dir = NULL;
+static unsigned long last_class_ino;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -106,6 +110,7 @@ static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
 #define SEL_INITCON_INO_OFFSET 	0x01000000
 #define SEL_BOOL_INO_OFFSET	0x02000000
+#define SEL_CLASS_INO_OFFSET	0x04000000
 #define SEL_INO_MASK		0x00ffffff
 
 #define TMPBUFLEN	12
@@ -237,6 +242,11 @@ static const struct file_operations sel_policyvers_ops = {
 
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
+static int sel_make_classes(void);
+
+/* declaration for sel_make_class_dirs */
+static int sel_make_dir(struct inode *dir, struct dentry *dentry,
+			unsigned long *ino);
 
 static ssize_t sel_read_mls(struct file *filp, char __user *buf,
 				size_t count, loff_t *ppos)
@@ -287,10 +297,18 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
 		goto out;
 
 	ret = sel_make_bools();
+	if (ret) {
+		length = ret;
+		goto out1;
+	}
+
+	ret = sel_make_classes();
 	if (ret)
 		length = ret;
 	else
 		length = count;
+
+out1:
 	audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
 		"policy loaded auid=%u",
 		audit_get_loginuid(current->audit_context));
@@ -1293,6 +1311,225 @@ out:
 	return ret;
 }
 
+static inline unsigned int sel_div(unsigned long a, unsigned long b)
+{
+	return a / b - (a % b < 0);
+}
+
+static inline unsigned long sel_class_to_ino(u16 class)
+{
+	return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
+}
+
+static inline u16 sel_ino_to_class(unsigned long ino)
+{
+	return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
+}
+
+static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
+{
+	return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
+}
+
+static inline u32 sel_ino_to_perm(unsigned long ino)
+{
+	return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
+}
+
+static ssize_t sel_read_class(struct file * file, char __user *buf, 
+				size_t count, loff_t *ppos)
+{
+	ssize_t rc, len;
+	char *page;
+	unsigned long ino = file->f_path.dentry->d_inode->i_ino;
+
+	page = (char *)__get_free_page(GFP_KERNEL);
+	if (!page) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
+	rc = simple_read_from_buffer(buf, count, ppos, page, len);
+	free_page((unsigned long)page);
+out:
+	return rc;
+}
+
+static const struct file_operations sel_class_ops = {
+	.read		= sel_read_class,
+};
+
+static ssize_t sel_read_perm(struct file * file, char __user *buf, 
+				size_t count, loff_t *ppos)
+{
+	ssize_t rc, len;
+	char *page;
+	unsigned long ino = file->f_path.dentry->d_inode->i_ino;
+
+	page = (char *)__get_free_page(GFP_KERNEL);
+	if (!page) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	len = snprintf(page, PAGE_SIZE,"%d", sel_ino_to_perm(ino));
+	rc = simple_read_from_buffer(buf, count, ppos, page, len);
+	free_page((unsigned long)page);
+out:
+	return rc;
+}
+
+static const struct file_operations sel_perm_ops = {
+	.read		= sel_read_perm,
+};
+
+static int sel_make_perm_files(char *objclass, int classvalue,
+				struct dentry *dir)
+{
+	int i, rc = 0, nperms;
+	char **perms;
+
+	rc = security_get_permissions(objclass, &perms, &nperms);
+	if (rc)
+		goto out;
+
+	for (i = 0; i < nperms; i++) {
+		struct inode *inode;
+		struct dentry *dentry;
+
+		dentry = d_alloc_name(dir, perms[i]);
+		if (!dentry) {
+			rc = -ENOMEM;
+			goto out1;
+		}
+
+		inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
+		if (!inode) {
+			rc = -ENOMEM;
+			goto out1;
+		}
+		inode->i_fop = &sel_perm_ops;
+		/* i+1 since perm values are 1-indexed */
+		inode->i_ino = sel_perm_to_ino(classvalue, i+1);
+		d_add(dentry, inode);
+	}
+
+out1:
+	for (i = 0; i < nperms; i++)
+		kfree(perms[i]);
+	kfree(perms);
+out:
+	return rc;
+}
+
+static int sel_make_class_dir_entries(char *classname, int index,
+					struct dentry *dir)
+{
+	struct dentry *dentry = NULL;
+	struct inode *inode = NULL;
+	int rc;
+
+	dentry = d_alloc_name(dir, "index");
+	if (!dentry) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
+	if (!inode) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	inode->i_fop = &sel_class_ops;
+	inode->i_ino = sel_class_to_ino(index);
+	d_add(dentry, inode);
+
+	dentry = d_alloc_name(dir, "perms");
+	if (!dentry) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
+	if (rc)
+		goto out;
+
+	rc = sel_make_perm_files(classname, index, dentry);
+
+out:
+	return rc;
+}
+
+static void sel_remove_classes(void)
+{
+	struct list_head *class_node;
+
+	list_for_each(class_node, &class_dir->d_subdirs) {
+		struct dentry *class_subdir = list_entry(class_node,
+					struct dentry, d_u.d_child);
+		struct list_head *class_subdir_node;
+
+		list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
+			struct dentry *d = list_entry(class_subdir_node,
+						struct dentry, d_u.d_child);
+
+			if (d->d_inode)
+				if (d->d_inode->i_mode & S_IFDIR)
+					sel_remove_entries(d);
+		}
+
+		sel_remove_entries(class_subdir);
+	}
+
+	sel_remove_entries(class_dir);
+}
+
+static int sel_make_classes(void)
+{
+	int rc = 0, nclasses, i;
+	char **classes;
+
+	/* delete any existing entries */
+	sel_remove_classes();
+
+	rc = security_get_classes(&classes, &nclasses);
+	if (rc < 0)
+		goto out;
+
+	/* +2 since classes are 1-indexed */
+	last_class_ino = sel_class_to_ino(nclasses+2);
+
+	for (i = 0; i < nclasses; i++) {
+		struct dentry *class_name_dir;
+
+		class_name_dir = d_alloc_name(class_dir, classes[i]);
+		if (!class_name_dir) {
+			rc = -ENOMEM;
+			goto out1;
+		}
+
+		rc = sel_make_dir(class_dir->d_inode, class_name_dir,
+				&last_class_ino);
+		if (rc)
+			goto out1;
+
+		/* i+1 since class values are 1-indexed */
+		rc = sel_make_class_dir_entries(classes[i], i+1,
+				class_name_dir);
+		if (rc)
+			goto out1;
+	}
+
+out1:
+	for (i = 0; i < nclasses; i++)
+		kfree(classes[i]);
+	kfree(classes);
+out:
+	return rc;
+}
+
 static int sel_make_dir(struct inode *dir, struct dentry *dentry,
 			unsigned long *ino)
 {
@@ -1407,6 +1644,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 	if (ret)
 		goto err;
 
+	dentry = d_alloc_name(sb->s_root, "class");
+	if (!dentry) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
+	if (ret)
+		goto err;
+
+	class_dir = dentry;
+
 out:
 	return ret;
 err:
-- 
1.5.1.6


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: selinux: add object class discovery v2
  2007-05-23 13:12 selinux: add object class discovery v2 Christopher J. PeBenito
  2007-05-23 13:12 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
@ 2007-05-23 13:24 ` James Morris
  1 sibling, 0 replies; 12+ messages in thread
From: James Morris @ 2007-05-23 13:24 UTC (permalink / raw)
  To: Christopher J. PeBenito; +Cc: sds, jmorris, eparis, selinux

On Wed, 23 May 2007, Christopher J. PeBenito wrote:

> Add support to SELinux for userland to discover object classes and their
> permissions.  This patch set adds a class directory to the root of selinuxfs
> and a tree of object classes and permissions, with the value for each of the
> respective component.

Looks good.  I'll do some testing & wait for an ack from Stephen.


-- 
James Morris
<jmorris@namei.org>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-23 13:12 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
  2007-05-23 13:12   ` [PATCH 2/4] selinux: rename sel_remove_bools() for more general usage Christopher J. PeBenito
@ 2007-05-23 15:42   ` James Antill
  2007-05-23 17:25     ` Christopher J. PeBenito
  1 sibling, 1 reply; 12+ messages in thread
From: James Antill @ 2007-05-23 15:42 UTC (permalink / raw)
  To: Christopher J. PeBenito; +Cc: sds, jmorris, eparis, selinux

[-- Attachment #1: Type: text/plain, Size: 1432 bytes --]

On Wed, 2007-05-23 at 09:12 -0400, Christopher J. PeBenito wrote:
> 
> +static int get_permissions_callback(void *k, void *d, void *args)
> +{
> +       struct perm_datum *datum = d;
> +       char *name = k, **perms = args;
> +       int value = datum->value - 1;
> +
> +       perms[value] = kstrdup(name, GFP_ATOMIC);
> +       if (!perms[value])
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +int security_get_permissions(char *class, char ***perms, int *nperms)
> +{
[...]
> +       *nperms = match->permissions.nprim;
> +       *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
> +       if (!*perms)
> +               goto out;
> +
> +       if (match->comdatum) {
> +               rc = hashtab_map(match->comdatum->permissions.table,
> +                               get_permissions_callback, *perms);
> +               if (rc < 0)
> +                       goto err;
> +       }
> +
> +       rc = hashtab_map(match->permissions.table, get_permissions_callback,
> +                       *perms);


 So I'm probably just wasting your time out of ignorance here, but this
looks really suspicious to me. Why don't you need to add in
match->comdatum->permissions.nprim for the allocation? Also how is it
guaranteed that one "datum->value - 1" won't be the same in both
hashtabs? (if it isn't you've leaked memory).

-- 
James Antill <jantill@redhat.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy
  2007-05-23 15:42   ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy James Antill
@ 2007-05-23 17:25     ` Christopher J. PeBenito
  0 siblings, 0 replies; 12+ messages in thread
From: Christopher J. PeBenito @ 2007-05-23 17:25 UTC (permalink / raw)
  To: James Antill; +Cc: sds, jmorris, eparis, selinux

On Wed, 2007-05-23 at 11:42 -0400, James Antill wrote:
> On Wed, 2007-05-23 at 09:12 -0400, Christopher J. PeBenito wrote:
> > 
> > +static int get_permissions_callback(void *k, void *d, void *args)
> > +{
> > +       struct perm_datum *datum = d;
> > +       char *name = k, **perms = args;
> > +       int value = datum->value - 1;
> > +
> > +       perms[value] = kstrdup(name, GFP_ATOMIC);
> > +       if (!perms[value])
> > +               return -ENOMEM;
> > +
> > +       return 0;
> > +}
> > +
> > +int security_get_permissions(char *class, char ***perms, int *nperms)
> > +{
> [...]
> > +       *nperms = match->permissions.nprim;
> > +       *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC);
> > +       if (!*perms)
> > +               goto out;
> > +
> > +       if (match->comdatum) {
> > +               rc = hashtab_map(match->comdatum->permissions.table,
> > +                               get_permissions_callback, *perms);
> > +               if (rc < 0)
> > +                       goto err;
> > +       }
> > +
> > +       rc = hashtab_map(match->permissions.table, get_permissions_callback,
> > +                       *perms);
> 
> 
>  So I'm probably just wasting your time out of ignorance here, but this
> looks really suspicious to me. Why don't you need to add in
> match->comdatum->permissions.nprim for the allocation?

match->permissions.nprim already includes
match->comdatum->permissions.nprim, see:

http://marc.info/?l=selinux&m=117517987105068&w=2

>  Also how is it
> guaranteed that one "datum->value - 1" won't be the same in both
> hashtabs? (if it isn't you've leaked memory).

If I understand what you're saying, then we would have a common
permission and a unique permission with the same value, which isn't
possible.

-- 
Chris PeBenito
Tresys Technology, LLC
(410) 290-1411 x150


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] selinux: add selinuxfs structure for object class discovery
  2007-05-23 13:12       ` [PATCH 4/4] selinux: add selinuxfs structure for object class discovery Christopher J. PeBenito
@ 2007-05-30 15:06         ` Stephen Smalley
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Smalley @ 2007-05-30 15:06 UTC (permalink / raw)
  To: Christopher J. PeBenito; +Cc: jmorris, eparis, selinux

On Wed, 2007-05-23 at 09:12 -0400, Christopher J. PeBenito wrote:
> From: Christopher J. PeBenito <cpebenito@tresys.com>
> 
> The structure is as follows (relative to selinuxfs root):
> 
> /class/file/index
> /class/file/perms/read
> /class/file/perms/write
> ...
> 
> Each class is allocated 33 inodes, 1 for the class index and 32 for
> permissions.  Relative to SEL_CLASS_INO_OFFSET, the inode of the index file
> DIV 33 is the class number.  The inode of the permission file % 33 is the
> index of the permission for that class.
> 
> Signed-off-by: Christopher J. PeBenito <cpebenito@tresys.com>

For all four patches:
Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>

> 
> ---
>  security/selinux/include/security.h |    1 +
>  security/selinux/selinuxfs.c        |  249 +++++++++++++++++++++++++++++++++++
>  2 files changed, 250 insertions(+), 0 deletions(-)
> 
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 731a173..83bdd4d 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -41,6 +41,7 @@ extern int selinux_mls_enabled;
>  
>  int security_load_policy(void * data, size_t len);
>  
> +#define SEL_VEC_MAX 32
>  struct av_decision {
>  	u32 allowed;
>  	u32 decided;
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 95051b1..8be9706 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -67,6 +67,10 @@ static struct dentry *bool_dir = NULL;
>  static int bool_num = 0;
>  static int *bool_pending_values = NULL;
>  
> +/* global data for classes */
> +static struct dentry *class_dir = NULL;
> +static unsigned long last_class_ino;
> +
>  extern void selnl_notify_setenforce(int val);
>  
>  /* Check whether a task is allowed to use a security operation. */
> @@ -106,6 +110,7 @@ static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
>  
>  #define SEL_INITCON_INO_OFFSET 	0x01000000
>  #define SEL_BOOL_INO_OFFSET	0x02000000
> +#define SEL_CLASS_INO_OFFSET	0x04000000
>  #define SEL_INO_MASK		0x00ffffff
>  
>  #define TMPBUFLEN	12
> @@ -237,6 +242,11 @@ static const struct file_operations sel_policyvers_ops = {
>  
>  /* declaration for sel_write_load */
>  static int sel_make_bools(void);
> +static int sel_make_classes(void);
> +
> +/* declaration for sel_make_class_dirs */
> +static int sel_make_dir(struct inode *dir, struct dentry *dentry,
> +			unsigned long *ino);
>  
>  static ssize_t sel_read_mls(struct file *filp, char __user *buf,
>  				size_t count, loff_t *ppos)
> @@ -287,10 +297,18 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
>  		goto out;
>  
>  	ret = sel_make_bools();
> +	if (ret) {
> +		length = ret;
> +		goto out1;
> +	}
> +
> +	ret = sel_make_classes();
>  	if (ret)
>  		length = ret;
>  	else
>  		length = count;
> +
> +out1:
>  	audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
>  		"policy loaded auid=%u",
>  		audit_get_loginuid(current->audit_context));
> @@ -1293,6 +1311,225 @@ out:
>  	return ret;
>  }
>  
> +static inline unsigned int sel_div(unsigned long a, unsigned long b)
> +{
> +	return a / b - (a % b < 0);
> +}
> +
> +static inline unsigned long sel_class_to_ino(u16 class)
> +{
> +	return (class * (SEL_VEC_MAX + 1)) | SEL_CLASS_INO_OFFSET;
> +}
> +
> +static inline u16 sel_ino_to_class(unsigned long ino)
> +{
> +	return sel_div(ino & SEL_INO_MASK, SEL_VEC_MAX + 1);
> +}
> +
> +static inline unsigned long sel_perm_to_ino(u16 class, u32 perm)
> +{
> +	return (class * (SEL_VEC_MAX + 1) + perm) | SEL_CLASS_INO_OFFSET;
> +}
> +
> +static inline u32 sel_ino_to_perm(unsigned long ino)
> +{
> +	return (ino & SEL_INO_MASK) % (SEL_VEC_MAX + 1);
> +}
> +
> +static ssize_t sel_read_class(struct file * file, char __user *buf, 
> +				size_t count, loff_t *ppos)
> +{
> +	ssize_t rc, len;
> +	char *page;
> +	unsigned long ino = file->f_path.dentry->d_inode->i_ino;
> +
> +	page = (char *)__get_free_page(GFP_KERNEL);
> +	if (!page) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
> +	rc = simple_read_from_buffer(buf, count, ppos, page, len);
> +	free_page((unsigned long)page);
> +out:
> +	return rc;
> +}
> +
> +static const struct file_operations sel_class_ops = {
> +	.read		= sel_read_class,
> +};
> +
> +static ssize_t sel_read_perm(struct file * file, char __user *buf, 
> +				size_t count, loff_t *ppos)
> +{
> +	ssize_t rc, len;
> +	char *page;
> +	unsigned long ino = file->f_path.dentry->d_inode->i_ino;
> +
> +	page = (char *)__get_free_page(GFP_KERNEL);
> +	if (!page) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	len = snprintf(page, PAGE_SIZE,"%d", sel_ino_to_perm(ino));
> +	rc = simple_read_from_buffer(buf, count, ppos, page, len);
> +	free_page((unsigned long)page);
> +out:
> +	return rc;
> +}
> +
> +static const struct file_operations sel_perm_ops = {
> +	.read		= sel_read_perm,
> +};
> +
> +static int sel_make_perm_files(char *objclass, int classvalue,
> +				struct dentry *dir)
> +{
> +	int i, rc = 0, nperms;
> +	char **perms;
> +
> +	rc = security_get_permissions(objclass, &perms, &nperms);
> +	if (rc)
> +		goto out;
> +
> +	for (i = 0; i < nperms; i++) {
> +		struct inode *inode;
> +		struct dentry *dentry;
> +
> +		dentry = d_alloc_name(dir, perms[i]);
> +		if (!dentry) {
> +			rc = -ENOMEM;
> +			goto out1;
> +		}
> +
> +		inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
> +		if (!inode) {
> +			rc = -ENOMEM;
> +			goto out1;
> +		}
> +		inode->i_fop = &sel_perm_ops;
> +		/* i+1 since perm values are 1-indexed */
> +		inode->i_ino = sel_perm_to_ino(classvalue, i+1);
> +		d_add(dentry, inode);
> +	}
> +
> +out1:
> +	for (i = 0; i < nperms; i++)
> +		kfree(perms[i]);
> +	kfree(perms);
> +out:
> +	return rc;
> +}
> +
> +static int sel_make_class_dir_entries(char *classname, int index,
> +					struct dentry *dir)
> +{
> +	struct dentry *dentry = NULL;
> +	struct inode *inode = NULL;
> +	int rc;
> +
> +	dentry = d_alloc_name(dir, "index");
> +	if (!dentry) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
> +	if (!inode) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	inode->i_fop = &sel_class_ops;
> +	inode->i_ino = sel_class_to_ino(index);
> +	d_add(dentry, inode);
> +
> +	dentry = d_alloc_name(dir, "perms");
> +	if (!dentry) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
> +	if (rc)
> +		goto out;
> +
> +	rc = sel_make_perm_files(classname, index, dentry);
> +
> +out:
> +	return rc;
> +}
> +
> +static void sel_remove_classes(void)
> +{
> +	struct list_head *class_node;
> +
> +	list_for_each(class_node, &class_dir->d_subdirs) {
> +		struct dentry *class_subdir = list_entry(class_node,
> +					struct dentry, d_u.d_child);
> +		struct list_head *class_subdir_node;
> +
> +		list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
> +			struct dentry *d = list_entry(class_subdir_node,
> +						struct dentry, d_u.d_child);
> +
> +			if (d->d_inode)
> +				if (d->d_inode->i_mode & S_IFDIR)
> +					sel_remove_entries(d);
> +		}
> +
> +		sel_remove_entries(class_subdir);
> +	}
> +
> +	sel_remove_entries(class_dir);
> +}
> +
> +static int sel_make_classes(void)
> +{
> +	int rc = 0, nclasses, i;
> +	char **classes;
> +
> +	/* delete any existing entries */
> +	sel_remove_classes();
> +
> +	rc = security_get_classes(&classes, &nclasses);
> +	if (rc < 0)
> +		goto out;
> +
> +	/* +2 since classes are 1-indexed */
> +	last_class_ino = sel_class_to_ino(nclasses+2);
> +
> +	for (i = 0; i < nclasses; i++) {
> +		struct dentry *class_name_dir;
> +
> +		class_name_dir = d_alloc_name(class_dir, classes[i]);
> +		if (!class_name_dir) {
> +			rc = -ENOMEM;
> +			goto out1;
> +		}
> +
> +		rc = sel_make_dir(class_dir->d_inode, class_name_dir,
> +				&last_class_ino);
> +		if (rc)
> +			goto out1;
> +
> +		/* i+1 since class values are 1-indexed */
> +		rc = sel_make_class_dir_entries(classes[i], i+1,
> +				class_name_dir);
> +		if (rc)
> +			goto out1;
> +	}
> +
> +out1:
> +	for (i = 0; i < nclasses; i++)
> +		kfree(classes[i]);
> +	kfree(classes);
> +out:
> +	return rc;
> +}
> +
>  static int sel_make_dir(struct inode *dir, struct dentry *dentry,
>  			unsigned long *ino)
>  {
> @@ -1407,6 +1644,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
>  	if (ret)
>  		goto err;
>  
> +	dentry = d_alloc_name(sb->s_root, "class");
> +	if (!dentry) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
> +	if (ret)
> +		goto err;
> +
> +	class_dir = dentry;
> +
>  out:
>  	return ret;
>  err:
-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2007-05-30 15:06 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-23 13:12 selinux: add object class discovery v2 Christopher J. PeBenito
2007-05-23 13:12 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
2007-05-23 13:12   ` [PATCH 2/4] selinux: rename sel_remove_bools() for more general usage Christopher J. PeBenito
2007-05-23 13:12     ` [PATCH 3/4] selinux: change sel_make_dir() to specify inode counter Christopher J. PeBenito
2007-05-23 13:12       ` [PATCH 4/4] selinux: add selinuxfs structure for object class discovery Christopher J. PeBenito
2007-05-30 15:06         ` Stephen Smalley
2007-05-23 15:42   ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy James Antill
2007-05-23 17:25     ` Christopher J. PeBenito
2007-05-23 13:24 ` selinux: add object class discovery v2 James Morris
  -- strict thread matches above, loose matches on Subject: below --
2007-05-21 15:38 [PATCH 0/4] selinux: add object class discovery Christopher J. PeBenito
2007-05-21 15:38 ` [PATCH 1/4] selinux: add support for querying object classes and permissions from the running policy Christopher J. PeBenito
2007-05-21 17:02   ` James Morris
2007-05-21 18:44     ` Christopher J. PeBenito

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.