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