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