Home | History | Annotate | Download | only in src
      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 <ctype.h>
     10 #include "selinux_internal.h"
     11 #include "policy.h"
     12 #include "mapping.h"
     13 
     14 static int object_name_encode(const char *objname, char *buffer, size_t buflen)
     15 {
     16 	int	code;
     17 	size_t	offset = 0;
     18 
     19 	if (buflen - offset < 1)
     20 		return -1;
     21 	buffer[offset++] = ' ';
     22 
     23 	do {
     24 		code = *objname++;
     25 
     26 		if (isalnum(code) || code == '\0' || code == '-' ||
     27 		    code == '.' || code == '_' || code == '~') {
     28 			if (buflen - offset < 1)
     29 				return -1;
     30 			buffer[offset++] = code;
     31 		} else if (code == ' ') {
     32 			if (buflen - offset < 1)
     33 				return -1;
     34 			buffer[offset++] = '+';
     35 		} else {
     36 			static const char *table = "0123456789ABCDEF";
     37 			int	l = (code & 0x0f);
     38 			int	h = (code & 0xf0) >> 4;
     39 
     40 			if (buflen - offset < 3)
     41 				return -1;
     42 			buffer[offset++] = '%';
     43 			buffer[offset++] = table[h];
     44 			buffer[offset++] = table[l];
     45 		}
     46 	} while (code != '\0');
     47 
     48 	return 0;
     49 }
     50 
     51 int security_compute_create_name_raw(const char * scon,
     52 				     const char * tcon,
     53 				     security_class_t tclass,
     54 				     const char *objname,
     55 				     char ** newcon)
     56 {
     57 	char path[PATH_MAX];
     58 	char *buf;
     59 	size_t size;
     60 	int fd, ret, len;
     61 
     62 	if (!selinux_mnt) {
     63 		errno = ENOENT;
     64 		return -1;
     65 	}
     66 
     67 	snprintf(path, sizeof path, "%s/create", selinux_mnt);
     68 	fd = open(path, O_RDWR | O_CLOEXEC);
     69 	if (fd < 0)
     70 		return -1;
     71 
     72 	size = selinux_page_size;
     73 	buf = malloc(size);
     74 	if (!buf) {
     75 		ret = -1;
     76 		goto out;
     77 	}
     78 	len = snprintf(buf, size, "%s %s %hu",
     79 		       scon, tcon, unmap_class(tclass));
     80 	if (objname &&
     81 	    object_name_encode(objname, buf + len, size - len) < 0) {
     82 		errno = ENAMETOOLONG;
     83 		ret = -1;
     84 		goto out2;
     85 	}
     86 
     87 	ret = write(fd, buf, strlen(buf));
     88 	if (ret < 0)
     89 		goto out2;
     90 
     91 	memset(buf, 0, size);
     92 	ret = read(fd, buf, size - 1);
     93 	if (ret < 0)
     94 		goto out2;
     95 
     96 	*newcon = strdup(buf);
     97 	if (!(*newcon)) {
     98 		ret = -1;
     99 		goto out2;
    100 	}
    101 	ret = 0;
    102       out2:
    103 	free(buf);
    104       out:
    105 	close(fd);
    106 	return ret;
    107 }
    108 hidden_def(security_compute_create_name_raw)
    109 
    110 int security_compute_create_raw(const char * scon,
    111 				const char * tcon,
    112 				security_class_t tclass,
    113 				char ** newcon)
    114 {
    115 	return security_compute_create_name_raw(scon, tcon, tclass,
    116 						NULL, newcon);
    117 }
    118 hidden_def(security_compute_create_raw)
    119 
    120 int security_compute_create_name(const char * scon,
    121 				 const char * tcon,
    122 				 security_class_t tclass,
    123 				 const char *objname,
    124 				 char ** newcon)
    125 {
    126 	int ret;
    127 	char * rscon;
    128 	char * rtcon;
    129 	char * rnewcon;
    130 
    131 	if (selinux_trans_to_raw_context(scon, &rscon))
    132 		return -1;
    133 	if (selinux_trans_to_raw_context(tcon, &rtcon)) {
    134 		freecon(rscon);
    135 		return -1;
    136 	}
    137 
    138 	ret = security_compute_create_name_raw(rscon, rtcon, tclass,
    139 					       objname, &rnewcon);
    140 	freecon(rscon);
    141 	freecon(rtcon);
    142 	if (!ret) {
    143 		ret = selinux_raw_to_trans_context(rnewcon, newcon);
    144 		freecon(rnewcon);
    145 	}
    146 
    147 	return ret;
    148 }
    149 hidden_def(security_compute_create_name)
    150 
    151 int security_compute_create(const char * scon,
    152 				const char * tcon,
    153 			    security_class_t tclass,
    154 				char ** newcon)
    155 {
    156 	return security_compute_create_name(scon, tcon, tclass, NULL, newcon);
    157 }
    158 hidden_def(security_compute_create)
    159