blob: 6c2c5a88a2fc66be0181e36e66ed7fce5048fe7a [file] [log] [blame]
Stephen Smalleyf0740362012-01-04 12:30:47 -05001#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
12static pid_t gettid(void)
13{
14 return syscall(__NR_gettid);
15}
16#endif
17
18static 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
76static 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
137all_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)