Home | History | Annotate | Download | only in src
      1 #include <sys/syscall.h>
      2 #include <unistd.h>
      3 #include <fcntl.h>
      4 #include <string.h>
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <errno.h>
      8 #include "selinux_internal.h"
      9 #include "policy.h"
     10 
     11 #ifdef HOST
     12 static pid_t gettid(void)
     13 {
     14 	return syscall(__NR_gettid);
     15 }
     16 #endif
     17 
     18 static int openattr(pid_t pid, const char *attr, int flags)
     19 {
     20 	int fd, rc;
     21 	char *path;
     22 	pid_t tid;
     23 
     24 	if (pid > 0) {
     25 		rc = asprintf(&path, "/proc/%d/attr/%s", pid, attr);
     26 	} else if (pid == 0) {
     27 		rc = asprintf(&path, "/proc/thread-self/attr/%s", attr);
     28 		if (rc < 0)
     29 			return -1;
     30 		fd = open(path, flags | O_CLOEXEC);
     31 		if (fd >= 0 || errno != ENOENT)
     32 			goto out;
     33 		free(path);
     34 		tid = gettid();
     35 		rc = asprintf(&path, "/proc/self/task/%d/attr/%s", tid, attr);
     36 	} else {
     37 		errno = EINVAL;
     38 		return -1;
     39 	}
     40 	if (rc < 0)
     41 		return -1;
     42 
     43 	fd = open(path, flags | O_CLOEXEC);
     44 out:
     45 	free(path);
     46 	return fd;
     47 }
     48 
     49 static int getprocattrcon(char ** context,
     50 			  pid_t pid, const char *attr)
     51 {
     52 	char *buf;
     53 	size_t size;
     54 	int fd;
     55 	ssize_t ret;
     56 	int errno_hold;
     57 
     58 	fd = openattr(pid, attr, O_RDONLY);
     59 	if (fd < 0)
     60 		return -1;
     61 
     62 	size = selinux_page_size;
     63 	buf = malloc(size);
     64 	if (!buf) {
     65 		ret = -1;
     66 		goto out;
     67 	}
     68 	memset(buf, 0, size);
     69 
     70 	do {
     71 		ret = read(fd, buf, size - 1);
     72 	} while (ret < 0 && errno == EINTR);
     73 	if (ret < 0)
     74 		goto out2;
     75 
     76 	if (ret == 0) {
     77 		*context = NULL;
     78 		goto out2;
     79 	}
     80 
     81 	*context = strdup(buf);
     82 	if (!(*context)) {
     83 		ret = -1;
     84 		goto out2;
     85 	}
     86 	ret = 0;
     87       out2:
     88 	free(buf);
     89       out:
     90 	errno_hold = errno;
     91 	close(fd);
     92 	errno = errno_hold;
     93 	return ret;
     94 }
     95 
     96 static int setprocattrcon(const char * context,
     97 			  pid_t pid, const char *attr)
     98 {
     99 	int fd;
    100 	ssize_t ret;
    101 	int errno_hold;
    102 
    103 	fd = openattr(pid, attr, O_RDWR);
    104 	if (fd < 0)
    105 		return -1;
    106 	if (context)
    107 		do {
    108 			ret = write(fd, context, strlen(context) + 1);
    109 		} while (ret < 0 && errno == EINTR);
    110 	else
    111 		do {
    112 			ret = write(fd, NULL, 0);	/* clear */
    113 		} while (ret < 0 && errno == EINTR);
    114 	errno_hold = errno;
    115 	close(fd);
    116 	errno = errno_hold;
    117 	if (ret < 0)
    118 		return -1;
    119 	else
    120 		return 0;
    121 }
    122 
    123 #define getselfattr_def(fn, attr) \
    124 	int get##fn(char **c) \
    125 	{ \
    126 		return getprocattrcon(c, 0, #attr); \
    127 	}
    128 
    129 #define setselfattr_def(fn, attr) \
    130 	int set##fn(const char * c) \
    131 	{ \
    132 		return setprocattrcon(c, 0, #attr); \
    133 	}
    134 
    135 #define all_selfattr_def(fn, attr) \
    136 	getselfattr_def(fn, attr)	 \
    137 	setselfattr_def(fn, attr)
    138 
    139 #define getpidattr_def(fn, attr) \
    140 	int get##fn(pid_t pid, char **c)	\
    141 	{ \
    142 		if (pid <= 0) { \
    143 			errno = EINVAL; \
    144 			return -1; \
    145 		} else { \
    146 			return getprocattrcon(c, pid, #attr); \
    147 		} \
    148 	}
    149 
    150 all_selfattr_def(con, current)
    151     getpidattr_def(pidcon, current)
    152     getselfattr_def(prevcon, prev)
    153     all_selfattr_def(execcon, exec)
    154     all_selfattr_def(fscreatecon, fscreate)
    155     all_selfattr_def(sockcreatecon, sockcreate)
    156     all_selfattr_def(keycreatecon, keycreate)
    157 
    158     hidden_def(getcon_raw)
    159     hidden_def(getcon)
    160     hidden_def(getexeccon_raw)
    161     hidden_def(getfilecon_raw)
    162     hidden_def(getfilecon)
    163     hidden_def(getfscreatecon_raw)
    164     hidden_def(getkeycreatecon_raw)
    165     hidden_def(getpeercon_raw)
    166     hidden_def(getpidcon_raw)
    167     hidden_def(getprevcon_raw)
    168     hidden_def(getprevcon)
    169     hidden_def(getsockcreatecon_raw)
    170     hidden_def(setcon_raw)
    171     hidden_def(setexeccon_raw)
    172     hidden_def(setexeccon)
    173     hidden_def(setfilecon_raw)
    174     hidden_def(setfscreatecon_raw)
    175     hidden_def(setkeycreatecon_raw)
    176     hidden_def(setsockcreatecon_raw)
    177