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 13int security_compute_relabel_raw(const char * scon, 14 const char * tcon, 15 security_class_t tclass, 16 char ** newcon) 17{ 18 char path[PATH_MAX]; 19 char *buf; 20 size_t size; 21 int fd, ret; 22 23 if (!selinux_mnt) { 24 errno = ENOENT; 25 return -1; 26 } 27 28 snprintf(path, sizeof path, "%s/relabel", selinux_mnt); 29 fd = open(path, O_RDWR | O_CLOEXEC); 30 if (fd < 0) 31 return -1; 32 33 size = selinux_page_size; 34 buf = malloc(size); 35 if (!buf) { 36 ret = -1; 37 goto out; 38 } 39 40 ret = snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass)); 41 if (ret < 0 || (size_t)ret >= size) { 42 errno = EOVERFLOW; 43 ret = -1; 44 goto out2; 45 } 46 47 ret = write(fd, buf, strlen(buf)); 48 if (ret < 0) 49 goto out2; 50 51 memset(buf, 0, size); 52 ret = read(fd, buf, size - 1); 53 if (ret < 0) 54 goto out2; 55 56 *newcon = strdup(buf); 57 if (!*newcon) { 58 ret = -1; 59 goto out2; 60 } 61 ret = 0; 62 out2: 63 free(buf); 64 out: 65 close(fd); 66 return ret; 67} 68 69 70int security_compute_relabel(const char * scon, 71 const char * tcon, 72 security_class_t tclass, 73 char ** newcon) 74{ 75 int ret; 76 char * rscon; 77 char * rtcon; 78 char * rnewcon; 79 80 if (selinux_trans_to_raw_context(scon, &rscon)) 81 return -1; 82 if (selinux_trans_to_raw_context(tcon, &rtcon)) { 83 freecon(rscon); 84 return -1; 85 } 86 87 ret = security_compute_relabel_raw(rscon, rtcon, tclass, &rnewcon); 88 89 freecon(rscon); 90 freecon(rtcon); 91 if (!ret) { 92 ret = selinux_raw_to_trans_context(rnewcon, newcon); 93 freecon(rnewcon); 94 } 95 96 return ret; 97} 98