diff options
Diffstat (limited to 'libselinux/src/stringrep.c')
-rw-r--r-- | libselinux/src/stringrep.c | 292 |
1 files changed, 5 insertions, 287 deletions
diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c index ba75ccd5..9ae82483 100644 --- a/libselinux/src/stringrep.c +++ b/libselinux/src/stringrep.c @@ -13,165 +13,12 @@ #include <string.h> #include <stdint.h> #include <ctype.h> -#include <selinux/flask.h> -#include <selinux/av_permissions.h> #include "selinux_internal.h" #include "policy.h" #include "mapping.h" -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* The following code looks complicated, but it really is not. What it - does is to generate two variables. The first is basically a struct - of arrays. The second is the real array of structures which would - have used string pointers. But instead it now uses an offset value - into the first structure. Strings are accessed indirectly by an - explicit addition of the string index and the base address of the - structure with the strings (all type safe). The advantage is that - there are no relocations necessary in the array with the data as it - would be the case with string pointers. This has advantages at - load time, the data section is smaller, and it is read-only. */ -#define L1(line) L2(line) -#define L2(line) str##line -static const union av_perm_to_string_data { - struct { -#define S_(c, v, s) char L1(__LINE__)[sizeof(s)]; -#include "av_perm_to_string.h" -#undef S_ - }; - char str[0]; -} av_perm_to_string_data = { - { -#define S_(c, v, s) s, -#include "av_perm_to_string.h" -#undef S_ - } -}; -static const struct av_perm_to_string { - uint16_t tclass; - uint16_t nameidx; - uint32_t value; -} av_perm_to_string[] = { -#define S_(c, v, s) { c, offsetof(union av_perm_to_string_data, L1(__LINE__)), v }, -#include "av_perm_to_string.h" -#undef S_ -}; - -#undef L1 -#undef L2 - -#define L1(line) L2(line) -#define L2(line) str##line -static const union class_to_string_data { - struct { -#define S_(s) char L1(__LINE__)[sizeof(s)]; -#include "class_to_string.h" -#undef S_ - }; - char str[0]; -} class_to_string_data = { - { -#define S_(s) s, -#include "class_to_string.h" -#undef S_ - } -}; -static const uint16_t class_to_string[] = { -#define S_(s) offsetof(union class_to_string_data, L1(__LINE__)), -#include "class_to_string.h" -#undef S_ -}; - -#undef L1 -#undef L2 - -static const union common_perm_to_string_data { - struct { -#define L1(line) L2(line) -#define L2(line) str##line -#define S_(s) char L1(__LINE__)[sizeof(s)]; -#define TB_(s) -#define TE_(s) -#include "common_perm_to_string.h" -#undef S_ -#undef L1 -#undef L2 - }; - char str[0]; -} common_perm_to_string_data = { - { -#define S_(s) s, -#include "common_perm_to_string.h" -#undef S_ -#undef TB_ -#undef TE_ - } -}; -static const union common_perm_to_string { - struct { -#define TB_(s) struct { -#define TE_(s) } s##_part; -#define S_(s) uint16_t L1(__LINE__) -#define L1(l) L2(l) -#define L2(l) field_##l; -#include "common_perm_to_string.h" -#undef TB_ -#undef TE_ -#undef S_ -#undef L1 -#undef L2 - }; - uint16_t data[0]; -} common_perm_to_string = { - { -#define TB_(s) { -#define TE_(s) }, -#define S_(s) offsetof(union common_perm_to_string_data, L1(__LINE__)), -#define L1(line) L2(line) -#define L2(line) str##line -#include "common_perm_to_string.h" -#undef TB_ -#undef TE_ -#undef S_ -#undef L1 -#undef L2 - } -}; - -static const struct av_inherit { - uint16_t tclass; - uint16_t common_pts_idx; - uint32_t common_base; -} av_inherit[] = { -#define S_(c, i, b) { c, offsetof(union common_perm_to_string, common_##i##_perm_to_string_part)/sizeof(uint16_t), b }, -#include "av_inherit.h" -#undef S_ -}; - -#define NCLASSES ARRAY_SIZE(class_to_string) -#define NVECTORS ARRAY_SIZE(av_perm_to_string) #define MAXVECTORS 8*sizeof(access_vector_t) -static pthread_once_t once = PTHREAD_ONCE_INIT; - -static int obj_class_compat; - -static void init_obj_class_compat(void) -{ - char path[PATH_MAX]; - struct stat s; - - if (!selinux_mnt) - return; - - snprintf(path,PATH_MAX,"%s/class",selinux_mnt); - if (stat(path,&s) < 0) - return; - - if (S_ISDIR(s.st_mode)) - obj_class_compat = 0; -} - struct discover_class_node { char *name; security_class_t value; @@ -222,7 +69,7 @@ static struct discover_class_node * discover_class(const char *s) return NULL; /* allocate array for perms */ - node->perms = calloc(NVECTORS,sizeof(char*)); + node->perms = calloc(MAXVECTORS,sizeof(char*)); if (node->perms == NULL) goto err1; @@ -282,7 +129,7 @@ static struct discover_class_node * discover_class(const char *s) if (sscanf(buf, "%u", &value) != 1) goto err4; - if (value == 0 || value > NVECTORS) + if (value == 0 || value > MAXVECTORS) goto err4; node->perms[value-1] = strdup(dentry->d_name); @@ -300,7 +147,7 @@ static struct discover_class_node * discover_class(const char *s) err4: closedir(dir); - for (i=0; i<NVECTORS; i++) + for (i=0; i<MAXVECTORS; i++) free(node->perms[i]); err3: free(node->name); @@ -311,124 +158,10 @@ err1: return NULL; } -static security_class_t string_to_security_class_compat(const char *s) -{ - unsigned int val; - - if (isdigit(s[0])) { - val = atoi(s); - if (val > 0 && val < NCLASSES) - 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 map_class(val); - } - } - - errno = EINVAL; - return 0; -} - -static access_vector_t string_to_av_perm_compat(security_class_t kclass, const char *s) -{ - const uint16_t *common_pts_idx = 0; - access_vector_t perm, common_base = 0; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(av_inherit); i++) { - if (av_inherit[i].tclass == kclass) { - common_pts_idx = - &common_perm_to_string.data[av_inherit[i]. - common_pts_idx]; - common_base = av_inherit[i].common_base; - break; - } - } - - i = 0; - perm = 1; - while (perm < common_base) { - if (strcmp - (s, - common_perm_to_string_data.str + common_pts_idx[i]) == 0) - return perm; - perm <<= 1; - i++; - } - - for (i = 0; i < NVECTORS; i++) { - 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; - } - - errno = EINVAL; - return 0; -} - -static const char *security_class_to_string_compat(security_class_t tclass) -{ - if (tclass > 0 && tclass < NCLASSES) - return class_to_string_data.str + class_to_string[tclass]; - - errno = EINVAL; - return NULL; -} - -static const char *security_av_perm_to_string_compat(security_class_t tclass, - access_vector_t av) -{ - const uint16_t *common_pts_idx = 0; - access_vector_t common_base = 0; - unsigned int i; - - if (!av) { - errno = EINVAL; - return NULL; - } - - for (i = 0; i < ARRAY_SIZE(av_inherit); i++) { - if (av_inherit[i].tclass == tclass) { - common_pts_idx = - &common_perm_to_string.data[av_inherit[i]. - common_pts_idx]; - common_base = av_inherit[i].common_base; - break; - } - } - - if (av < common_base) { - i = 0; - while (!(av & 1)) { - av >>= 1; - i++; - } - return common_perm_to_string_data.str + common_pts_idx[i]; - } - - for (i = 0; i < NVECTORS; i++) { - if (av_perm_to_string[i].tclass == tclass && - av_perm_to_string[i].value == av) - return av_perm_to_string_data.str - + av_perm_to_string[i].nameidx; - } - - errno = EINVAL; - return NULL; -} - security_class_t string_to_security_class(const char *s) { struct discover_class_node *node; - __selinux_once(once, init_obj_class_compat); - - if (obj_class_compat) - return string_to_security_class_compat(s); - node = get_class_cache_entry_name(s); if (node == NULL) { node = discover_class(s); @@ -468,11 +201,6 @@ 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); - __selinux_once(once, init_obj_class_compat); - - if (obj_class_compat) - return map_perm(tclass, string_to_av_perm_compat(kclass, s)); - node = get_class_cache_entry_value(kclass); if (node != NULL) { size_t i; @@ -491,14 +219,9 @@ const char *security_class_to_string(security_class_t tclass) tclass = unmap_class(tclass); - __selinux_once(once, init_obj_class_compat); - - if (obj_class_compat) - return security_class_to_string_compat(tclass); - node = get_class_cache_entry_value(tclass); if (node == NULL) - return security_class_to_string_compat(tclass); + return NULL; else return node->name; } @@ -512,18 +235,13 @@ const char *security_av_perm_to_string(security_class_t tclass, av = unmap_perm(tclass, av); tclass = unmap_class(tclass); - __selinux_once(once, init_obj_class_compat); - - if (obj_class_compat) - return security_av_perm_to_string_compat(tclass,av); - node = get_class_cache_entry_value(tclass); if (av && node) for (i = 0; i<MAXVECTORS; i++) if ((1<<i) & av) return node->perms[i]; - return security_av_perm_to_string_compat(tclass,av); + return NULL; } int security_av_string(security_class_t tclass, access_vector_t av, char **res) |