147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <unistd.h> 247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <sys/types.h> 347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <fcntl.h> 447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdlib.h> 547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <stdio.h> 647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <errno.h> 747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <string.h> 847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "selinux_internal.h" 947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include "policy.h" 1047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner#include <limits.h> 1147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 1247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turnerint security_canonicalize_context(const char * con, 1347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char ** canoncon) 1447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner{ 1547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char path[PATH_MAX]; 1647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner char *buf; 1747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size_t size; 1847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner int fd, ret; 1947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!selinux_mnt) { 2147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner errno = ENOENT; 2247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return -1; 2347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 2447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 2547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner snprintf(path, sizeof path, "%s/context", selinux_mnt); 2647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner fd = open(path, O_RDWR); 2747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (fd < 0) 2847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return -1; 2947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner size = selinux_page_size; 3147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner buf = malloc(size); 3247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!buf) { 3347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = -1; 3447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out; 3547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 3647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strncpy(buf, con, size); 3747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 3847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = write(fd, buf, strlen(buf) + 1); 3947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (ret < 0) 4047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out2; 4147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 4247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner memset(buf, 0, size); 4347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = read(fd, buf, size - 1); 4447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (ret < 0 && errno == EINVAL) { 4547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner /* Fall back to the original context for kernels 4647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner that do not support the extended interface. */ 4747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner strncpy(buf, con, size); 4847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 4947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 5047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner *canoncon = strdup(buf); 5147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner if (!(*canoncon)) { 5247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = -1; 5347173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner goto out2; 5447173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner } 5547173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner ret = 0; 5647173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner out2: 5747173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner free(buf); 5847173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner out: 5947173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner close(fd); 6047173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner return ret; 6147173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner} 6247173c7d6704f1258b2d85537caa09185f6920c8David 'Digit' Turner 63