1f074036424618c130dacb3464465a8b40bffef5Stephen Smalley/* 2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley * String representation support for classes and permissions. 3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley */ 4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <sys/stat.h> 5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <dirent.h> 6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <fcntl.h> 7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <limits.h> 8f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <unistd.h> 9f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h> 10f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stddef.h> 11f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdio.h> 12f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h> 13f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <string.h> 14f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdint.h> 15f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <ctype.h> 16f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "selinux_internal.h" 17f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "policy.h" 18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "mapping.h" 19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 20f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#define MAXVECTORS 8*sizeof(access_vector_t) 21f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 22f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystruct discover_class_node { 23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *name; 24f074036424618c130dacb3464465a8b40bffef5Stephen Smalley security_class_t value; 25f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char **perms; 26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 27f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *next; 28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley}; 29f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 30f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic struct discover_class_node *discover_class_cache = NULL; 31f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 32f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic struct discover_class_node * get_class_cache_entry_name(const char *s) 33f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 34f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node = discover_class_cache; 35f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 36f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (; node != NULL && strcmp(s,node->name) != 0; node = node->next); 37f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 38f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return node; 39f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 40f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 41f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic struct discover_class_node * get_class_cache_entry_value(security_class_t c) 42f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 43f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node = discover_class_cache; 44f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 45f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (; node != NULL && c != node->value; node = node->next); 46f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 47f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return node; 48f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 49f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 50f074036424618c130dacb3464465a8b40bffef5Stephen Smalleystatic struct discover_class_node * discover_class(const char *s) 51f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 52f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int fd, ret; 53f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char path[PATH_MAX]; 54f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char buf[20]; 55f074036424618c130dacb3464465a8b40bffef5Stephen Smalley DIR *dir; 56f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct dirent *dentry; 57f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t i; 58f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 59f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node; 60f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 61f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!selinux_mnt) { 62f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = ENOENT; 63f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return NULL; 64f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 65f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 66f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* allocate a node */ 67f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = malloc(sizeof(struct discover_class_node)); 68f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node == NULL) 69f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return NULL; 70f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 71f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* allocate array for perms */ 72f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node->perms = calloc(MAXVECTORS,sizeof(char*)); 73f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node->perms == NULL) 74f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err1; 75f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 76f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* load up the name */ 77f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node->name = strdup(s); 78f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node->name == NULL) 79f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err2; 80f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 81f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* load up class index */ 82f074036424618c130dacb3464465a8b40bffef5Stephen Smalley snprintf(path, sizeof path, "%s/class/%s/index", selinux_mnt,s); 83f074036424618c130dacb3464465a8b40bffef5Stephen Smalley fd = open(path, O_RDONLY); 84f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (fd < 0) 85f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err3; 86f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 87f074036424618c130dacb3464465a8b40bffef5Stephen Smalley memset(buf, 0, sizeof(buf)); 88f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = read(fd, buf, sizeof(buf) - 1); 89f074036424618c130dacb3464465a8b40bffef5Stephen Smalley close(fd); 90f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (ret < 0) 91f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err3; 92f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 93f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (sscanf(buf, "%hu", &node->value) != 1) 94f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err3; 95f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 96f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* load up permission indicies */ 97f074036424618c130dacb3464465a8b40bffef5Stephen Smalley snprintf(path, sizeof path, "%s/class/%s/perms",selinux_mnt,s); 98f074036424618c130dacb3464465a8b40bffef5Stephen Smalley dir = opendir(path); 99f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (dir == NULL) 100f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err3; 101f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 102f074036424618c130dacb3464465a8b40bffef5Stephen Smalley dentry = readdir(dir); 103f074036424618c130dacb3464465a8b40bffef5Stephen Smalley while (dentry != NULL) { 104f074036424618c130dacb3464465a8b40bffef5Stephen Smalley unsigned int value; 105f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct stat m; 106f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 107f074036424618c130dacb3464465a8b40bffef5Stephen Smalley snprintf(path, sizeof path, "%s/class/%s/perms/%s", selinux_mnt,s,dentry->d_name); 108c01e95f737527e068edcacb1179affca9f62a52dEric Paris fd = open(path, O_RDONLY | O_CLOEXEC); 109c01e95f737527e068edcacb1179affca9f62a52dEric Paris if (fd < 0) 110f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err4; 111f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 112c01e95f737527e068edcacb1179affca9f62a52dEric Paris if (fstat(fd, &m) < 0) { 113c01e95f737527e068edcacb1179affca9f62a52dEric Paris close(fd); 114c01e95f737527e068edcacb1179affca9f62a52dEric Paris goto err4; 115c01e95f737527e068edcacb1179affca9f62a52dEric Paris } 116c01e95f737527e068edcacb1179affca9f62a52dEric Paris 117f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (m.st_mode & S_IFDIR) { 118c01e95f737527e068edcacb1179affca9f62a52dEric Paris close(fd); 119f074036424618c130dacb3464465a8b40bffef5Stephen Smalley dentry = readdir(dir); 120f074036424618c130dacb3464465a8b40bffef5Stephen Smalley continue; 121f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 122f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 123f074036424618c130dacb3464465a8b40bffef5Stephen Smalley memset(buf, 0, sizeof(buf)); 124f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = read(fd, buf, sizeof(buf) - 1); 125f074036424618c130dacb3464465a8b40bffef5Stephen Smalley close(fd); 126f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (ret < 0) 127f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err4; 128f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 129f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (sscanf(buf, "%u", &value) != 1) 130f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err4; 131f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 132c01e95f737527e068edcacb1179affca9f62a52dEric Paris if (value == 0 || value > MAXVECTORS) 133c01e95f737527e068edcacb1179affca9f62a52dEric Paris goto err4; 134c01e95f737527e068edcacb1179affca9f62a52dEric Paris 135f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node->perms[value-1] = strdup(dentry->d_name); 136f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node->perms[value-1] == NULL) 137f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto err4; 138f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 139f074036424618c130dacb3464465a8b40bffef5Stephen Smalley dentry = readdir(dir); 140f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 141f074036424618c130dacb3464465a8b40bffef5Stephen Smalley closedir(dir); 142f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 143f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node->next = discover_class_cache; 144f074036424618c130dacb3464465a8b40bffef5Stephen Smalley discover_class_cache = node; 145f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 146f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return node; 147f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 148f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyerr4: 149f074036424618c130dacb3464465a8b40bffef5Stephen Smalley closedir(dir); 150f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i=0; i<MAXVECTORS; i++) 151f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(node->perms[i]); 152f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyerr3: 153f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(node->name); 154f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyerr2: 155f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(node->perms); 156f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyerr1: 157f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(node); 158f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return NULL; 159f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 160f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 161f074036424618c130dacb3464465a8b40bffef5Stephen Smalleysecurity_class_t string_to_security_class(const char *s) 162f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 163f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node; 164f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 165f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = get_class_cache_entry_name(s); 166f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node == NULL) { 167f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = discover_class(s); 168f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 169f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node == NULL) { 170f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = EINVAL; 171f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 0; 172f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 173f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 174f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 175f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return map_class(node->value); 176f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 177f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 178f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyaccess_vector_t string_to_av_perm(security_class_t tclass, const char *s) 179f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 180f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node; 181f074036424618c130dacb3464465a8b40bffef5Stephen Smalley security_class_t kclass = unmap_class(tclass); 182f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 183f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = get_class_cache_entry_value(kclass); 184f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node != NULL) { 185f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t i; 186f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i=0; i<MAXVECTORS && node->perms[i] != NULL; i++) 187f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (strcmp(node->perms[i],s) == 0) 188f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return map_perm(tclass, 1<<i); 189f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 190f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 191f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = EINVAL; 192f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return 0; 193f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 194f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 195f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyconst char *security_class_to_string(security_class_t tclass) 196f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 197f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node; 198f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 199f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tclass = unmap_class(tclass); 200f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 201f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = get_class_cache_entry_value(tclass); 202f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (node) 203f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return node->name; 204f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return NULL; 205f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 206f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 207f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyconst char *security_av_perm_to_string(security_class_t tclass, 208f074036424618c130dacb3464465a8b40bffef5Stephen Smalley access_vector_t av) 209f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 210f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct discover_class_node *node; 211f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t i; 212f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 213f074036424618c130dacb3464465a8b40bffef5Stephen Smalley av = unmap_perm(tclass, av); 214f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tclass = unmap_class(tclass); 215f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 216f074036424618c130dacb3464465a8b40bffef5Stephen Smalley node = get_class_cache_entry_value(tclass); 217f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (av && node) 218f074036424618c130dacb3464465a8b40bffef5Stephen Smalley for (i = 0; i<MAXVECTORS; i++) 219f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if ((1<<i) & av) 220f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return node->perms[i]; 221f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 222f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return NULL; 223f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 224f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 225f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyint security_av_string(security_class_t tclass, access_vector_t av, char **res) 226f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 227f074036424618c130dacb3464465a8b40bffef5Stephen Smalley unsigned int i = 0; 228f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t len = 5; 229f074036424618c130dacb3464465a8b40bffef5Stephen Smalley access_vector_t tmp = av; 230f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int rc = 0; 231f074036424618c130dacb3464465a8b40bffef5Stephen Smalley const char *str; 232f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *ptr; 233f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 234f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* first pass computes the required length */ 235f074036424618c130dacb3464465a8b40bffef5Stephen Smalley while (tmp) { 236f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (tmp & 1) { 237f074036424618c130dacb3464465a8b40bffef5Stephen Smalley str = security_av_perm_to_string(tclass, av & (1<<i)); 238f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (str) 239f074036424618c130dacb3464465a8b40bffef5Stephen Smalley len += strlen(str) + 1; 240f074036424618c130dacb3464465a8b40bffef5Stephen Smalley else { 241f074036424618c130dacb3464465a8b40bffef5Stephen Smalley rc = -1; 242f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = EINVAL; 243f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out; 244f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 245f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 246f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tmp >>= 1; 247f074036424618c130dacb3464465a8b40bffef5Stephen Smalley i++; 248f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 249f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 250f074036424618c130dacb3464465a8b40bffef5Stephen Smalley *res = malloc(len); 251f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!*res) { 252f074036424618c130dacb3464465a8b40bffef5Stephen Smalley rc = -1; 253f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out; 254f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 255f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 256f074036424618c130dacb3464465a8b40bffef5Stephen Smalley /* second pass constructs the string */ 257f074036424618c130dacb3464465a8b40bffef5Stephen Smalley i = 0; 258f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tmp = av; 259f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ptr = *res; 260f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 261f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!av) { 262f074036424618c130dacb3464465a8b40bffef5Stephen Smalley sprintf(ptr, "null"); 263f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out; 264f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 265f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 266f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ptr += sprintf(ptr, "{ "); 267f074036424618c130dacb3464465a8b40bffef5Stephen Smalley while (tmp) { 268f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (tmp & 1) 269f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ptr += sprintf(ptr, "%s ", security_av_perm_to_string( 270f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tclass, av & (1<<i))); 271f074036424618c130dacb3464465a8b40bffef5Stephen Smalley tmp >>= 1; 272f074036424618c130dacb3464465a8b40bffef5Stephen Smalley i++; 273f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 274f074036424618c130dacb3464465a8b40bffef5Stephen Smalley sprintf(ptr, "}"); 275f074036424618c130dacb3464465a8b40bffef5Stephen Smalleyout: 276f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return rc; 277f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 278