113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Author: Trusted Computer Solutions, Inc. 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Modified: 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Yuichi Nakamura <ynakam@hitachisoft.jp> 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle - Stubs are used when DISABLE_SETRANS is defined, 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle it is to reduce size for such as embedded devices. 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle*/ 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h> 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/socket.h> 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/un.h> 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h> 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <netdb.h> 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fcntl.h> 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <ctype.h> 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h> 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "dso.h" 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "selinux_internal.h" 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "setrans_internal.h" 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#ifndef DISABLE_SETRANS 26a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalleystatic unsigned char has_setrans; 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle// Simple cache 299eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic __thread char * prev_t2r_trans = NULL; 309eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic __thread char * prev_t2r_raw = NULL; 319eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic __thread char * prev_r2t_trans = NULL; 329eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic __thread char * prev_r2t_raw = NULL; 331ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalleystatic __thread char *prev_r2c_trans = NULL; 349eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic __thread char * prev_r2c_raw = NULL; 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 368c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalleystatic pthread_once_t once = PTHREAD_ONCE_INIT; 37a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walshstatic pthread_key_t destructor_key; 381629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walshstatic int destructor_key_initialized = 0; 39a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walshstatic __thread char destructor_initialized; 408c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalley 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * setransd_open 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This function opens a socket to the setransd. 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Returns: on success, a file descriptor ( >= 0 ) to the socket 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * on error, a negative value 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int setransd_open(void) 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct sockaddr_un addr; 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int fd; 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#ifdef SOCK_CLOEXEC 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fd = socket(PF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0 && errno == EINVAL) 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#endif 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle { 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fd = socket(PF_UNIX, SOCK_STREAM, 0); 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd >= 0) 59aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris if (fcntl(fd, F_SETFD, FD_CLOEXEC)) { 60aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris close(fd); 61aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris return -1; 62aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris } 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0) 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(&addr, 0, sizeof(addr)); 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle addr.sun_family = AF_UNIX; 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle strncpy(addr.sun_path, SETRANS_UNIX_SOCKET, sizeof(addr.sun_path)); 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle close(fd); 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return fd; 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Returns: 0 on success, <0 on failure */ 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlesend_request(int fd, uint32_t function, const char *data1, const char *data2) 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct msghdr msgh; 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct iovec iov[5]; 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t data1_size; 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t data2_size; 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ssize_t count, expected; 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0) 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!data1) 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data1 = ""; 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!data2) 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data2 = ""; 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data1_size = strlen(data1) + 1; 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data2_size = strlen(data2) + 1; 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[0].iov_base = &function; 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[0].iov_len = sizeof(function); 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[1].iov_base = &data1_size; 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[1].iov_len = sizeof(data1_size); 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[2].iov_base = &data2_size; 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[2].iov_len = sizeof(data2_size); 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[3].iov_base = (char *)data1; 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[3].iov_len = data1_size; 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[4].iov_base = (char *)data2; 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle iov[4].iov_len = data2_size; 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle memset(&msgh, 0, sizeof(msgh)); 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle msgh.msg_iov = iov; 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle msgh.msg_iovlen = sizeof(iov) / sizeof(iov[0]); 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expected = 0; 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < sizeof(iov) / sizeof(iov[0]); i++) 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle expected += iov[i].iov_len; 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (((count = sendmsg(fd, &msgh, MSG_NOSIGNAL)) < 0) 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle && (errno == EINTR)) ; 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (count < 0 || count != expected) 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Returns: 0 on success, <0 on failure */ 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlereceive_response(int fd, uint32_t function, char **outdata, int32_t * ret_val) 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct iovec resp_hdr[3]; 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t func; 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle uint32_t data_size; 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *data; 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct iovec resp_data; 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ssize_t count; 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0) 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[0].iov_base = &func; 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[0].iov_len = sizeof(func); 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[1].iov_base = &data_size; 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[1].iov_len = sizeof(data_size); 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[2].iov_base = ret_val; 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_hdr[2].iov_len = sizeof(*ret_val); 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (((count = readv(fd, resp_hdr, 3)) < 0) && (errno == EINTR)) ; 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (count != (sizeof(func) + sizeof(data_size) + sizeof(*ret_val))) { 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (func != function || !data_size || data_size > MAX_DATA_BUF) { 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data = malloc(data_size); 157aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris if (!data) 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 159aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris /* coveriety doesn't realize that data will be initialized in readv */ 160aa62cd60f7192123b509c2518e7a2083e34a65a2Eric Paris memset(data, 0, data_size); 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_data.iov_base = data; 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle resp_data.iov_len = data_size; 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (((count = readv(fd, &resp_data, 1))) < 0 && (errno == EINTR)) ; 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (count < 0 || (uint32_t) count != data_size || 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle data[data_size - 1] != '\0') { 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(data); 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *outdata = data; 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1756a17cfaafcdab82c9909eccff56968913b36a631KaiGai Koheistatic int raw_to_trans_context(const char *raw, char **transp) 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int32_t ret_val; 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int fd; 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = NULL; 18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fd = setransd_open(); 18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0) 18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return fd; 18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = send_request(fd, RAW_TO_TRANS_CONTEXT, raw, NULL); 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = receive_response(fd, RAW_TO_TRANS_CONTEXT, transp, &ret_val); 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = ret_val; 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle close(fd); 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2016a17cfaafcdab82c9909eccff56968913b36a631KaiGai Koheistatic int trans_to_raw_context(const char *trans, char **rawp) 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int ret; 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int32_t ret_val; 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int fd; 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = NULL; 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fd = setransd_open(); 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fd < 0) 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return fd; 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = send_request(fd, TRANS_TO_RAW_CONTEXT, trans, NULL); 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = receive_response(fd, TRANS_TO_RAW_CONTEXT, rawp, &ret_val); 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (ret) 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ret = ret_val; 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle close(fd); 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return ret; 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2266a17cfaafcdab82c9909eccff56968913b36a631KaiGai Koheistatic int raw_context_to_color(const char *raw, char **colors) 227cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh{ 228cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh int ret; 229cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh int32_t ret_val; 230cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh int fd; 231cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 232cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh fd = setransd_open(); 233cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (fd < 0) 234cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh return fd; 235cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 236cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh ret = send_request(fd, RAW_CONTEXT_TO_COLOR, raw, NULL); 237cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (ret) 238cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh goto out; 239cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 240cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh ret = receive_response(fd, RAW_CONTEXT_TO_COLOR, colors, &ret_val); 241cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (ret) 242cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh goto out; 243cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 244cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh ret = ret_val; 245cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walshout: 246cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh close(fd); 247cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh return ret; 248cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh} 249cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 250a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walshstatic void setrans_thread_destructor(void __attribute__((unused)) *unused) 251a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh{ 252a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_t2r_trans); 253a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_t2r_raw); 254a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_r2t_trans); 255a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_r2t_raw); 256a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_r2c_trans); 257a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh free(prev_r2c_raw); 258a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh} 259a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh 260da5e7e3b81c8300f597d01907d1b228e51ebe8f9Daniel P. Berrangevoid __attribute__((destructor)) setrans_lib_destructor(void); 261da5e7e3b81c8300f597d01907d1b228e51ebe8f9Daniel P. Berrange 262a4f84109b51263599a284b167bf04e088e7da95dLaurent Bigonvillevoid hidden __attribute__((destructor)) setrans_lib_destructor(void) 263f0b3127ca3c99ae218dba43a6e3f7430081c412bEamon Walsh{ 264a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) 265a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley return; 2661629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walsh if (destructor_key_initialized) 2671629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walsh __selinux_key_delete(destructor_key); 268f0b3127ca3c99ae218dba43a6e3f7430081c412bEamon Walsh} 269f0b3127ca3c99ae218dba43a6e3f7430081c412bEamon Walsh 270a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walshstatic inline void init_thread_destructor(void) 271a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh{ 272a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) 273a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley return; 274a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh if (destructor_initialized == 0) { 275a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh __selinux_setspecific(destructor_key, (void *)1); 276a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh destructor_initialized = 1; 277a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh } 278a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh} 279a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh 2808c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalleystatic void init_context_translations(void) 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 282a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley has_setrans = (access(SETRANS_UNIX_SOCKET, F_OK) == 0); 283a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) 284a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley return; 2851629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walsh if (__selinux_key_create(&destructor_key, setrans_thread_destructor) == 0) 2861629d2f89a8c5f758413b87b94740aaaa5f21144Daniel J Walsh destructor_key_initialized = 1; 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2899eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_trans_to_raw_context(const char * trans, 2909eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalley char ** rawp) 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!trans) { 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = NULL; 29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2978c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalley __selinux_once(once, init_context_translations); 298a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh init_thread_destructor(); 2998c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalley 300a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) { 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = strdup(trans); 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3051ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (prev_t2r_trans && strcmp(prev_t2r_trans, trans) == 0) { 3061ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley *rawp = strdup(prev_t2r_raw); 3071ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } else { 3081ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_t2r_trans); 3091ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_t2r_trans = NULL; 3101ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_t2r_raw); 3111ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_t2r_raw = NULL; 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (trans_to_raw_context(trans, rawp)) 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = strdup(trans); 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*rawp) { 3151ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_t2r_trans = strdup(trans); 3161ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_t2r_trans) 3171ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley goto out; 3181ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_t2r_raw = strdup(*rawp); 3191ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_t2r_raw) { 3201ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_t2r_trans); 3211ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_t2r_trans = NULL; 3221ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *rawp ? 0 : -1; 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_trans_to_raw_context) 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3319eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_raw_to_trans_context(const char * raw, 3329eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalley char ** transp) 33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!raw) { 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = NULL; 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3398c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalley __selinux_once(once, init_context_translations); 340a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh init_thread_destructor(); 3418c372f665db44cf753bb299e2ee7dcf6143b9e9eStephen Smalley 342a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) { 34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = strdup(raw); 34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto out; 34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3471ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (prev_r2t_raw && strcmp(prev_r2t_raw, raw) == 0) { 3481ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley *transp = strdup(prev_r2t_trans); 3491ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } else { 3501ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2t_raw); 3511ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2t_raw = NULL; 3521ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2t_trans); 3531ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2t_trans = NULL; 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (raw_to_trans_context(raw, transp)) 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = strdup(raw); 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*transp) { 3571ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2t_raw = strdup(raw); 3581ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_r2t_raw) 3591ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley goto out; 3601ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2t_trans = strdup(*transp); 3611ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_r2t_trans) { 3621ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2t_raw); 3631ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2t_raw = NULL; 3641ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } 36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle out: 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *transp ? 0 : -1; 36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_raw_to_trans_context) 372cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 3739eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_raw_context_to_color(const char * raw, char **transp) 374cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh{ 375cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (!raw) { 376cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh *transp = NULL; 377cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh return -1; 378cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh } 379cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 380a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh __selinux_once(once, init_context_translations); 381a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh init_thread_destructor(); 382a29ff33baf366825c0fbe721d30b12b5b96a64e1Eamon Walsh 383a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley if (!has_setrans) { 384a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley *transp = strdup(raw); 385a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley goto out; 386a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley } 387a03f006d7e02a394dcaa55fc4fab6d3d46890224Stephen Smalley 3881ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (prev_r2c_raw && strcmp(prev_r2c_raw, raw) == 0) { 3891ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley *transp = strdup(prev_r2c_trans); 3901ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } else { 3911ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2c_raw); 3921ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2c_raw = NULL; 3931ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2c_trans); 3941ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2c_trans = NULL; 395cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (raw_context_to_color(raw, transp)) 396cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh return -1; 397cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh if (*transp) { 3981ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2c_raw = strdup(raw); 3991ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_r2c_raw) 4001ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley goto out; 4011ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2c_trans = strdup(*transp); 4021ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley if (!prev_r2c_trans) { 4031ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley free(prev_r2c_raw); 4041ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley prev_r2c_raw = NULL; 4051ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley } 406cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh } 407cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh } 4081ac1ff6382505fa1e245fdc9c91b2448a7843101Stephen Smalley out: 409cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh return *transp ? 0 : -1; 410cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh} 411cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walsh 412cfa3cb6fa5d0cc00fde75ee74ec2da577f62e141Eamon Walshhidden_def(selinux_raw_context_to_color) 41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#else /*DISABLE_SETRANS*/ 41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4159eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_trans_to_raw_context(const char * trans, 4169eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalley char ** rawp) 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!trans) { 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = NULL; 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *rawp = strdup(trans); 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *rawp ? 0 : -1; 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_trans_to_raw_context) 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4309eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint selinux_raw_to_trans_context(const char * raw, 4319eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalley char ** transp) 43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!raw) { 43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = NULL; 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *transp = strdup(raw); 43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return *transp ? 0 : -1; 44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlehidden_def(selinux_raw_to_trans_context) 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#endif /*DISABLE_SETRANS*/ 444