147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner/* 247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner * String representation support for classes and permissions. 347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner */ 447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <sys/stat.h> 547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <dirent.h> 647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <fcntl.h> 747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <limits.h> 847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <unistd.h> 947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <errno.h> 1047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stddef.h> 1147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdio.h> 1247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdlib.h> 1347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <string.h> 1447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdint.h> 1547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <ctype.h> 1647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "selinux_internal.h" 1747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "policy.h" 1847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "mapping.h" 1947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 2147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#define MAXVECTORS 8*sizeof(access_vector_t) 2347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic pthread_once_t once = PTHREAD_ONCE_INIT; 2547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstruct discover_class_node { 2747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *name; 2847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner security_class_t value; 2947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char **perms; 3047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *next; 3247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner}; 3347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic struct discover_class_node *discover_class_cache = NULL; 3547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic struct discover_class_node * get_class_cache_entry_name(const char *s) 3747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 3847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node = discover_class_cache; 3947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (; node != NULL && strcmp(s,node->name) != 0; node = node->next); 4147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return node; 4347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 4447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic struct discover_class_node * get_class_cache_entry_value(security_class_t c) 4647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 4747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node = discover_class_cache; 4847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (; node != NULL && c != node->value; node = node->next); 5047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 5147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return node; 5247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 5347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 5447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerstatic struct discover_class_node * discover_class(const char *s) 5547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 5647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int fd, ret; 5747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char path[PATH_MAX]; 5847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char buf[20]; 5947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner DIR *dir; 6047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct dirent *dentry; 6147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t i; 6247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 6347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node; 6447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 6547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!selinux_mnt) { 6647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = ENOENT; 6747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return NULL; 6847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 6947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 7047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* allocate a node */ 7147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = malloc(sizeof(struct discover_class_node)); 7247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node == NULL) 7347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return NULL; 7447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 7547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* allocate array for perms */ 7647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node->perms = calloc(MAXVECTORS,sizeof(char*)); 7747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node->perms == NULL) 7847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err1; 7947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* load up the name */ 8147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node->name = strdup(s); 8247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node->name == NULL) 8347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err2; 8447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 8547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* load up class index */ 8647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s); 8747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner fd = open(path, O_RDONLY); 8847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (fd < 0) 8947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err3; 9047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner memset(buf, 0, sizeof(buf)); 9247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = read(fd, buf, sizeof(buf) - 1); 9347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner close(fd); 9447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (ret < 0) 9547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err3; 9647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 9747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (sscanf(buf, "%hu", &node->value) != 1) 9847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err3; 9947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 10047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* load up permission indicies */ 10147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner snprintf(path, sizeof path, "%s/class/%s/perms",selinux_mnt,s); 10247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner dir = opendir(path); 10347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (dir == NULL) 10447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err3; 10547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 10647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner dentry = readdir(dir); 10747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner while (dentry != NULL) { 10847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner unsigned int value; 10947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct stat m; 11047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner snprintf(path, sizeof path, "%s/class/%s/perms/%s", selinux_mnt,s,dentry->d_name); 11247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (stat(path,&m) < 0) 11347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err4; 11447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 11547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (m.st_mode & S_IFDIR) { 11647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner dentry = readdir(dir); 11747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner continue; 11847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 11947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 12047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner fd = open(path, O_RDONLY); 12147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (fd < 0) 12247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err4; 12347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 12447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner memset(buf, 0, sizeof(buf)); 12547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = read(fd, buf, sizeof(buf) - 1); 12647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner close(fd); 12747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (ret < 0) 12847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err4; 12947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 13047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (sscanf(buf, "%u", &value) != 1) 13147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err4; 13247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 13347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node->perms[value-1] = strdup(dentry->d_name); 13447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node->perms[value-1] == NULL) 13547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto err4; 13647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 13747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner dentry = readdir(dir); 13847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 13947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner closedir(dir); 14047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 14147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node->next = discover_class_cache; 14247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner discover_class_cache = node; 14347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 14447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return node; 14547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 14647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnererr4: 14747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner closedir(dir); 14847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i=0; i<MAXVECTORS; i++) 14947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(node->perms[i]); 15047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnererr3: 15147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(node->name); 15247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnererr2: 15347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(node->perms); 15447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnererr1: 15547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(node); 15647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return NULL; 15747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 15847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 15947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnervoid flush_class_cache(void) 16047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 16147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *cur = discover_class_cache, *prev = NULL; 16247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t i; 16347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 16447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner while (cur != NULL) { 16547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(cur->name); 16647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 16747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i=0 ; i<MAXVECTORS ; i++) 16847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(cur->perms[i]); 16947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 17047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(cur->perms); 17147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 17247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner prev = cur; 17347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner cur = cur->next; 17447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 17547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(prev); 17647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 17747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 17847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner discover_class_cache = NULL; 17947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 18047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 18147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnersecurity_class_t string_to_security_class(const char *s) 18247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 18347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node; 18447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 18547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = get_class_cache_entry_name(s); 18647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node == NULL) { 18747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = discover_class(s); 18847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 18947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node == NULL) { 19047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = EINVAL; 19147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 0; 19247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 19347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 19447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 19547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return map_class(node->value); 19647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 19747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 19847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turneraccess_vector_t string_to_av_perm(security_class_t tclass, const char *s) 19947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 20047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node; 20147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner security_class_t kclass = unmap_class(tclass); 20247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 20347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = get_class_cache_entry_value(kclass); 20447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node != NULL) { 20547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t i; 20647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i=0; i<MAXVECTORS && node->perms[i] != NULL; i++) 20747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (strcmp(node->perms[i],s) == 0) 20847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return map_perm(tclass, 1<<i); 20947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 21047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 21147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = EINVAL; 21247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return 0; 21347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 21447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 21547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerconst char *security_class_to_string(security_class_t tclass) 21647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 21747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node; 21847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 21947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tclass = unmap_class(tclass); 22047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 22147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = get_class_cache_entry_value(tclass); 22247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (node) 22347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return node->name; 22447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return NULL; 22547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 22647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 22747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerconst char *security_av_perm_to_string(security_class_t tclass, 22847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner access_vector_t av) 22947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 23047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner struct discover_class_node *node; 23147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t i; 23247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 23347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner av = unmap_perm(tclass, av); 23447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tclass = unmap_class(tclass); 23547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 23647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner node = get_class_cache_entry_value(tclass); 23747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (av && node) 23847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner for (i = 0; i<MAXVECTORS; i++) 23947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if ((1<<i) & av) 24047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return node->perms[i]; 24147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 24247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return NULL; 24347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 24447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 24547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerint security_av_string(security_class_t tclass, access_vector_t av, char **res) 24647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 24747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner unsigned int i = 0; 24847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t len = 5; 24947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner access_vector_t tmp = av; 25047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int rc = 0; 25147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner const char *str; 25247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *ptr; 25347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 25447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* first pass computes the required length */ 25547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner while (tmp) { 25647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (tmp & 1) { 25747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner str = security_av_perm_to_string(tclass, av & (1<<i)); 25847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (str) 25947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner len += strlen(str) + 1; 26047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner else { 26147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner rc = -1; 26247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = EINVAL; 26347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out; 26447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 26547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 26647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tmp >>= 1; 26747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner i++; 26847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 26947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 27047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner *res = malloc(len); 27147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!*res) { 27247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner rc = -1; 27347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out; 27447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 27547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 27647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* second pass constructs the string */ 27747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner i = 0; 27847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tmp = av; 27947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ptr = *res; 28047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 28147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!av) { 28247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner sprintf(ptr, "null"); 28347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out; 28447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 28547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 28647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ptr += sprintf(ptr, "{ "); 28747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner while (tmp) { 28847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (tmp & 1) 28947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ptr += sprintf(ptr, "%s ", security_av_perm_to_string( 29047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tclass, av & (1<<i))); 29147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner tmp >>= 1; 29247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner i++; 29347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 29447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner sprintf(ptr, "}"); 29547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerout: 29647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return rc; 29747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 298