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 <ctype.h> 10 #include "selinux_internal.h" 11 #include "policy.h" 12 #include "mapping.h" 13 14 static int object_name_encode(const char *objname, char *buffer, size_t buflen) 15 { 16 int code; 17 size_t offset = 0; 18 19 if (buflen - offset < 1) 20 return -1; 21 buffer[offset++] = ' '; 22 23 do { 24 code = *objname++; 25 26 if (isalnum(code) || code == '\0' || code == '-' || 27 code == '.' || code == '_' || code == '~') { 28 if (buflen - offset < 1) 29 return -1; 30 buffer[offset++] = code; 31 } else if (code == ' ') { 32 if (buflen - offset < 1) 33 return -1; 34 buffer[offset++] = '+'; 35 } else { 36 static const char *table = "0123456789ABCDEF"; 37 int l = (code & 0x0f); 38 int h = (code & 0xf0) >> 4; 39 40 if (buflen - offset < 3) 41 return -1; 42 buffer[offset++] = '%'; 43 buffer[offset++] = table[h]; 44 buffer[offset++] = table[l]; 45 } 46 } while (code != '\0'); 47 48 return 0; 49 } 50 51 int security_compute_create_name_raw(const char * scon, 52 const char * tcon, 53 security_class_t tclass, 54 const char *objname, 55 char ** newcon) 56 { 57 char path[PATH_MAX]; 58 char *buf; 59 size_t size; 60 int fd, ret, len; 61 62 if (!selinux_mnt) { 63 errno = ENOENT; 64 return -1; 65 } 66 67 snprintf(path, sizeof path, "%s/create", selinux_mnt); 68 fd = open(path, O_RDWR); 69 if (fd < 0) 70 return -1; 71 72 size = selinux_page_size; 73 buf = malloc(size); 74 if (!buf) { 75 ret = -1; 76 goto out; 77 } 78 len = snprintf(buf, size, "%s %s %hu", 79 scon, tcon, unmap_class(tclass)); 80 if (objname && 81 object_name_encode(objname, buf + len, size - len) < 0) { 82 errno = ENAMETOOLONG; 83 ret = -1; 84 goto out2; 85 } 86 87 ret = write(fd, buf, strlen(buf)); 88 if (ret < 0) 89 goto out2; 90 91 memset(buf, 0, size); 92 ret = read(fd, buf, size - 1); 93 if (ret < 0) 94 goto out2; 95 96 *newcon = strdup(buf); 97 if (!(*newcon)) { 98 ret = -1; 99 goto out2; 100 } 101 ret = 0; 102 out2: 103 free(buf); 104 out: 105 close(fd); 106 return ret; 107 } 108 hidden_def(security_compute_create_name_raw) 109 110 int security_compute_create_raw(const char * scon, 111 const char * tcon, 112 security_class_t tclass, 113 char ** newcon) 114 { 115 return security_compute_create_name_raw(scon, tcon, tclass, 116 NULL, newcon); 117 } 118 hidden_def(security_compute_create_raw) 119 120 int security_compute_create_name(const char * scon, 121 const char * tcon, 122 security_class_t tclass, 123 const char *objname, 124 char ** newcon) 125 { 126 int ret; 127 char * rscon; 128 char * rtcon; 129 char * rnewcon; 130 131 if (selinux_trans_to_raw_context(scon, &rscon)) 132 return -1; 133 if (selinux_trans_to_raw_context(tcon, &rtcon)) { 134 freecon(rscon); 135 return -1; 136 } 137 138 ret = security_compute_create_name_raw(rscon, rtcon, tclass, 139 objname, &rnewcon); 140 freecon(rscon); 141 freecon(rtcon); 142 if (!ret) { 143 ret = selinux_raw_to_trans_context(rnewcon, newcon); 144 freecon(rnewcon); 145 } 146 147 return ret; 148 } 149 hidden_def(security_compute_create_name) 150 151 int security_compute_create(const char * scon, 152 const char * tcon, 153 security_class_t tclass, 154 char ** newcon) 155 { 156 return security_compute_create_name(scon, tcon, tclass, NULL, newcon); 157 } 158 hidden_def(security_compute_create) 159