All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] libselinux: class and permission mapping support
@ 2007-06-06 15:42 Eamon Walsh
  2007-06-06 15:45 ` Joshua Brindle
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-06 15:42 UTC (permalink / raw)
  To: SE Linux; +Cc: Stephen Smalley, Joshua Brindle, Christopher J. PeBenito

This provides support for userspace object managers to register a
mapping of class and permission values.  After the mapping is
registered all libselinux functions that take a security class
or permission value must be provided with mapped values instead
of the "real," kernel values.

Changes from the original interface proposal: No selinux_init()
function, just a straight set_mapping() function.  Also, to
simplify things the incoming mapping does not include explicit
values; the classes and permissions are numbered implicitly by
their ordering.  NULL strings are used to terminate the lists.

Tested with X server, no problems encountered.

This patch includes the interface and implementation of the
mapping set function.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---

 include/selinux/selinux.h |    8 +++++
 src/mapping.c             |   67 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

Index: libselinux/include/selinux/selinux.h
===================================================================
--- libselinux/include/selinux/selinux.h	(revision 2464)
+++ libselinux/include/selinux/selinux.h	(working copy)
@@ -280,6 +280,14 @@
 /* Commit the pending values for the booleans */
 extern int security_commit_booleans(void);
 
+/* Userspace class mapping support */
+struct security_class_mapping {
+	const char *name;
+	const char *perms[sizeof(access_vector_t) * 8 + 1];
+};
+
+int selinux_set_mapping(struct security_class_mapping *map);
+
 /* Common helpers */
 
 /* Convert between security class values and string names */
Index: libselinux/src/mapping.c
===================================================================
--- libselinux/src/mapping.c	(revision 0)
+++ libselinux/src/mapping.c	(revision 0)
@@ -0,0 +1,67 @@
+/*
+ * Class and permission mappings.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <selinux/selinux.h>
+#include "mapping.h"
+
+/* class and permission mappings */
+struct selinux_mapping *current_mapping = NULL;
+security_class_t current_mapping_size = 0;
+
+/* mapping setting function */
+int
+selinux_set_mapping(struct security_class_mapping *map)
+{
+	size_t size = sizeof(struct selinux_mapping);
+	security_class_t i, j;
+	unsigned k;
+
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+
+	/* Find number of classes in the input mapping plus one */
+	i = 1;
+	while (map && map[i-1].name)
+		i++;
+
+	/* Allocate space for the class records */
+	current_mapping = (struct selinux_mapping *)calloc(i, size);
+	if (!current_mapping)
+		goto err;
+
+	/* Store the raw class and permission values */
+	j = 0;
+	while (map && map[j].name) {
+		struct security_class_mapping *p_in = map + (j++);
+		struct selinux_mapping *p_out = current_mapping + j;
+
+		p_out->value = string_to_security_class(p_in->name);
+		if (!p_out->value)
+			goto err2;
+
+		k = 0;
+		while (p_in->perms && p_in->perms[k]) {
+			p_out->perms[k] = string_to_av_perm(p_out->value,
+							    p_in->perms[k]);
+			if (!p_out->perms[k])
+				goto err2;
+			k++;
+		}
+		p_out->num_perms = k;
+	}
+
+	/* Set the mapping size here so the above lookups are "raw" */
+	current_mapping_size = i;
+	return 0;
+err2:
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+err:
+	return -1;
+}

-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* RE: [PATCH 1/2] libselinux: class and permission mapping support
  2007-06-06 15:42 [PATCH 1/2] libselinux: class and permission mapping support Eamon Walsh
@ 2007-06-06 15:45 ` Joshua Brindle
  2007-06-06 16:32   ` Eamon Walsh
  2007-06-06 15:59 ` Stephen Smalley
  2007-06-06 16:40 ` James Carter
  2 siblings, 1 reply; 13+ messages in thread
From: Joshua Brindle @ 2007-06-06 15:45 UTC (permalink / raw)
  To: Eamon Walsh, SE Linux; +Cc: Stephen Smalley, Christopher J. PeBenito

Eamon Walsh wrote:
> This provides support for userspace object managers to
> register a mapping of class and permission values.  After the
> mapping is registered all libselinux functions that take a
> security class or permission value must be provided with
> mapped values instead of the "real," kernel values.
> 
> Changes from the original interface proposal: No
> selinux_init() function, just a straight set_mapping()
> function.  Also, to simplify things the incoming mapping does
> not include explicit values; the classes and permissions are
> numbered implicitly by their ordering.  NULL strings are used
> to terminate the lists.
> 
> Tested with X server, no problems encountered.
> 
> This patch includes the interface and implementation of the mapping
> set function. 
> 

Hrm, I thought we agreed that remapping access vectors at runtime was a
bad idea?


--
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] 13+ messages in thread

* Re: [PATCH 1/2] libselinux: class and permission mapping support
  2007-06-06 15:42 [PATCH 1/2] libselinux: class and permission mapping support Eamon Walsh
  2007-06-06 15:45 ` Joshua Brindle
@ 2007-06-06 15:59 ` Stephen Smalley
  2007-06-06 16:24   ` Eamon Walsh
  2007-06-06 16:40 ` James Carter
  2 siblings, 1 reply; 13+ messages in thread
From: Stephen Smalley @ 2007-06-06 15:59 UTC (permalink / raw)
  To: Eamon Walsh; +Cc: SE Linux, Joshua Brindle, Christopher J. PeBenito

On Wed, 2007-06-06 at 11:42 -0400, Eamon Walsh wrote:
> This provides support for userspace object managers to register a
> mapping of class and permission values.  After the mapping is
> registered all libselinux functions that take a security class
> or permission value must be provided with mapped values instead
> of the "real," kernel values.
> 
> Changes from the original interface proposal: No selinux_init()
> function, just a straight set_mapping() function.  Also, to
> simplify things the incoming mapping does not include explicit
> values; the classes and permissions are numbered implicitly by
> their ordering.  NULL strings are used to terminate the lists.
> 
> Tested with X server, no problems encountered.
> 
> This patch includes the interface and implementation of the
> mapping set function.

Can you post a snippet of code from the X server showing the usage of
this interface by an object manager?

I was thinking that we weren't going down this route due to
complexity/performance concerns about having to remap the access vectors
on checks, but it doesn't look too bad from your patches, especially
since the mapping happens on compute_av and the AVC can just always use
the mapped values.

-- 
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] 13+ messages in thread

* Re: [PATCH 1/2] libselinux: class and permission mapping support
  2007-06-06 15:59 ` Stephen Smalley
@ 2007-06-06 16:24   ` Eamon Walsh
  0 siblings, 0 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-06 16:24 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: SE Linux, Joshua Brindle, Christopher J. PeBenito

Stephen Smalley wrote:
> On Wed, 2007-06-06 at 11:42 -0400, Eamon Walsh wrote:
>   
>> This provides support for userspace object managers to register a
>> mapping of class and permission values.  After the mapping is
>> registered all libselinux functions that take a security class
>> or permission value must be provided with mapped values instead
>> of the "real," kernel values.
>>
>> Changes from the original interface proposal: No selinux_init()
>> function, just a straight set_mapping() function.  Also, to
>> simplify things the incoming mapping does not include explicit
>> values; the classes and permissions are numbered implicitly by
>> their ordering.  NULL strings are used to terminate the lists.
>>
>> Tested with X server, no problems encountered.
>>
>> This patch includes the interface and implementation of the
>> mapping set function.
>>     
>
> Can you post a snippet of code from the X server showing the usage of
> this interface by an object manager

In a header file:

/* Private Flask definitions */
#define SECCLASS_DRAWABLE		1
#define DRAWABLE__CREATE		0x00000001UL
#define DRAWABLE__DESTROY		0x00000002UL
#define DRAWABLE__DRAW			0x00000004UL
#define DRAWABLE__COPY			0x00000008UL
#define DRAWABLE__GETATTR		0x00000010UL
#define SECCLASS_WINDOW			2
#define WINDOW__ADDCHILD		0x00000001UL
#define WINDOW__CREATE			0x00000002UL
#define WINDOW__DESTROY			0x00000004UL
#define WINDOW__MAP			0x00000008UL
#define WINDOW__UNMAP			0x00000010UL
#define WINDOW__CHSTACK			0x00000020UL
#define WINDOW__CHPROPLIST		0x00000040UL
#define WINDOW__CHPROP			0x00000080UL
#define WINDOW__LISTPROP		0x00000100UL
#define WINDOW__GETATTR			0x00000200UL
#define WINDOW__SETATTR			0x00000400UL
#define WINDOW__SETFOCUS		0x00000800UL
#define WINDOW__MOVE			0x00001000UL
#define WINDOW__CHSELECTION		0x00002000UL
#define WINDOW__CHPARENT		0x00004000UL
#define WINDOW__CTRLLIFE		0x00008000UL
#define WINDOW__ENUMERATE		0x00010000UL
#define WINDOW__TRANSPARENT		0x00020000UL
#define WINDOW__MOUSEMOTION		0x00040000UL
#define WINDOW__CLIENTCOMEVENT		0x00080000UL
#define WINDOW__INPUTEVENT		0x00100000UL
#define WINDOW__DRAWEVENT		0x00200000UL
#define WINDOW__WINDOWCHANGEEVENT	0x00400000UL
#define WINDOW__WINDOWCHANGEREQUEST	0x00800000UL
#define WINDOW__SERVERCHANGEEVENT	0x01000000UL
#define WINDOW__EXTENSIONEVENT		0x02000000UL
#define SECCLASS_GC			3
#define GC__CREATE			0x00000001UL
#define GC__FREE			0x00000002UL
#define GC__GETATTR			0x00000004UL
#define GC__SETATTR			0x00000008UL
#define SECCLASS_FONT			4
...


In the initialization code:

/* Dynamically allocated security classes and permissions */
/* Do not change these without changing the private Flask definitions */
static struct security_class_mapping map[] = {
    { "drawable",
      { "create", "destroy", "draw", "copy", "getattr", NULL }},
    { "window",
      { "addchild", "create", "destroy", "map", "unmap", "chstack",
	"chproplist", "chprop", "listprop", "getattr", "setattr", "setfocus",
	"move", "chselection", "chparent", "ctrllife", "enumerate",
	"transparent", "mousemotion", "clientcomevent", "inputevent",
	"drawevent", "windowchangeevent", "windowchangerequest",
	"serverchangeevent", "extensionevent", NULL }},
    { "gc",
      { "create", "free", "getattr", "setattr", NULL }},
    { "font",
      { "load", "free", "getattr", "use", NULL }},
    { "colormap",
      { "create", "free", "install", "uninstall", "list", "read", "store",
	"getattr", "setattr", NULL }},
    { "property",
      { "create", "free", "read", "write", NULL }},
    { "cursor",
      { "create", "createglyph", "free", "assign", "setattr", NULL }},
    { "xclient",
      { "kill", NULL }},
    { "xinput",
      { "lookup", "getattr", "setattr", "setfocus", "warppointer",
	"activegrab", "passivegrab", "ungrab", "bell", "mousemotion",
	"relabelinput", NULL }},
    { "xserver",
      { "screensaver", "gethostlist", "sethostlist", "getfontpath",
	"setfontpath", "getattr", "grab", "ungrab", NULL }},
    { "xextension",
      { "query", "use", NULL }},
    { NULL }
};

if (selinux_set_mapping(map) < 0) {
    FatalError("XSELinux: Failed to set up security class mapping\n");
}

That's it, no other changes.



-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* Re: [PATCH 1/2] libselinux: class and permission mapping support
  2007-06-06 15:45 ` Joshua Brindle
@ 2007-06-06 16:32   ` Eamon Walsh
  0 siblings, 0 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-06 16:32 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: SE Linux, Stephen Smalley, Christopher J. PeBenito

Joshua Brindle wrote:
> Eamon Walsh wrote:
>> This provides support for userspace object managers to
>> register a mapping of class and permission values.  After the
>> mapping is registered all libselinux functions that take a
>> security class or permission value must be provided with
>> mapped values instead of the "real," kernel values.
>>
>> Changes from the original interface proposal: No
>> selinux_init() function, just a straight set_mapping()
>> function.  Also, to simplify things the incoming mapping does
>> not include explicit values; the classes and permissions are
>> numbered implicitly by their ordering.  NULL strings are used
>> to terminate the lists.
>>
>> Tested with X server, no problems encountered.
>>
>> This patch includes the interface and implementation of the mapping
>> set function. 
>>
> 
> Hrm, I thought we agreed that remapping access vectors at runtime was a
> bad idea?
> 

I did think that initially, but I didn't realize that the mapping could 
be done underneath the AVC instead of on every single call to 
avc_has_perm or whatnot.

The overhead of the remapping should be negligible compared to the cost 
of an selinuxfs operation, right?  And it frees the userspace object 
manager from having to manage the translation tables itself.


-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* Re: [PATCH 1/2] libselinux: class and permission mapping support
  2007-06-06 15:42 [PATCH 1/2] libselinux: class and permission mapping support Eamon Walsh
  2007-06-06 15:45 ` Joshua Brindle
  2007-06-06 15:59 ` Stephen Smalley
@ 2007-06-06 16:40 ` James Carter
  2007-06-06 18:32   ` [PATCH 1/2] libselinux: class and permission mapping support (try 2) Eamon Walsh
  2007-06-06 18:34   ` [PATCH 2/2] " Eamon Walsh
  2 siblings, 2 replies; 13+ messages in thread
From: James Carter @ 2007-06-06 16:40 UTC (permalink / raw)
  To: Eamon Walsh
  Cc: SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

On Wed, 2007-06-06 at 11:42 -0400, Eamon Walsh wrote:
> This provides support for userspace object managers to register a
> mapping of class and permission values.  After the mapping is
> registered all libselinux functions that take a security class
> or permission value must be provided with mapped values instead
> of the "real," kernel values.
> 
> Changes from the original interface proposal: No selinux_init()
> function, just a straight set_mapping() function.  Also, to
> simplify things the incoming mapping does not include explicit
> values; the classes and permissions are numbered implicitly by
> their ordering.  NULL strings are used to terminate the lists.
> 
> Tested with X server, no problems encountered.
> 
> This patch includes the interface and implementation of the
> mapping set function.
> 
> Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
> ---
> 
>  include/selinux/selinux.h |    8 +++++
>  src/mapping.c             |   67 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 75 insertions(+)
> 
> Index: libselinux/include/selinux/selinux.h
> ===================================================================
> --- libselinux/include/selinux/selinux.h	(revision 2464)
> +++ libselinux/include/selinux/selinux.h	(working copy)
> @@ -280,6 +280,14 @@
>  /* Commit the pending values for the booleans */
>  extern int security_commit_booleans(void);
>  
> +/* Userspace class mapping support */
> +struct security_class_mapping {
> +	const char *name;
> +	const char *perms[sizeof(access_vector_t) * 8 + 1];
> +};
> +
> +int selinux_set_mapping(struct security_class_mapping *map);
> +
>  /* Common helpers */
>  
>  /* Convert between security class values and string names */
> Index: libselinux/src/mapping.c
> ===================================================================
> --- libselinux/src/mapping.c	(revision 0)
> +++ libselinux/src/mapping.c	(revision 0)
> @@ -0,0 +1,67 @@
> +/*
> + * Class and permission mappings.
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdarg.h>
> +#include <selinux/selinux.h>
> +#include "mapping.h"
> +
> +/* class and permission mappings */
> +struct selinux_mapping *current_mapping = NULL;
> +security_class_t current_mapping_size = 0;
> +
> +/* mapping setting function */
> +int
> +selinux_set_mapping(struct security_class_mapping *map)
> +{
> +	size_t size = sizeof(struct selinux_mapping);
> +	security_class_t i, j;
> +	unsigned k;
> +
> +	free(current_mapping);
> +	current_mapping = NULL;
> +	current_mapping_size = 0;
> +
> +	/* Find number of classes in the input mapping plus one */
> +	i = 1;
> +	while (map && map[i-1].name)
> +		i++;
> +
Shouldn't you check for map being NULL at the beginning?
if map == NULL, i = 1, ...

> +	/* Allocate space for the class records */
> +	current_mapping = (struct selinux_mapping *)calloc(i, size);
> +	if (!current_mapping)
> +		goto err;
> +
Now calloc is called with i = 1 ...

> +	/* Store the raw class and permission values */
> +	j = 0;
> +	while (map && map[j].name) {
> +		struct security_class_mapping *p_in = map + (j++);
> +		struct selinux_mapping *p_out = current_mapping + j;
> +
> +		p_out->value = string_to_security_class(p_in->name);
> +		if (!p_out->value)
> +			goto err2;
> +
> +		k = 0;
> +		while (p_in->perms && p_in->perms[k]) {
> +			p_out->perms[k] = string_to_av_perm(p_out->value,
> +							    p_in->perms[k]);
> +			if (!p_out->perms[k])
> +				goto err2;
> +			k++;
> +		}
> +		p_out->num_perms = k;
> +	}
> +
> +	/* Set the mapping size here so the above lookups are "raw" */
> +	current_mapping_size = i;
> +	return 0;
current_mapping_size = 1
return 0
for map == NULL

This doesn't seem like the correct behavior.

> +err2:
> +	free(current_mapping);
> +	current_mapping = NULL;
> +	current_mapping_size = 0;
> +err:
> +	return -1;
> +}
> 
-- 
James Carter <jwcart2@epoch.ncsc.mil>
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] 13+ messages in thread

* [PATCH 1/2] libselinux: class and permission mapping support (try 2)
  2007-06-06 16:40 ` James Carter
@ 2007-06-06 18:32   ` Eamon Walsh
  2007-06-06 18:34   ` [PATCH 2/2] " Eamon Walsh
  1 sibling, 0 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-06 18:32 UTC (permalink / raw)
  To: jwcart2; +Cc: SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

Changes from the first version: disallow a NULL mapping with
error EINVAL; add assert statements to the map/unmap helpers
to catch out-of-bounds value bugs in callers.

This provides support for userspace object managers to register a
mapping of class and permission values.  After the mapping is
registered all libselinux functions that take a security class
or permission value must be provided with mapped values instead
of the "real," kernel values.

Changes from the original interface proposal: No selinux_init()
function, just a straight set_mapping() function.  Also, to
simplify things the incoming mapping does not include explicit
values; the classes and permissions are numbered implicitly by
their ordering.  NULL strings are used to terminate the lists.

Tested with X server, no problems encountered.

This patch includes the interface and implementation of the
mapping set function.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---

 include/selinux/selinux.h |    8 +++++
 src/mapping.c             |   72 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

Index: libselinux/include/selinux/selinux.h
===================================================================
--- libselinux/include/selinux/selinux.h	(revision 2464)
+++ libselinux/include/selinux/selinux.h	(working copy)
@@ -280,6 +280,14 @@
 /* Commit the pending values for the booleans */
 extern int security_commit_booleans(void);
 
+/* Userspace class mapping support */
+struct security_class_mapping {
+	const char *name;
+	const char *perms[sizeof(access_vector_t) * 8 + 1];
+};
+
+int selinux_set_mapping(struct security_class_mapping *map);
+
 /* Common helpers */
 
 /* Convert between security class values and string names */
Index: libselinux/src/mapping.c
===================================================================
--- libselinux/src/mapping.c	(revision 0)
+++ libselinux/src/mapping.c	(revision 0)
@@ -0,0 +1,72 @@
+/*
+ * Class and permission mappings.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <selinux/selinux.h>
+#include "mapping.h"
+
+/* class and permission mappings */
+struct selinux_mapping *current_mapping = NULL;
+security_class_t current_mapping_size = 0;
+
+/* mapping setting function */
+int
+selinux_set_mapping(struct security_class_mapping *map)
+{
+	size_t size = sizeof(struct selinux_mapping);
+	security_class_t i, j;
+	unsigned k;
+
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+
+	/* Find number of classes in the input mapping */
+	if (!map) {
+		errno = EINVAL;
+		goto err;
+	}
+	i = 0;
+	while (map[i].name)
+		i++;
+
+	/* Allocate space for the class records, plus one for class zero */
+	current_mapping = (struct selinux_mapping *)calloc(++i, size);
+	if (!current_mapping)
+		goto err;
+
+	/* Store the raw class and permission values */
+	j = 0;
+	while (map[j].name) {
+		struct security_class_mapping *p_in = map + (j++);
+		struct selinux_mapping *p_out = current_mapping + j;
+
+		p_out->value = string_to_security_class(p_in->name);
+		if (!p_out->value)
+			goto err2;
+
+		k = 0;
+		while (p_in->perms && p_in->perms[k]) {
+			p_out->perms[k] = string_to_av_perm(p_out->value,
+							    p_in->perms[k]);
+			if (!p_out->perms[k])
+				goto err2;
+			k++;
+		}
+		p_out->num_perms = k;
+	}
+
+	/* Set the mapping size here so the above lookups are "raw" */
+	current_mapping_size = i;
+	return 0;
+err2:
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+err:
+	return -1;
+}



-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* [PATCH 2/2] libselinux: class and permission mapping support (try 2)
  2007-06-06 16:40 ` James Carter
  2007-06-06 18:32   ` [PATCH 1/2] libselinux: class and permission mapping support (try 2) Eamon Walsh
@ 2007-06-06 18:34   ` Eamon Walsh
  2007-06-07 14:18     ` Karl MacMillan
  1 sibling, 1 reply; 13+ messages in thread
From: Eamon Walsh @ 2007-06-06 18:34 UTC (permalink / raw)
  To: jwcart2; +Cc: SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

This patch includes the internal map and unmap functions and
the changes to the selinuxfs interfaces to make it work.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---

 compute_av.c      |    8 ++-
 compute_create.c  |    5 +-
 compute_member.c  |    5 +-
 compute_relabel.c |    5 +-
 mapping.h         |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 stringrep.c       |   17 +++++--
 6 files changed, 148 insertions(+), 13 deletions(-)

Index: libselinux/src/mapping.h
===================================================================
--- libselinux/src/mapping.h	(revision 0)
+++ libselinux/src/mapping.h	(revision 0)
@@ -0,0 +1,121 @@
+/*
+ * This file describes the class and permission mappings used to 
+ * hide the kernel numbers from userspace by allowing userspace object
+ * managers to specify a list of classes and permissions.
+ */
+#ifndef _SELINUX_MAPPING_H_
+#define _SELINUX_MAPPING_H_
+
+#include <assert.h>
+#include <selinux/selinux.h>
+
+struct selinux_mapping {
+	security_class_t value; /* real, kernel value */
+	unsigned num_perms;
+	access_vector_t perms[sizeof(access_vector_t) * 8];
+};
+
+extern struct selinux_mapping *current_mapping;
+extern security_class_t current_mapping_size;
+
+/*
+ * Get real, kernel values from mapped values
+ */
+
+static inline security_class_t
+unmap_class(security_class_t tclass)
+{
+	if (tclass < current_mapping_size)
+		return current_mapping[tclass].value;
+
+	assert(current_mapping_size == 0);
+	return tclass;
+}
+
+static inline access_vector_t
+unmap_perm(security_class_t tclass, access_vector_t tperm)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t kperm = 0;
+
+		for (i=0; i<current_mapping[tclass].num_perms; i++)
+			if (tperm & (1<<i)) {
+				kperm |= current_mapping[tclass].perms[i];
+				tperm &= ~(1<<i);
+			}
+		assert(tperm == 0);
+		return kperm;
+	}
+
+	assert(current_mapping_size == 0);
+	return tperm;
+}
+
+/*
+ * Get mapped values from real, kernel values
+ */
+
+static inline security_class_t
+map_class(security_class_t kclass)
+{
+	security_class_t i;
+
+	for (i=0; i<current_mapping_size; i++)
+		if (current_mapping[i].value == kclass)
+			return i;
+
+	assert(current_mapping_size == 0);
+	return kclass;
+}
+
+static inline access_vector_t
+map_perm(security_class_t tclass, access_vector_t kperm)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t tperm = 0;
+
+		for (i=0; i<current_mapping[tclass].num_perms; i++)
+			if (kperm & current_mapping[tclass].perms[i]) {
+				tperm |= 1<<i;
+				kperm &= ~current_mapping[tclass].perms[i];
+			}
+		assert(kperm == 0);
+		return tperm;
+	}
+
+	assert(current_mapping_size == 0);
+	return kperm;
+}
+
+static inline void
+map_decision(security_class_t tclass, struct av_decision *avd)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->allowed & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->allowed = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->decided & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->decided = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->auditallow & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->auditallow = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->auditdeny & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->auditdeny = result;
+	}
+}
+
+#endif				/* _SELINUX_MAPPING_H_ */
Index: libselinux/src/stringrep.c
===================================================================
--- libselinux/src/stringrep.c	(revision 2464)
+++ libselinux/src/stringrep.c	(working copy)
@@ -11,6 +11,7 @@
 #include <selinux/flask.h>
 #include <selinux/av_permissions.h>
 #include "selinux_internal.h"
+#include "mapping.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
@@ -151,12 +152,12 @@
 	if (isdigit(s[0])) {
 		val = atoi(s);
 		if (val > 0 && val < NCLASSES)
-			return val;
+			return map_class(val);
 	} else {
 		for (val = 0; val < NCLASSES; val++) {
 			if (strcmp(s, (class_to_string_data.str
 				       + class_to_string[val])) == 0)
-				return val;
+				return map_class(val);
 		}
 	}
 
@@ -169,9 +170,10 @@
 	const uint16_t *common_pts_idx = 0;
 	access_vector_t perm, common_base = 0;
 	unsigned int i;
+	security_class_t kclass = unmap_class(tclass);
 
 	for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
-		if (av_inherit[i].tclass == tclass) {
+		if (av_inherit[i].tclass == kclass) {
 			common_pts_idx =
 			    &common_perm_to_string.data[av_inherit[i].
 							common_pts_idx];
@@ -186,13 +188,13 @@
 		if (strcmp
 		    (s,
 		     common_perm_to_string_data.str + common_pts_idx[i]) == 0)
-			return perm;
+			return map_perm(tclass, perm);
 		perm <<= 1;
 		i++;
 	}
 
 	for (i = 0; i < NVECTORS; i++) {
-		if ((av_perm_to_string[i].tclass == tclass) &&
+		if ((av_perm_to_string[i].tclass == kclass) &&
 		    (strcmp(s, (av_perm_to_string_data.str
 				+ av_perm_to_string[i].nameidx)) == 0))
 			return av_perm_to_string[i].value;
@@ -204,6 +206,8 @@
 
 const char *security_class_to_string(security_class_t tclass)
 {
+	tclass = unmap_class(tclass);
+
 	if (tclass > 0 && tclass < NCLASSES)
 		return class_to_string_data.str + class_to_string[tclass];
 
@@ -218,6 +222,9 @@
 	access_vector_t common_base = 0;
 	unsigned int i;
 
+	av = unmap_perm(tclass, av);
+	tclass = unmap_class(tclass);
+
 	if (!av)
 		return NULL;
 
Index: libselinux/src/compute_av.c
===================================================================
--- libselinux/src/compute_av.c	(revision 2464)
+++ libselinux/src/compute_av.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_av_raw(security_context_t scon,
 			    security_context_t tcon,
@@ -36,7 +37,8 @@
 		goto out;
 	}
 
-	snprintf(buf, len, "%s %s %hu %x", scon, tcon, tclass, requested);
+	snprintf(buf, len, "%s %s %hu %x", scon, tcon,
+		 unmap_class(tclass), unmap_perm(tclass, requested));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
@@ -54,6 +56,8 @@
 		goto out2;
 	}
 
+	map_decision(tclass, avd);
+
 	ret = 0;
       out2:
 	free(buf);
Index: libselinux/src/compute_create.c
===================================================================
--- libselinux/src/compute_create.c	(revision 2464)
+++ libselinux/src/compute_create.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_create_raw(security_context_t scon,
 				security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
Index: libselinux/src/compute_member.c
===================================================================
--- libselinux/src/compute_member.c	(revision 2464)
+++ libselinux/src/compute_member.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_member_raw(security_context_t scon,
 				security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
Index: libselinux/src/compute_relabel.c
===================================================================
--- libselinux/src/compute_relabel.c	(revision 2464)
+++ libselinux/src/compute_relabel.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_relabel_raw(security_context_t scon,
 				 security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)

-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* Re: [PATCH 2/2] libselinux: class and permission mapping support (try 2)
  2007-06-06 18:34   ` [PATCH 2/2] " Eamon Walsh
@ 2007-06-07 14:18     ` Karl MacMillan
  2007-06-08 17:26       ` [PATCH 1/3] libselinux: class and permission mapping support (try 3) Eamon Walsh
                         ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Karl MacMillan @ 2007-06-07 14:18 UTC (permalink / raw)
  To: Eamon Walsh
  Cc: jwcart2, SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

On Wed, 2007-06-06 at 14:34 -0400, Eamon Walsh wrote:
> This patch includes the internal map and unmap functions and
> the changes to the selinuxfs interfaces to make it work.
> 
> Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
> ---
> 
>  compute_av.c      |    8 ++-
>  compute_create.c  |    5 +-
>  compute_member.c  |    5 +-
>  compute_relabel.c |    5 +-
>  mapping.h         |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  stringrep.c       |   17 +++++--
>  6 files changed, 148 insertions(+), 13 deletions(-)
> 
> Index: libselinux/src/mapping.h
> ===================================================================
> --- libselinux/src/mapping.h	(revision 0)
> +++ libselinux/src/mapping.h	(revision 0)
> @@ -0,0 +1,121 @@
> +/*
> + * This file describes the class and permission mappings used to 
> + * hide the kernel numbers from userspace by allowing userspace object
> + * managers to specify a list of classes and permissions.
> + */
> +#ifndef _SELINUX_MAPPING_H_
> +#define _SELINUX_MAPPING_H_
> +
> +#include <assert.h>
> +#include <selinux/selinux.h>
> +
> +struct selinux_mapping {
> +	security_class_t value; /* real, kernel value */
> +	unsigned num_perms;
> +	access_vector_t perms[sizeof(access_vector_t) * 8];
> +};

Should 8 be sizeof(access_vector_t)?

Karl


--
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] 13+ messages in thread

* [PATCH 1/3] libselinux: class and permission mapping support (try 3)
  2007-06-07 14:18     ` Karl MacMillan
@ 2007-06-08 17:26       ` Eamon Walsh
  2007-06-08 17:28       ` [PATCH 2/3] " Eamon Walsh
  2007-06-08 17:30       ` [PATCH 3/3] " Eamon Walsh
  2 siblings, 0 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-08 17:26 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: jwcart2, SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

Changes from the second version: rebase to object class discovery
patchset; flush the AVC when setting a mapping.

Changes from the first version: disallow a NULL mapping with
error EINVAL; add assert statements to the map/unmap helpers
to catch out-of-bounds value bugs in callers.

This provides support for userspace object managers to register a
mapping of class and permission values.  After the mapping is
registered all libselinux functions that take a security class
or permission value must be provided with mapped values instead
of the "real," kernel values.

Changes from the original interface proposal: No selinux_init()
function, just a straight set_mapping() function.  Also, to
simplify things the incoming mapping does not include explicit
values; the classes and permissions are numbered implicitly by
their ordering.  NULL strings are used to terminate the lists.

Tested with X server, no problems encountered.

This patch includes the interface and implementation of the
mapping set function.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---

 include/selinux/selinux.h |    8 +
 src/mapping.c             |  189 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 197 insertions(+)


Index: libselinux/include/selinux/selinux.h
===================================================================
--- libselinux/include/selinux/selinux.h	(revision 2470)
+++ libselinux/include/selinux/selinux.h	(working copy)
@@ -280,6 +280,14 @@
 /* Commit the pending values for the booleans */
 extern int security_commit_booleans(void);
 
+/* Userspace class mapping support */
+struct security_class_mapping {
+	const char *name;
+	const char *perms[sizeof(access_vector_t) * 8 + 1];
+};
+
+int selinux_set_mapping(struct security_class_mapping *map);
+
 /* Common helpers */
 
 /* Convert between security class values and string names */
Index: libselinux/src/mapping.c
===================================================================
--- libselinux/src/mapping.c	(revision 0)
+++ libselinux/src/mapping.c	(revision 0)
@@ -0,0 +1,189 @@
+/*
+ * Class and permission mappings.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <selinux/selinux.h>
+#include <selinux/avc.h>
+#include "mapping.h"
+
+/*
+ * Class and permission mappings
+ */
+
+struct selinux_mapping {
+	security_class_t value; /* real, kernel value */
+	unsigned num_perms;
+	access_vector_t perms[sizeof(access_vector_t) * 8];
+};
+
+static struct selinux_mapping *current_mapping = NULL;
+static security_class_t current_mapping_size = 0;
+
+/*
+ * Mapping setting function
+ */
+
+int
+selinux_set_mapping(struct security_class_mapping *map)
+{
+	size_t size = sizeof(struct selinux_mapping);
+	security_class_t i, j;
+	unsigned k;
+
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+
+	if (avc_reset() < 0)
+		goto err;
+
+	/* Find number of classes in the input mapping */
+	if (!map) {
+		errno = EINVAL;
+		goto err;
+	}
+	i = 0;
+	while (map[i].name)
+		i++;
+
+	/* Allocate space for the class records, plus one for class zero */
+	current_mapping = (struct selinux_mapping *)calloc(++i, size);
+	if (!current_mapping)
+		goto err;
+
+	/* Store the raw class and permission values */
+	j = 0;
+	while (map[j].name) {
+		struct security_class_mapping *p_in = map + (j++);
+		struct selinux_mapping *p_out = current_mapping + j;
+
+		p_out->value = string_to_security_class(p_in->name);
+		if (!p_out->value)
+			goto err2;
+
+		k = 0;
+		while (p_in->perms && p_in->perms[k]) {
+			p_out->perms[k] = string_to_av_perm(p_out->value,
+							    p_in->perms[k]);
+			if (!p_out->perms[k])
+				goto err2;
+			k++;
+		}
+		p_out->num_perms = k;
+	}
+
+	/* Set the mapping size here so the above lookups are "raw" */
+	current_mapping_size = i;
+	return 0;
+err2:
+	free(current_mapping);
+	current_mapping = NULL;
+	current_mapping_size = 0;
+err:
+	return -1;
+}
+
+/*
+ * Get real, kernel values from mapped values
+ */
+
+security_class_t
+unmap_class(security_class_t tclass)
+{
+	if (tclass < current_mapping_size)
+		return current_mapping[tclass].value;
+
+	assert(current_mapping_size == 0);
+	return tclass;
+}
+
+access_vector_t
+unmap_perm(security_class_t tclass, access_vector_t tperm)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t kperm = 0;
+
+		for (i=0; i<current_mapping[tclass].num_perms; i++)
+			if (tperm & (1<<i)) {
+				kperm |= current_mapping[tclass].perms[i];
+				tperm &= ~(1<<i);
+			}
+		assert(tperm == 0);
+		return kperm;
+	}
+
+	assert(current_mapping_size == 0);
+	return tperm;
+}
+
+/*
+ * Get mapped values from real, kernel values
+ */
+
+security_class_t
+map_class(security_class_t kclass)
+{
+	security_class_t i;
+
+	for (i=0; i<current_mapping_size; i++)
+		if (current_mapping[i].value == kclass)
+			return i;
+
+	assert(current_mapping_size == 0);
+	return kclass;
+}
+
+access_vector_t
+map_perm(security_class_t tclass, access_vector_t kperm)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t tperm = 0;
+
+		for (i=0; i<current_mapping[tclass].num_perms; i++)
+			if (kperm & current_mapping[tclass].perms[i]) {
+				tperm |= 1<<i;
+				kperm &= ~current_mapping[tclass].perms[i];
+			}
+		assert(kperm == 0);
+		return tperm;
+	}
+
+	assert(current_mapping_size == 0);
+	return kperm;
+}
+
+void
+map_decision(security_class_t tclass, struct av_decision *avd)
+{
+	if (tclass < current_mapping_size) {
+		unsigned i;
+		access_vector_t result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->allowed & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->allowed = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->decided & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->decided = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->auditallow & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->auditallow = result;
+
+		for (i=0, result=0; i<current_mapping[tclass].num_perms; i++)
+			if (avd->auditdeny & current_mapping[tclass].perms[i])
+				result |= 1<<i;
+		avd->auditdeny = result;
+	}
+}


-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* [PATCH 2/3] libselinux: class and permission mapping support (try 3)
  2007-06-07 14:18     ` Karl MacMillan
  2007-06-08 17:26       ` [PATCH 1/3] libselinux: class and permission mapping support (try 3) Eamon Walsh
@ 2007-06-08 17:28       ` Eamon Walsh
  2007-06-08 17:30       ` [PATCH 3/3] " Eamon Walsh
  2 siblings, 0 replies; 13+ messages in thread
From: Eamon Walsh @ 2007-06-08 17:28 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: jwcart2, SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

This patch makes avc_reset() exit properly if the AVC
was not initialized.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---

 avc.c          |    5 +++++
 avc_internal.c |    1 +
 avc_internal.h |    1 +
 3 files changed, 7 insertions(+)


Index: libselinux/src/avc_internal.h
===================================================================
--- libselinux/src/avc_internal.h	(revision 2470)
+++ libselinux/src/avc_internal.h	(working copy)
@@ -71,6 +71,7 @@
 /* message prefix and enforcing mode*/
 #define AVC_PREFIX_SIZE 16
 extern char avc_prefix[AVC_PREFIX_SIZE] hidden;
+extern int avc_running hidden;
 extern int avc_enforcing hidden;
 
 /* user-supplied callback interface for avc */
Index: libselinux/src/avc_internal.c
===================================================================
--- libselinux/src/avc_internal.c	(revision 2470)
+++ libselinux/src/avc_internal.c	(working copy)
@@ -44,6 +44,7 @@
 
 /* message prefix string and avc enforcing mode */
 char avc_prefix[AVC_PREFIX_SIZE] = "uavc";
+int avc_running = 0;
 int avc_enforcing = 1;
 int avc_netlink_trouble = 0;
 
Index: libselinux/src/avc.c
===================================================================
--- libselinux/src/avc.c	(revision 2470)
+++ libselinux/src/avc.c	(working copy)
@@ -225,6 +225,7 @@
 		avc_netlink_thread = avc_create_thread(&avc_netlink_loop);
 		avc_netlink_trouble = 0;
 	}
+	avc_running = 1;
       out:
 	return rc;
 }
@@ -534,6 +535,9 @@
 	struct avc_node *node, *tmp;
 	errno = 0;
 
+	if (!avc_running)
+		return 0;
+
 	avc_get_lock(avc_lock);
 
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
@@ -609,6 +613,7 @@
 	avc_free_lock(avc_lock);
 	avc_free_lock(avc_log_lock);
 	avc_free(avc_audit_buf);
+	avc_running = 0;
 }
 
 /* ratelimit stuff put aside for now --EFW */



-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* [PATCH 3/3] libselinux: class and permission mapping support (try 3)
  2007-06-07 14:18     ` Karl MacMillan
  2007-06-08 17:26       ` [PATCH 1/3] libselinux: class and permission mapping support (try 3) Eamon Walsh
  2007-06-08 17:28       ` [PATCH 2/3] " Eamon Walsh
@ 2007-06-08 17:30       ` Eamon Walsh
  2007-06-08 20:00         ` Stephen Smalley
  2 siblings, 1 reply; 13+ messages in thread
From: Eamon Walsh @ 2007-06-08 17:30 UTC (permalink / raw)
  To: Karl MacMillan
  Cc: jwcart2, SE Linux, Stephen Smalley, Joshua Brindle,
	Christopher J. PeBenito

This patch includes the internal map and unmap functions and
the changes to the selinuxfs interfaces to make it work.

Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>
---


 compute_av.c      |    8 ++++++--
 compute_create.c  |    5 +++--
 compute_member.c  |    5 +++--
 compute_relabel.c |    5 +++--
 mapping.h         |   34 ++++++++++++++++++++++++++++++++++
 stringrep.c       |   29 ++++++++++++++++++++---------
 6 files changed, 69 insertions(+), 17 deletions(-)


Index: libselinux/src/mapping.h
===================================================================
--- libselinux/src/mapping.h	(revision 0)
+++ libselinux/src/mapping.h	(revision 0)
@@ -0,0 +1,34 @@
+/*
+ * This file describes the class and permission mappings used to 
+ * hide the kernel numbers from userspace by allowing userspace object
+ * managers to specify a list of classes and permissions.
+ */
+#ifndef _SELINUX_MAPPING_H_
+#define _SELINUX_MAPPING_H_
+
+#include <selinux/selinux.h>
+
+/*
+ * Get real, kernel values from mapped values
+ */
+
+extern security_class_t
+unmap_class(security_class_t tclass);
+
+extern access_vector_t
+unmap_perm(security_class_t tclass, access_vector_t tperm);
+
+/*
+ * Get mapped values from real, kernel values
+ */
+
+extern security_class_t
+map_class(security_class_t kclass);
+
+extern access_vector_t
+map_perm(security_class_t tclass, access_vector_t kperm);
+
+extern void
+map_decision(security_class_t tclass, struct av_decision *avd);
+
+#endif				/* _SELINUX_MAPPING_H_ */
Index: libselinux/src/stringrep.c
===================================================================
--- libselinux/src/stringrep.c	(revision 2470)
+++ libselinux/src/stringrep.c	(working copy)
@@ -17,6 +17,7 @@
 #include <selinux/av_permissions.h>
 #include "selinux_internal.h"
 #include "policy.h"
+#include "mapping.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
@@ -315,12 +316,12 @@
 	if (isdigit(s[0])) {
 		val = atoi(s);
 		if (val > 0 && val < NCLASSES)
-			return val;
+			return map_class(val);
 	} else {
 		for (val = 0; val < NCLASSES; val++) {
 			if (strcmp(s, (class_to_string_data.str
 				       + class_to_string[val])) == 0)
-				return val;
+				return map_class(val);
 		}
 	}
 
@@ -333,9 +334,10 @@
 	const uint16_t *common_pts_idx = 0;
 	access_vector_t perm, common_base = 0;
 	unsigned int i;
+	security_class_t kclass = unmap_class(tclass);
 
 	for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
-		if (av_inherit[i].tclass == tclass) {
+		if (av_inherit[i].tclass == kclass) {
 			common_pts_idx =
 			    &common_perm_to_string.data[av_inherit[i].
 							common_pts_idx];
@@ -350,16 +352,16 @@
 		if (strcmp
 		    (s,
 		     common_perm_to_string_data.str + common_pts_idx[i]) == 0)
-			return perm;
+			return map_perm(tclass, perm);
 		perm <<= 1;
 		i++;
 	}
 
 	for (i = 0; i < NVECTORS; i++) {
-		if ((av_perm_to_string[i].tclass == tclass) &&
+		if ((av_perm_to_string[i].tclass == kclass) &&
 		    (strcmp(s, (av_perm_to_string_data.str
 				+ av_perm_to_string[i].nameidx)) == 0))
-			return av_perm_to_string[i].value;
+			return map_perm(tclass, av_perm_to_string[i].value);
 	}
 
 	errno = EINVAL;
@@ -368,6 +370,8 @@
 
 static const char *security_class_to_string_compat(security_class_t tclass)
 {
+	tclass = unmap_class(tclass);
+
 	if (tclass > 0 && tclass < NCLASSES)
 		return class_to_string_data.str + class_to_string[tclass];
 
@@ -382,6 +386,9 @@
 	access_vector_t common_base = 0;
 	unsigned int i;
 
+	av = unmap_perm(tclass, av);
+	tclass = unmap_class(tclass);
+
 	if (!av)
 		return NULL;
 
@@ -432,22 +439,23 @@
 		}
 	}
 
-	return node->value;
+	return map_class(node->value);
 }
 
 access_vector_t string_to_av_perm(security_class_t tclass, const char *s)
 {
 	struct discover_class_node *node;
+	security_class_t kclass = unmap_class(tclass);
 
 	if (obj_class_compat)
 		return string_to_av_perm_compat(tclass,s);
 
-	node = get_class_cache_entry_value(tclass);
+	node = get_class_cache_entry_value(kclass);
 	if (node != NULL) {
 		size_t i;
 		for (i=0; i<MAXVECTORS && node->perms[i] != NULL; i++)
 			if (strcmp(node->perms[i],s) == 0)
-				return (1<<i);
+				return map_perm(tclass, 1<<i);
 	}
 
 	errno = EINVAL;
@@ -461,6 +469,7 @@
 	if (obj_class_compat)
 		return security_class_to_string_compat(tclass);
 
+	tclass = unmap_class(tclass);
 	node = get_class_cache_entry_value(tclass);
 	if (node == NULL) {
 		errno = EINVAL;
@@ -478,6 +487,8 @@
 	if (obj_class_compat)
 		return security_av_perm_to_string_compat(tclass,av);
 
+	av = unmap_perm(tclass, av);
+	tclass = unmap_class(tclass);
 	node = get_class_cache_entry_value(tclass);
 	if (av && node)
 		for (i = 0; i<MAXVECTORS; i++)
Index: libselinux/src/compute_av.c
===================================================================
--- libselinux/src/compute_av.c	(revision 2470)
+++ libselinux/src/compute_av.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_av_raw(security_context_t scon,
 			    security_context_t tcon,
@@ -36,7 +37,8 @@
 		goto out;
 	}
 
-	snprintf(buf, len, "%s %s %hu %x", scon, tcon, tclass, requested);
+	snprintf(buf, len, "%s %s %hu %x", scon, tcon,
+		 unmap_class(tclass), unmap_perm(tclass, requested));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
@@ -54,6 +56,8 @@
 		goto out2;
 	}
 
+	map_decision(tclass, avd);
+
 	ret = 0;
       out2:
 	free(buf);
Index: libselinux/src/compute_create.c
===================================================================
--- libselinux/src/compute_create.c	(revision 2470)
+++ libselinux/src/compute_create.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_create_raw(security_context_t scon,
 				security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
Index: libselinux/src/compute_member.c
===================================================================
--- libselinux/src/compute_member.c	(revision 2470)
+++ libselinux/src/compute_member.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_member_raw(security_context_t scon,
 				security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)
Index: libselinux/src/compute_relabel.c
===================================================================
--- libselinux/src/compute_relabel.c	(revision 2470)
+++ libselinux/src/compute_relabel.c	(working copy)
@@ -5,9 +5,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <limits.h>
 #include "selinux_internal.h"
 #include "policy.h"
-#include <limits.h>
+#include "mapping.h"
 
 int security_compute_relabel_raw(security_context_t scon,
 				 security_context_t tcon,
@@ -35,7 +36,7 @@
 		ret = -1;
 		goto out;
 	}
-	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
+	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
 
 	ret = write(fd, buf, strlen(buf));
 	if (ret < 0)


-- 
Eamon Walsh <ewalsh@tycho.nsa.gov>
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] 13+ messages in thread

* Re: [PATCH 3/3] libselinux: class and permission mapping support (try 3)
  2007-06-08 17:30       ` [PATCH 3/3] " Eamon Walsh
@ 2007-06-08 20:00         ` Stephen Smalley
  0 siblings, 0 replies; 13+ messages in thread
From: Stephen Smalley @ 2007-06-08 20:00 UTC (permalink / raw)
  To: Eamon Walsh
  Cc: Karl MacMillan, jwcart2, SE Linux, Joshua Brindle,
	Christopher J. PeBenito

On Fri, 2007-06-08 at 13:30 -0400, Eamon Walsh wrote:
> This patch includes the internal map and unmap functions and
> the changes to the selinuxfs interfaces to make it work.
> 
> Signed-off-by: Eamon Walsh <ewalsh@tycho.nsa.gov>

All three patches:
Acked-by:  Stephen Smalley <sds@tycho.nsa.gov>
> ---
> 
> 
>  compute_av.c      |    8 ++++++--
>  compute_create.c  |    5 +++--
>  compute_member.c  |    5 +++--
>  compute_relabel.c |    5 +++--
>  mapping.h         |   34 ++++++++++++++++++++++++++++++++++
>  stringrep.c       |   29 ++++++++++++++++++++---------
>  6 files changed, 69 insertions(+), 17 deletions(-)
> 
> 
> Index: libselinux/src/mapping.h
> ===================================================================
> --- libselinux/src/mapping.h	(revision 0)
> +++ libselinux/src/mapping.h	(revision 0)
> @@ -0,0 +1,34 @@
> +/*
> + * This file describes the class and permission mappings used to 
> + * hide the kernel numbers from userspace by allowing userspace object
> + * managers to specify a list of classes and permissions.
> + */
> +#ifndef _SELINUX_MAPPING_H_
> +#define _SELINUX_MAPPING_H_
> +
> +#include <selinux/selinux.h>
> +
> +/*
> + * Get real, kernel values from mapped values
> + */
> +
> +extern security_class_t
> +unmap_class(security_class_t tclass);
> +
> +extern access_vector_t
> +unmap_perm(security_class_t tclass, access_vector_t tperm);
> +
> +/*
> + * Get mapped values from real, kernel values
> + */
> +
> +extern security_class_t
> +map_class(security_class_t kclass);
> +
> +extern access_vector_t
> +map_perm(security_class_t tclass, access_vector_t kperm);
> +
> +extern void
> +map_decision(security_class_t tclass, struct av_decision *avd);
> +
> +#endif				/* _SELINUX_MAPPING_H_ */
> Index: libselinux/src/stringrep.c
> ===================================================================
> --- libselinux/src/stringrep.c	(revision 2470)
> +++ libselinux/src/stringrep.c	(working copy)
> @@ -17,6 +17,7 @@
>  #include <selinux/av_permissions.h>
>  #include "selinux_internal.h"
>  #include "policy.h"
> +#include "mapping.h"
>  
>  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
>  
> @@ -315,12 +316,12 @@
>  	if (isdigit(s[0])) {
>  		val = atoi(s);
>  		if (val > 0 && val < NCLASSES)
> -			return val;
> +			return map_class(val);
>  	} else {
>  		for (val = 0; val < NCLASSES; val++) {
>  			if (strcmp(s, (class_to_string_data.str
>  				       + class_to_string[val])) == 0)
> -				return val;
> +				return map_class(val);
>  		}
>  	}
>  
> @@ -333,9 +334,10 @@
>  	const uint16_t *common_pts_idx = 0;
>  	access_vector_t perm, common_base = 0;
>  	unsigned int i;
> +	security_class_t kclass = unmap_class(tclass);
>  
>  	for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
> -		if (av_inherit[i].tclass == tclass) {
> +		if (av_inherit[i].tclass == kclass) {
>  			common_pts_idx =
>  			    &common_perm_to_string.data[av_inherit[i].
>  							common_pts_idx];
> @@ -350,16 +352,16 @@
>  		if (strcmp
>  		    (s,
>  		     common_perm_to_string_data.str + common_pts_idx[i]) == 0)
> -			return perm;
> +			return map_perm(tclass, perm);
>  		perm <<= 1;
>  		i++;
>  	}
>  
>  	for (i = 0; i < NVECTORS; i++) {
> -		if ((av_perm_to_string[i].tclass == tclass) &&
> +		if ((av_perm_to_string[i].tclass == kclass) &&
>  		    (strcmp(s, (av_perm_to_string_data.str
>  				+ av_perm_to_string[i].nameidx)) == 0))
> -			return av_perm_to_string[i].value;
> +			return map_perm(tclass, av_perm_to_string[i].value);
>  	}
>  
>  	errno = EINVAL;
> @@ -368,6 +370,8 @@
>  
>  static const char *security_class_to_string_compat(security_class_t tclass)
>  {
> +	tclass = unmap_class(tclass);
> +
>  	if (tclass > 0 && tclass < NCLASSES)
>  		return class_to_string_data.str + class_to_string[tclass];
>  
> @@ -382,6 +386,9 @@
>  	access_vector_t common_base = 0;
>  	unsigned int i;
>  
> +	av = unmap_perm(tclass, av);
> +	tclass = unmap_class(tclass);
> +
>  	if (!av)
>  		return NULL;
>  
> @@ -432,22 +439,23 @@
>  		}
>  	}
>  
> -	return node->value;
> +	return map_class(node->value);
>  }
>  
>  access_vector_t string_to_av_perm(security_class_t tclass, const char *s)
>  {
>  	struct discover_class_node *node;
> +	security_class_t kclass = unmap_class(tclass);
>  
>  	if (obj_class_compat)
>  		return string_to_av_perm_compat(tclass,s);
>  
> -	node = get_class_cache_entry_value(tclass);
> +	node = get_class_cache_entry_value(kclass);
>  	if (node != NULL) {
>  		size_t i;
>  		for (i=0; i<MAXVECTORS && node->perms[i] != NULL; i++)
>  			if (strcmp(node->perms[i],s) == 0)
> -				return (1<<i);
> +				return map_perm(tclass, 1<<i);
>  	}
>  
>  	errno = EINVAL;
> @@ -461,6 +469,7 @@
>  	if (obj_class_compat)
>  		return security_class_to_string_compat(tclass);
>  
> +	tclass = unmap_class(tclass);
>  	node = get_class_cache_entry_value(tclass);
>  	if (node == NULL) {
>  		errno = EINVAL;
> @@ -478,6 +487,8 @@
>  	if (obj_class_compat)
>  		return security_av_perm_to_string_compat(tclass,av);
>  
> +	av = unmap_perm(tclass, av);
> +	tclass = unmap_class(tclass);
>  	node = get_class_cache_entry_value(tclass);
>  	if (av && node)
>  		for (i = 0; i<MAXVECTORS; i++)
> Index: libselinux/src/compute_av.c
> ===================================================================
> --- libselinux/src/compute_av.c	(revision 2470)
> +++ libselinux/src/compute_av.c	(working copy)
> @@ -5,9 +5,10 @@
>  #include <stdio.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <limits.h>
>  #include "selinux_internal.h"
>  #include "policy.h"
> -#include <limits.h>
> +#include "mapping.h"
>  
>  int security_compute_av_raw(security_context_t scon,
>  			    security_context_t tcon,
> @@ -36,7 +37,8 @@
>  		goto out;
>  	}
>  
> -	snprintf(buf, len, "%s %s %hu %x", scon, tcon, tclass, requested);
> +	snprintf(buf, len, "%s %s %hu %x", scon, tcon,
> +		 unmap_class(tclass), unmap_perm(tclass, requested));
>  
>  	ret = write(fd, buf, strlen(buf));
>  	if (ret < 0)
> @@ -54,6 +56,8 @@
>  		goto out2;
>  	}
>  
> +	map_decision(tclass, avd);
> +
>  	ret = 0;
>        out2:
>  	free(buf);
> Index: libselinux/src/compute_create.c
> ===================================================================
> --- libselinux/src/compute_create.c	(revision 2470)
> +++ libselinux/src/compute_create.c	(working copy)
> @@ -5,9 +5,10 @@
>  #include <stdio.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <limits.h>
>  #include "selinux_internal.h"
>  #include "policy.h"
> -#include <limits.h>
> +#include "mapping.h"
>  
>  int security_compute_create_raw(security_context_t scon,
>  				security_context_t tcon,
> @@ -35,7 +36,7 @@
>  		ret = -1;
>  		goto out;
>  	}
> -	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
> +	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
>  
>  	ret = write(fd, buf, strlen(buf));
>  	if (ret < 0)
> Index: libselinux/src/compute_member.c
> ===================================================================
> --- libselinux/src/compute_member.c	(revision 2470)
> +++ libselinux/src/compute_member.c	(working copy)
> @@ -5,9 +5,10 @@
>  #include <stdio.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <limits.h>
>  #include "selinux_internal.h"
>  #include "policy.h"
> -#include <limits.h>
> +#include "mapping.h"
>  
>  int security_compute_member_raw(security_context_t scon,
>  				security_context_t tcon,
> @@ -35,7 +36,7 @@
>  		ret = -1;
>  		goto out;
>  	}
> -	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
> +	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
>  
>  	ret = write(fd, buf, strlen(buf));
>  	if (ret < 0)
> Index: libselinux/src/compute_relabel.c
> ===================================================================
> --- libselinux/src/compute_relabel.c	(revision 2470)
> +++ libselinux/src/compute_relabel.c	(working copy)
> @@ -5,9 +5,10 @@
>  #include <stdio.h>
>  #include <errno.h>
>  #include <string.h>
> +#include <limits.h>
>  #include "selinux_internal.h"
>  #include "policy.h"
> -#include <limits.h>
> +#include "mapping.h"
>  
>  int security_compute_relabel_raw(security_context_t scon,
>  				 security_context_t tcon,
> @@ -35,7 +36,7 @@
>  		ret = -1;
>  		goto out;
>  	}
> -	snprintf(buf, size, "%s %s %hu", scon, tcon, tclass);
> +	snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass));
>  
>  	ret = write(fd, buf, strlen(buf));
>  	if (ret < 0)
> 
> 
-- 
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] 13+ messages in thread

end of thread, other threads:[~2007-06-08 20:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-06 15:42 [PATCH 1/2] libselinux: class and permission mapping support Eamon Walsh
2007-06-06 15:45 ` Joshua Brindle
2007-06-06 16:32   ` Eamon Walsh
2007-06-06 15:59 ` Stephen Smalley
2007-06-06 16:24   ` Eamon Walsh
2007-06-06 16:40 ` James Carter
2007-06-06 18:32   ` [PATCH 1/2] libselinux: class and permission mapping support (try 2) Eamon Walsh
2007-06-06 18:34   ` [PATCH 2/2] " Eamon Walsh
2007-06-07 14:18     ` Karl MacMillan
2007-06-08 17:26       ` [PATCH 1/3] libselinux: class and permission mapping support (try 3) Eamon Walsh
2007-06-08 17:28       ` [PATCH 2/3] " Eamon Walsh
2007-06-08 17:30       ` [PATCH 3/3] " Eamon Walsh
2007-06-08 20:00         ` Stephen Smalley

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.