16cd6a6acSopenharmony_ci#include <unistd.h> 26cd6a6acSopenharmony_ci#include <sys/types.h> 36cd6a6acSopenharmony_ci#include <fcntl.h> 46cd6a6acSopenharmony_ci#include <stdlib.h> 56cd6a6acSopenharmony_ci#include <stdio.h> 66cd6a6acSopenharmony_ci#include <errno.h> 76cd6a6acSopenharmony_ci#include <string.h> 86cd6a6acSopenharmony_ci#include <limits.h> 96cd6a6acSopenharmony_ci#include "selinux_internal.h" 106cd6a6acSopenharmony_ci#include "policy.h" 116cd6a6acSopenharmony_ci#include "mapping.h" 126cd6a6acSopenharmony_ci 136cd6a6acSopenharmony_ciint security_compute_relabel_raw(const char * scon, 146cd6a6acSopenharmony_ci const char * tcon, 156cd6a6acSopenharmony_ci security_class_t tclass, 166cd6a6acSopenharmony_ci char ** newcon) 176cd6a6acSopenharmony_ci{ 186cd6a6acSopenharmony_ci char path[PATH_MAX]; 196cd6a6acSopenharmony_ci char *buf; 206cd6a6acSopenharmony_ci size_t size; 216cd6a6acSopenharmony_ci int fd, ret; 226cd6a6acSopenharmony_ci 236cd6a6acSopenharmony_ci if (!selinux_mnt) { 246cd6a6acSopenharmony_ci errno = ENOENT; 256cd6a6acSopenharmony_ci return -1; 266cd6a6acSopenharmony_ci } 276cd6a6acSopenharmony_ci 286cd6a6acSopenharmony_ci snprintf(path, sizeof path, "%s/relabel", selinux_mnt); 296cd6a6acSopenharmony_ci fd = open(path, O_RDWR | O_CLOEXEC); 306cd6a6acSopenharmony_ci if (fd < 0) 316cd6a6acSopenharmony_ci return -1; 326cd6a6acSopenharmony_ci 336cd6a6acSopenharmony_ci size = selinux_page_size; 346cd6a6acSopenharmony_ci buf = malloc(size); 356cd6a6acSopenharmony_ci if (!buf) { 366cd6a6acSopenharmony_ci ret = -1; 376cd6a6acSopenharmony_ci goto out; 386cd6a6acSopenharmony_ci } 396cd6a6acSopenharmony_ci 406cd6a6acSopenharmony_ci ret = snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass)); 416cd6a6acSopenharmony_ci if (ret < 0 || (size_t)ret >= size) { 426cd6a6acSopenharmony_ci errno = EOVERFLOW; 436cd6a6acSopenharmony_ci ret = -1; 446cd6a6acSopenharmony_ci goto out2; 456cd6a6acSopenharmony_ci } 466cd6a6acSopenharmony_ci 476cd6a6acSopenharmony_ci ret = write(fd, buf, strlen(buf)); 486cd6a6acSopenharmony_ci if (ret < 0) 496cd6a6acSopenharmony_ci goto out2; 506cd6a6acSopenharmony_ci 516cd6a6acSopenharmony_ci memset(buf, 0, size); 526cd6a6acSopenharmony_ci ret = read(fd, buf, size - 1); 536cd6a6acSopenharmony_ci if (ret < 0) 546cd6a6acSopenharmony_ci goto out2; 556cd6a6acSopenharmony_ci 566cd6a6acSopenharmony_ci *newcon = strdup(buf); 576cd6a6acSopenharmony_ci if (!*newcon) { 586cd6a6acSopenharmony_ci ret = -1; 596cd6a6acSopenharmony_ci goto out2; 606cd6a6acSopenharmony_ci } 616cd6a6acSopenharmony_ci ret = 0; 626cd6a6acSopenharmony_ci out2: 636cd6a6acSopenharmony_ci free(buf); 646cd6a6acSopenharmony_ci out: 656cd6a6acSopenharmony_ci close(fd); 666cd6a6acSopenharmony_ci return ret; 676cd6a6acSopenharmony_ci} 686cd6a6acSopenharmony_ci 696cd6a6acSopenharmony_ci 706cd6a6acSopenharmony_ciint security_compute_relabel(const char * scon, 716cd6a6acSopenharmony_ci const char * tcon, 726cd6a6acSopenharmony_ci security_class_t tclass, 736cd6a6acSopenharmony_ci char ** newcon) 746cd6a6acSopenharmony_ci{ 756cd6a6acSopenharmony_ci int ret; 766cd6a6acSopenharmony_ci char * rscon; 776cd6a6acSopenharmony_ci char * rtcon; 786cd6a6acSopenharmony_ci char * rnewcon; 796cd6a6acSopenharmony_ci 806cd6a6acSopenharmony_ci if (selinux_trans_to_raw_context(scon, &rscon)) 816cd6a6acSopenharmony_ci return -1; 826cd6a6acSopenharmony_ci if (selinux_trans_to_raw_context(tcon, &rtcon)) { 836cd6a6acSopenharmony_ci freecon(rscon); 846cd6a6acSopenharmony_ci return -1; 856cd6a6acSopenharmony_ci } 866cd6a6acSopenharmony_ci 876cd6a6acSopenharmony_ci ret = security_compute_relabel_raw(rscon, rtcon, tclass, &rnewcon); 886cd6a6acSopenharmony_ci 896cd6a6acSopenharmony_ci freecon(rscon); 906cd6a6acSopenharmony_ci freecon(rtcon); 916cd6a6acSopenharmony_ci if (!ret) { 926cd6a6acSopenharmony_ci ret = selinux_raw_to_trans_context(rnewcon, newcon); 936cd6a6acSopenharmony_ci freecon(rnewcon); 946cd6a6acSopenharmony_ci } 956cd6a6acSopenharmony_ci 966cd6a6acSopenharmony_ci return ret; 976cd6a6acSopenharmony_ci} 98