• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2017 The Android Open Source Project
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "system.h"
17 
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <net/if.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/prctl.h>
26 #include <sys/socket.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 
30 #include "util.h"
31 
32 #ifdef HAVE_SECUREBITS_H
33 #include <linux/securebits.h>
34 #else
35 #define SECURE_ALL_BITS 0x55
36 #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1)
37 #endif
38 
39 #define SECURE_BITS_NO_AMBIENT 0x15
40 #define SECURE_LOCKS_NO_AMBIENT (SECURE_BITS_NO_AMBIENT << 1)
41 
42 /*
43  * Assert the value of SECURE_ALL_BITS at compile-time.
44  * Android devices are currently compiled against 4.4 kernel headers. Kernel 4.3
45  * added a new securebit.
46  * When a new securebit is added, the new SECURE_ALL_BITS mask will return EPERM
47  * when used on older kernels. The compile-time assert will catch this situation
48  * at compile time.
49  */
50 #if defined(__ANDROID__)
51 _Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55.");
52 #endif
53 
lock_securebits(uint64_t skip_mask)54 int lock_securebits(uint64_t skip_mask)
55 {
56 	/*
57 	 * Ambient capabilities can only be raised if they're already present
58 	 * in the permitted *and* inheritable set. Therefore, we don't really
59 	 * need to lock the NO_CAP_AMBIENT_RAISE securebit, since we are already
60 	 * configuring the permitted and inheritable set.
61 	 */
62 	unsigned long securebits =
63 	    (SECURE_BITS_NO_AMBIENT | SECURE_LOCKS_NO_AMBIENT) & ~skip_mask;
64 	if (!securebits) {
65 		return 0;
66 	}
67 	int securebits_ret = prctl(PR_SET_SECUREBITS, securebits);
68 	if (securebits_ret < 0) {
69 		pwarn("prctl(PR_SET_SECUREBITS) failed");
70 		return -1;
71 	}
72 
73 	return 0;
74 }
75 
write_proc_file(pid_t pid,const char * content,const char * basename)76 int write_proc_file(pid_t pid, const char *content, const char *basename)
77 {
78 	int fd, ret;
79 	size_t sz, len;
80 	ssize_t written;
81 	char filename[32];
82 
83 	sz = sizeof(filename);
84 	ret = snprintf(filename, sz, "/proc/%d/%s", pid, basename);
85 	if (ret < 0 || (size_t)ret >= sz) {
86 		warn("failed to generate %s filename", basename);
87 		return -1;
88 	}
89 
90 	fd = open(filename, O_WRONLY | O_CLOEXEC);
91 	if (fd < 0) {
92 		pwarn("failed to open '%s'", filename);
93 		return -errno;
94 	}
95 
96 	len = strlen(content);
97 	written = write(fd, content, len);
98 	if (written < 0) {
99 		pwarn("failed to write '%s'", filename);
100 		return -1;
101 	}
102 
103 	if ((size_t)written < len) {
104 		warn("failed to write %zu bytes to '%s'", len, filename);
105 		return -1;
106 	}
107 	close(fd);
108 	return 0;
109 }
110 
111 /*
112  * We specifically do not use cap_valid() as that only tells us the last
113  * valid cap we were *compiled* against (i.e. what the version of kernel
114  * headers says). If we run on a different kernel version, then it's not
115  * uncommon for that to be less (if an older kernel) or more (if a newer
116  * kernel).
117  * Normally, we suck up the answer via /proc. On Android, not all processes are
118  * guaranteed to be able to access '/proc/sys/kernel/cap_last_cap' so we
119  * programmatically find the value by calling prctl(PR_CAPBSET_READ).
120  */
get_last_valid_cap(void)121 unsigned int get_last_valid_cap(void)
122 {
123 	unsigned int last_valid_cap = 0;
124 	if (is_android()) {
125 		for (; prctl(PR_CAPBSET_READ, last_valid_cap, 0, 0, 0) >= 0;
126 		     ++last_valid_cap)
127 			;
128 
129 		/* |last_valid_cap| will be the first failing value. */
130 		if (last_valid_cap > 0) {
131 			last_valid_cap--;
132 		}
133 	} else {
134 		const char cap_file[] = "/proc/sys/kernel/cap_last_cap";
135 		FILE *fp = fopen(cap_file, "re");
136 		if (fscanf(fp, "%u", &last_valid_cap) != 1)
137 			pdie("fscanf(%s)", cap_file);
138 		fclose(fp);
139 	}
140 	return last_valid_cap;
141 }
142 
cap_ambient_supported(void)143 int cap_ambient_supported(void)
144 {
145 	return prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) >=
146 	       0;
147 }
148 
config_net_loopback(void)149 int config_net_loopback(void)
150 {
151 	const char ifname[] = "lo";
152 	int sock;
153 	struct ifreq ifr;
154 
155 	/* Make sure people don't try to add really long names. */
156 	_Static_assert(sizeof(ifname) <= IFNAMSIZ, "interface name too long");
157 
158 	sock = socket(AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0);
159 	if (sock < 0) {
160 		pwarn("socket(AF_LOCAL) failed");
161 		return -1;
162 	}
163 
164 	/*
165 	 * Do the equiv of `ip link set up lo`.  The kernel will assign
166 	 * IPv4 (127.0.0.1) & IPv6 (::1) addresses automatically!
167 	 */
168 	strcpy(ifr.ifr_name, ifname);
169 	if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
170 		pwarn("ioctl(SIOCGIFFLAGS) failed");
171 		return -1;
172 	}
173 
174 	/* The kernel preserves ifr.ifr_name for use. */
175 	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
176 	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
177 		pwarn("ioctl(SIOCSIFFLAGS) failed");
178 		return -1;
179 	}
180 
181 	close(sock);
182 	return 0;
183 }
184 
setup_pipe_end(int fds[2],size_t index)185 int setup_pipe_end(int fds[2], size_t index)
186 {
187 	if (index > 1)
188 		return -1;
189 
190 	close(fds[1 - index]);
191 	return fds[index];
192 }
193 
setup_and_dupe_pipe_end(int fds[2],size_t index,int fd)194 int setup_and_dupe_pipe_end(int fds[2], size_t index, int fd)
195 {
196 	if (index > 1)
197 		return -1;
198 
199 	close(fds[1 - index]);
200 	/* dup2(2) the corresponding end of the pipe into |fd|. */
201 	return dup2(fds[index], fd);
202 }
203 
write_pid_to_path(pid_t pid,const char * path)204 int write_pid_to_path(pid_t pid, const char *path)
205 {
206 	FILE *fp = fopen(path, "w");
207 
208 	if (!fp) {
209 		pwarn("failed to open '%s'", path);
210 		return -errno;
211 	}
212 	if (fprintf(fp, "%d\n", (int)pid) < 0) {
213 		/* fprintf(3) does not set errno on failure. */
214 		warn("fprintf(%s) failed", path);
215 		return -1;
216 	}
217 	if (fclose(fp)) {
218 		pwarn("fclose(%s) failed", path);
219 		return -errno;
220 	}
221 
222 	return 0;
223 }
224 
225 /*
226  * setup_mount_destination: Ensures the mount target exists.
227  * Creates it if needed and possible.
228  */
setup_mount_destination(const char * source,const char * dest,uid_t uid,uid_t gid)229 int setup_mount_destination(const char *source, const char *dest, uid_t uid,
230 			    uid_t gid)
231 {
232 	int rc;
233 	struct stat st_buf;
234 
235 	rc = stat(dest, &st_buf);
236 	if (rc == 0) /* destination exists */
237 		return 0;
238 
239 	/*
240 	 * Try to create the destination.
241 	 * Either make a directory or touch a file depending on the source type.
242 	 * If the source doesn't exist, assume it is a filesystem type such as
243 	 * "tmpfs" and create a directory to mount it on.
244 	 */
245 	rc = stat(source, &st_buf);
246 	if (rc || S_ISDIR(st_buf.st_mode) || S_ISBLK(st_buf.st_mode)) {
247 		if (mkdir(dest, 0700))
248 			return -errno;
249 	} else {
250 		int fd = open(dest, O_RDWR | O_CREAT, 0700);
251 		if (fd < 0)
252 			return -errno;
253 		close(fd);
254 	}
255 	return chown(dest, uid, gid);
256 }
257