summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjunyulai <junyulai@google.com>2019-01-04 08:40:37 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-01-04 08:40:37 -0800
commit32753e1e14bbcbc7ec4a4fbe7f43d8e6d2b6048a (patch)
treef9605a56d1a7d32a4a80465b4ab00c7b07a4e92d
parent8483a5291c62d54f507f5d83f3b337209da9397c (diff)
parent74c61c759253ef92e299b89e6c6a720e01f18b2b (diff)
downloadplatform_external_android-clat-32753e1e14bbcbc7ec4a4fbe7f43d8e6d2b6048a.tar.gz
platform_external_android-clat-32753e1e14bbcbc7ec4a4fbe7f43d8e6d2b6048a.tar.bz2
platform_external_android-clat-32753e1e14bbcbc7ec4a4fbe7f43d8e6d2b6048a.zip
Count ipv6 tx traffic of clat into clat uid. am: b5e8f977bb am: f7f765a611
am: 74c61c7592 Change-Id: Id72eba84f5c5682ee8b1aed6e355d3329c17ba17
-rw-r--r--clatd.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/clatd.c b/clatd.c
index d8df0d8..18d7562 100644
--- a/clatd.c
+++ b/clatd.c
@@ -154,40 +154,52 @@ void configure_tun_ip(const struct tun_data *tunnel) {
}
}
-/* function: drop_root
- * drops root privs but keeps the needed capability
+/* function: set_capability
+ * set the permitted, effective and inheritable capabilities of the current
+ * thread
*/
-void drop_root() {
+void set_capability(uint64_t target_cap) {
+ struct __user_cap_header_struct header = {
+ .version = _LINUX_CAPABILITY_VERSION_3,
+ .pid = 0 // 0 = change myself
+ };
+ struct __user_cap_data_struct cap[_LINUX_CAPABILITY_U32S_3] = {};
+
+ cap[0].permitted = cap[0].effective = cap[0].inheritable = target_cap;
+ cap[1].permitted = cap[1].effective = cap[1].inheritable = target_cap >> 32;
+
+ if (capset(&header, cap) < 0) {
+ logmsg(ANDROID_LOG_FATAL, "capset failed: %s", strerror(errno));
+ exit(1);
+ }
+}
+
+/* function: drop_root_but_keep_caps
+ * drops root privs but keeps the needed capabilities
+ */
+void drop_root_but_keep_caps() {
gid_t groups[] = { AID_INET, AID_VPN };
if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) < 0) {
- logmsg(ANDROID_LOG_FATAL, "drop_root/setgroups failed: %s", strerror(errno));
+ logmsg(ANDROID_LOG_FATAL, "setgroups failed: %s", strerror(errno));
exit(1);
}
- prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+ prctl(PR_SET_KEEPCAPS, 1);
- if (setgid(AID_CLAT) < 0) {
- logmsg(ANDROID_LOG_FATAL, "drop_root/setgid failed: %s", strerror(errno));
+ if (setresgid(AID_CLAT, AID_CLAT, AID_CLAT) < 0) {
+ logmsg(ANDROID_LOG_FATAL, "setresgid failed: %s", strerror(errno));
exit(1);
}
- if (setuid(AID_CLAT) < 0) {
- logmsg(ANDROID_LOG_FATAL, "drop_root/setuid failed: %s", strerror(errno));
+ if (setresuid(AID_CLAT, AID_CLAT, AID_CLAT) < 0) {
+ logmsg(ANDROID_LOG_FATAL, "setresuid failed: %s", strerror(errno));
exit(1);
}
- struct __user_cap_header_struct header;
- struct __user_cap_data_struct cap;
- memset(&header, 0, sizeof(header));
- memset(&cap, 0, sizeof(cap));
-
- header.version = _LINUX_CAPABILITY_VERSION;
- header.pid = 0; // 0 = change myself
- cap.effective = cap.permitted = (1 << CAP_NET_ADMIN);
-
- if (capset(&header, &cap) < 0) {
- logmsg(ANDROID_LOG_FATAL, "drop_root/capset failed: %s", strerror(errno));
- exit(1);
- }
+ // keep CAP_NET_RAW capability to open raw socket, and CAP_IPC_LOCK for mmap
+ // to lock memory.
+ set_capability((1 << CAP_NET_ADMIN) |
+ (1 << CAP_NET_RAW) |
+ (1 << CAP_IPC_LOCK));
}
/* function: open_sockets
@@ -494,11 +506,14 @@ int main(int argc, char **argv) {
logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", CLATD_VERSION,
uplink_interface, net_id_str ? net_id_str : "(none)", mark_str ? mark_str : "(none)");
+ // run under a regular user but keep needed capabilities
+ drop_root_but_keep_caps();
+
// open our raw sockets before dropping privs
open_sockets(&tunnel, mark);
- // run under a regular user
- drop_root();
+ // keeps only admin capability
+ set_capability(1 << CAP_NET_ADMIN);
// we can create tun devices as non-root because we're in the VPN group.
tunnel.fd4 = tun_open();