1 /* 2 * Class and permission mappings. 3 */ 4 5 #include <errno.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <stdarg.h> 9 #include <assert.h> 10 #include <selinux/selinux.h> 11 #include <selinux/avc.h> 12 #include "mapping.h" 13 14 /* 15 * Class and permission mappings 16 */ 17 18 struct selinux_mapping { 19 security_class_t value; /* real, kernel value */ 20 unsigned num_perms; 21 access_vector_t perms[sizeof(access_vector_t) * 8]; 22 }; 23 24 static struct selinux_mapping *current_mapping = NULL; 25 static security_class_t current_mapping_size = 0; 26 27 /* 28 * Mapping setting function 29 */ 30 31 int 32 selinux_set_mapping(struct security_class_mapping *map) 33 { 34 size_t size = sizeof(struct selinux_mapping); 35 security_class_t i, j; 36 unsigned k; 37 38 free(current_mapping); 39 current_mapping = NULL; 40 current_mapping_size = 0; 41 42 if (avc_reset() < 0) 43 goto err; 44 45 /* Find number of classes in the input mapping */ 46 if (!map) { 47 errno = EINVAL; 48 goto err; 49 } 50 i = 0; 51 while (map[i].name) 52 i++; 53 54 /* Allocate space for the class records, plus one for class zero */ 55 current_mapping = (struct selinux_mapping *)calloc(++i, size); 56 if (!current_mapping) 57 goto err; 58 59 /* Store the raw class and permission values */ 60 j = 0; 61 while (map[j].name) { 62 struct security_class_mapping *p_in = map + (j++); 63 struct selinux_mapping *p_out = current_mapping + j; 64 65 p_out->value = string_to_security_class(p_in->name); 66 if (!p_out->value) 67 goto err2; 68 69 k = 0; 70 while (p_in->perms && p_in->perms[k]) { 71 /* An empty permission string skips ahead */ 72 if (!*p_in->perms[k]) { 73 k++; 74 continue; 75 } 76 p_out->perms[k] = string_to_av_perm(p_out->value, 77 p_in->perms[k]); 78 if (!p_out->perms[k]) 79 goto err2; 80 k++; 81 } 82 p_out->num_perms = k; 83 } 84 85 /* Set the mapping size here so the above lookups are "raw" */ 86 current_mapping_size = i; 87 return 0; 88 err2: 89 free(current_mapping); 90 current_mapping = NULL; 91 current_mapping_size = 0; 92 err: 93 return -1; 94 } 95 96 /* 97 * Get real, kernel values from mapped values 98 */ 99 100 security_class_t 101 unmap_class(security_class_t tclass) 102 { 103 if (tclass < current_mapping_size) 104 return current_mapping[tclass].value; 105 106 assert(current_mapping_size == 0); 107 return tclass; 108 } 109 110 access_vector_t 111 unmap_perm(security_class_t tclass, access_vector_t tperm) 112 { 113 if (tclass < current_mapping_size) { 114 unsigned i; 115 access_vector_t kperm = 0; 116 117 for (i=0; i<current_mapping[tclass].num_perms; i++) 118 if (tperm & (1<<i)) { 119 assert(current_mapping[tclass].perms[i]); 120 kperm |= current_mapping[tclass].perms[i]; 121 tperm &= ~(1<<i); 122 } 123 assert(tperm == 0); 124 return kperm; 125 } 126 127 assert(current_mapping_size == 0); 128 return tperm; 129 } 130 131 /* 132 * Get mapped values from real, kernel values 133 */ 134 135 security_class_t 136 map_class(security_class_t kclass) 137 { 138 security_class_t i; 139 140 for (i=0; i<current_mapping_size; i++) 141 if (current_mapping[i].value == kclass) 142 return i; 143 144 assert(current_mapping_size == 0); 145 return kclass; 146 } 147 148 access_vector_t 149 map_perm(security_class_t tclass, access_vector_t kperm) 150 { 151 if (tclass < current_mapping_size) { 152 unsigned i; 153 access_vector_t tperm = 0; 154 155 for (i=0; i<current_mapping[tclass].num_perms; i++) 156 if (kperm & current_mapping[tclass].perms[i]) { 157 tperm |= 1<<i; 158 kperm &= ~current_mapping[tclass].perms[i]; 159 } 160 assert(kperm == 0); 161 return tperm; 162 } 163 164 assert(current_mapping_size == 0); 165 return kperm; 166 } 167 168 void 169 map_decision(security_class_t tclass, struct av_decision *avd) 170 { 171 if (tclass < current_mapping_size) { 172 unsigned i; 173 access_vector_t result; 174 175 for (i=0, result=0; i<current_mapping[tclass].num_perms; i++) 176 if (avd->allowed & current_mapping[tclass].perms[i]) 177 result |= 1<<i; 178 avd->allowed = result; 179 180 for (i=0, result=0; i<current_mapping[tclass].num_perms; i++) 181 if (avd->decided & current_mapping[tclass].perms[i]) 182 result |= 1<<i; 183 avd->decided = result; 184 185 for (i=0, result=0; i<current_mapping[tclass].num_perms; i++) 186 if (avd->auditallow & current_mapping[tclass].perms[i]) 187 result |= 1<<i; 188 avd->auditallow = result; 189 190 for (i=0, result=0; i<current_mapping[tclass].num_perms; i++) 191 if (avd->auditdeny & current_mapping[tclass].perms[i]) 192 result |= 1<<i; 193 avd->auditdeny = result; 194 } 195 } 196