1 #include <unistd.h> 2 #include <sys/types.h> 3 #include <fcntl.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <errno.h> 7 #include <string.h> 8 #include <limits.h> 9 #include "selinux_internal.h" 10 #include "policy.h" 11 #include "mapping.h" 12 13 int security_compute_av_flags_raw(const char * scon, 14 const char * tcon, 15 security_class_t tclass, 16 access_vector_t requested, 17 struct av_decision *avd) 18 { 19 char path[PATH_MAX]; 20 char *buf; 21 size_t len; 22 int fd, ret; 23 24 if (!selinux_mnt) { 25 errno = ENOENT; 26 return -1; 27 } 28 29 snprintf(path, sizeof path, "%s/access", selinux_mnt); 30 fd = open(path, O_RDWR); 31 if (fd < 0) 32 return -1; 33 34 len = selinux_page_size; 35 buf = malloc(len); 36 if (!buf) { 37 ret = -1; 38 goto out; 39 } 40 41 snprintf(buf, len, "%s %s %hu %x", scon, tcon, 42 unmap_class(tclass), unmap_perm(tclass, requested)); 43 44 ret = write(fd, buf, strlen(buf)); 45 if (ret < 0) 46 goto out2; 47 48 memset(buf, 0, len); 49 ret = read(fd, buf, len - 1); 50 if (ret < 0) 51 goto out2; 52 53 ret = sscanf(buf, "%x %x %x %x %u %x", 54 &avd->allowed, &avd->decided, 55 &avd->auditallow, &avd->auditdeny, 56 &avd->seqno, &avd->flags); 57 if (ret < 5) { 58 ret = -1; 59 goto out2; 60 } else if (ret < 6) 61 avd->flags = 0; 62 63 /* If tclass invalid, kernel sets avd according to deny_unknown flag */ 64 if (tclass != 0) 65 map_decision(tclass, avd); 66 67 ret = 0; 68 out2: 69 free(buf); 70 out: 71 close(fd); 72 return ret; 73 } 74 75 hidden_def(security_compute_av_flags_raw) 76 77 int security_compute_av_raw(const char * scon, 78 const char * tcon, 79 security_class_t tclass, 80 access_vector_t requested, 81 struct av_decision *avd) 82 { 83 struct av_decision lavd; 84 int ret; 85 86 ret = security_compute_av_flags_raw(scon, tcon, tclass, 87 requested, &lavd); 88 if (ret == 0) { 89 avd->allowed = lavd.allowed; 90 avd->decided = lavd.decided; 91 avd->auditallow = lavd.auditallow; 92 avd->auditdeny = lavd.auditdeny; 93 avd->seqno = lavd.seqno; 94 /* NOTE: 95 * We should not return avd->flags via the interface 96 * due to the binary compatibility. 97 */ 98 } 99 return ret; 100 } 101 102 hidden_def(security_compute_av_raw) 103 104 int security_compute_av_flags(const char * scon, 105 const char * tcon, 106 security_class_t tclass, 107 access_vector_t requested, 108 struct av_decision *avd) 109 { 110 char * rscon; 111 char * rtcon; 112 int ret; 113 114 if (selinux_trans_to_raw_context(scon, &rscon)) 115 return -1; 116 if (selinux_trans_to_raw_context(tcon, &rtcon)) { 117 freecon(rscon); 118 return -1; 119 } 120 ret = security_compute_av_flags_raw(rscon, rtcon, tclass, 121 requested, avd); 122 123 freecon(rscon); 124 freecon(rtcon); 125 126 return ret; 127 } 128 129 hidden_def(security_compute_av_flags) 130 131 int security_compute_av(const char * scon, 132 const char * tcon, 133 security_class_t tclass, 134 access_vector_t requested, struct av_decision *avd) 135 { 136 struct av_decision lavd; 137 int ret; 138 139 ret = security_compute_av_flags(scon, tcon, tclass, 140 requested, &lavd); 141 if (ret == 0) 142 { 143 avd->allowed = lavd.allowed; 144 avd->decided = lavd.decided; 145 avd->auditallow = lavd.auditallow; 146 avd->auditdeny = lavd.auditdeny; 147 avd->seqno = lavd.seqno; 148 /* NOTE: 149 * We should not return avd->flags via the interface 150 * due to the binary compatibility. 151 */ 152 } 153 154 return ret; 155 } 156 157 hidden_def(security_compute_av) 158