• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
gettid(void)12 static pid_t gettid(void)
13 {
14 	return syscall(__NR_gettid);
15 }
16 #endif
17 
getprocattrcon(security_context_t * context,pid_t pid,const char * attr)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 
setprocattrcon(security_context_t context,pid_t pid,const char * attr)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