* [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.