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_validatetrans_raw(const char *scon, 14 const char *tcon, 15 security_class_t tclass, 16 const char *newcon) 17{ 18 char path[PATH_MAX]; 19 char *buf = NULL; 20 int size, bufsz; 21 int fd, ret = -1; 22 errno = ENOENT; 23 24 if (!selinux_mnt) { 25 return -1; 26 } 27 28 snprintf(path, sizeof path, "%s/validatetrans", selinux_mnt); 29 fd = open(path, O_WRONLY | O_CLOEXEC); 30 if (fd < 0) { 31 return -1; 32 } 33 34 errno = EINVAL; 35 size = selinux_page_size; 36 buf = malloc(size); 37 if (!buf) { 38 goto out; 39 } 40 41 bufsz = snprintf(buf, size, "%s %s %hu %s", scon, tcon, unmap_class(tclass), newcon); 42 if (bufsz >= size || bufsz < 0) { 43 // It got truncated or there was an encoding error 44 goto out; 45 } 46 47 // clear errno for write() 48 errno = 0; 49 ret = write(fd, buf, strlen(buf)); 50 if (ret > 0) { 51 // The kernel returns the bytes written on success, not 0 as noted in the commit message 52 ret = 0; 53 } 54out: 55 free(buf); 56 close(fd); 57 return ret; 58} 59 60 61int security_validatetrans(const char *scon, 62 const char *tcon, 63 security_class_t tclass, 64 const char *newcon) 65{ 66 int ret = -1; 67 char *rscon = NULL; 68 char *rtcon = NULL; 69 char *rnewcon = NULL; 70 71 if (selinux_trans_to_raw_context(scon, &rscon)) { 72 goto out; 73 } 74 75 if (selinux_trans_to_raw_context(tcon, &rtcon)) { 76 goto out; 77 } 78 79 if (selinux_trans_to_raw_context(newcon, &rnewcon)) { 80 goto out; 81 } 82 83 ret = security_validatetrans_raw(rscon, rtcon, tclass, rnewcon); 84 85out: 86 freecon(rnewcon); 87 freecon(rtcon); 88 freecon(rscon); 89 90 return ret; 91} 92 93