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 "selinux_internal.h" 9#include "policy.h" 10#include <limits.h> 11 12int security_canonicalize_context_raw(const char * con, 13 char ** canoncon) 14{ 15 char path[PATH_MAX]; 16 char *buf; 17 size_t size; 18 int fd, ret; 19 20 if (!selinux_mnt) { 21 errno = ENOENT; 22 return -1; 23 } 24 25 snprintf(path, sizeof path, "%s/context", selinux_mnt); 26 fd = open(path, O_RDWR | O_CLOEXEC); 27 if (fd < 0) 28 return -1; 29 30 size = selinux_page_size; 31 buf = malloc(size); 32 if (!buf) { 33 ret = -1; 34 goto out; 35 } 36 if (strlcpy(buf, con, size) >= size) { 37 errno = EOVERFLOW; 38 ret = -1; 39 goto out2; 40 } 41 42 ret = write(fd, buf, strlen(buf) + 1); 43 if (ret < 0) 44 goto out2; 45 46 memset(buf, 0, size); 47 ret = read(fd, buf, size - 1); 48 if (ret < 0 && errno == EINVAL) { 49 /* Fall back to the original context for kernels 50 that do not support the extended interface. */ 51 strncpy(buf, con, size); 52 } 53 54 *canoncon = strdup(buf); 55 if (!(*canoncon)) { 56 ret = -1; 57 goto out2; 58 } 59 ret = 0; 60 out2: 61 free(buf); 62 out: 63 close(fd); 64 return ret; 65} 66 67 68int security_canonicalize_context(const char * con, 69 char ** canoncon) 70{ 71 int ret; 72 char * rcon; 73 char * rcanoncon; 74 75 if (selinux_trans_to_raw_context(con, &rcon)) 76 return -1; 77 78 ret = security_canonicalize_context_raw(rcon, &rcanoncon); 79 80 freecon(rcon); 81 if (!ret) { 82 ret = selinux_raw_to_trans_context(rcanoncon, canoncon); 83 freecon(rcanoncon); 84 } 85 86 return ret; 87} 88 89