summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTreehugger Robot2017-11-10 12:34:36 -0600
committerGerrit Code Review2017-11-10 12:34:36 -0600
commit6707ef139d9786887649e3e3c2e3e251a95dc96d (patch)
treefd9e724c7f64b29fccd94feec62f8bbbfa8bb222 /libcutils
parentc021b75cfd067963eb40d18b6be893cdde60943f (diff)
parentbaede73bd92d8d0ae11e42c438fe2ca7f209e2c4 (diff)
downloadplatform-system-core-6707ef139d9786887649e3e3c2e3e251a95dc96d.tar.gz
platform-system-core-6707ef139d9786887649e3e3c2e3e251a95dc96d.tar.xz
platform-system-core-6707ef139d9786887649e3e3c2e3e251a95dc96d.zip
Merge changes from topic "qtaguidReplace"
* changes: Redirect qtaguid native call to netd fwmark client Move qtaguid API out of libcutils
Diffstat (limited to 'libcutils')
-rw-r--r--libcutils/Android.bp2
-rw-r--r--libcutils/include/cutils/qtaguid.h12
-rw-r--r--libcutils/qtaguid.c174
-rw-r--r--libcutils/qtaguid.cpp125
4 files changed, 130 insertions, 183 deletions
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index faaad0c20..8fb3a52d7 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -110,7 +110,7 @@ cc_library {
110 "klog.cpp", 110 "klog.cpp",
111 "partition_utils.c", 111 "partition_utils.c",
112 "properties.cpp", 112 "properties.cpp",
113 "qtaguid.c", 113 "qtaguid.cpp",
114 "trace-dev.c", 114 "trace-dev.c",
115 "uevent.cpp", 115 "uevent.cpp",
116 ], 116 ],
diff --git a/libcutils/include/cutils/qtaguid.h b/libcutils/include/cutils/qtaguid.h
index 803fe0d9a..3f5e41fd3 100644
--- a/libcutils/include/cutils/qtaguid.h
+++ b/libcutils/include/cutils/qtaguid.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2011 The Android Open Source Project 2 * Copyright (C) 2017 The Android Open Source Project
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -17,18 +17,14 @@
17#ifndef __CUTILS_QTAGUID_H 17#ifndef __CUTILS_QTAGUID_H
18#define __CUTILS_QTAGUID_H 18#define __CUTILS_QTAGUID_H
19 19
20#include <stdint.h>
21#include <sys/types.h> 20#include <sys/types.h>
22#include <unistd.h>
23 21
24#ifdef __cplusplus 22#ifdef __cplusplus
25extern "C" { 23extern "C" {
26#endif 24#endif
27 25
28/* 26/*
29 * Set tags (and owning UIDs) for network sockets. The socket must be untagged 27 * Set tags (and owning UIDs) for network sockets.
30 * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid
31 * module will keep a reference to it even after close.
32 */ 28 */
33extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid); 29extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid);
34 30
@@ -46,8 +42,8 @@ extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid);
46 42
47/* 43/*
48 * Delete all tag info that relates to the given tag an uid. 44 * Delete all tag info that relates to the given tag an uid.
49 * If the tag is 0, then ALL info about the uid is freeded. 45 * If the tag is 0, then ALL info about the uid is freed.
50 * The delete data also affects active tagged socketd, which are 46 * The delete data also affects active tagged sockets, which are
51 * then untagged. 47 * then untagged.
52 * The calling process can only operate on its own tags. 48 * The calling process can only operate on its own tags.
53 * Unless it is part of the happy AID_NET_BW_ACCT group. 49 * Unless it is part of the happy AID_NET_BW_ACCT group.
diff --git a/libcutils/qtaguid.c b/libcutils/qtaguid.c
deleted file mode 100644
index 22b83253f..000000000
--- a/libcutils/qtaguid.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2** Copyright 2011, The Android Open Source Project
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8** http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License is distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
14** limitations under the License.
15*/
16
17// #define LOG_NDEBUG 0
18
19#define LOG_TAG "qtaguid"
20
21#include <errno.h>
22#include <fcntl.h>
23#include <inttypes.h>
24#include <pthread.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28
29#include <log/log.h>
30#include <cutils/qtaguid.h>
31
32static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl";
33static const int CTRL_MAX_INPUT_LEN = 128;
34static const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive";
35static const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive";
36
37/*
38 * One per proccess.
39 * Once the device is open, this process will have its socket tags tracked.
40 * And on exit or untimely death, all socket tags will be removed.
41 * A process can only open /dev/xt_qtaguid once.
42 * It should not close it unless it is really done with all the socket tags.
43 * Failure to open it will be visible when socket tagging will be attempted.
44 */
45static int resTrackFd = -1;
46pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT;
47
48/* Only call once per process. */
49void qtaguid_resTrack(void) {
50 resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC));
51}
52
53/*
54 * Returns:
55 * 0 on success.
56 * -errno on failure.
57 */
58static int write_ctrl(const char *cmd) {
59 int fd, res, savedErrno;
60
61 ALOGV("write_ctrl(%s)", cmd);
62
63 fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY | O_CLOEXEC));
64 if (fd < 0) {
65 return -errno;
66 }
67
68 res = TEMP_FAILURE_RETRY(write(fd, cmd, strlen(cmd)));
69 if (res < 0) {
70 savedErrno = errno;
71 } else {
72 savedErrno = 0;
73 }
74 if (res < 0) {
75 // ALOGV is enough because all the callers also log failures
76 ALOGV("Failed write_ctrl(%s) res=%d errno=%d", cmd, res, savedErrno);
77 }
78 close(fd);
79 return -savedErrno;
80}
81
82static int write_param(const char *param_path, const char *value) {
83 int param_fd;
84 int res;
85
86 param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY | O_CLOEXEC));
87 if (param_fd < 0) {
88 return -errno;
89 }
90 res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value)));
91 if (res < 0) {
92 return -errno;
93 }
94 close(param_fd);
95 return 0;
96}
97
98int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
99 char lineBuf[CTRL_MAX_INPUT_LEN];
100 int res;
101 uint64_t kTag = ((uint64_t)tag << 32);
102
103 pthread_once(&resTrackInitDone, qtaguid_resTrack);
104
105 snprintf(lineBuf, sizeof(lineBuf), "t %d %" PRIu64 " %d", sockfd, kTag, uid);
106
107 ALOGV("Tagging socket %d with tag %" PRIx64 "{%u,0} for uid %d", sockfd, kTag, tag, uid);
108
109 res = write_ctrl(lineBuf);
110 if (res < 0) {
111 ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d",
112 sockfd, kTag, tag, uid, res);
113 }
114
115 return res;
116}
117
118int qtaguid_untagSocket(int sockfd) {
119 char lineBuf[CTRL_MAX_INPUT_LEN];
120 int res;
121
122 ALOGV("Untagging socket %d", sockfd);
123
124 snprintf(lineBuf, sizeof(lineBuf), "u %d", sockfd);
125 res = write_ctrl(lineBuf);
126 if (res < 0) {
127 ALOGI("Untagging socket %d failed errno=%d", sockfd, res);
128 }
129
130 return res;
131}
132
133int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
134 char lineBuf[CTRL_MAX_INPUT_LEN];
135 int res;
136
137 ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid);
138
139 snprintf(lineBuf, sizeof(lineBuf), "s %d %d", counterSetNum, uid);
140 res = write_ctrl(lineBuf);
141 return res;
142}
143
144int qtaguid_deleteTagData(int tag, uid_t uid) {
145 char lineBuf[CTRL_MAX_INPUT_LEN];
146 int cnt = 0, res = 0;
147 uint64_t kTag = (uint64_t)tag << 32;
148
149 ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid);
150
151 pthread_once(&resTrackInitDone, qtaguid_resTrack);
152
153 snprintf(lineBuf, sizeof(lineBuf), "d %" PRIu64 " %d", kTag, uid);
154 res = write_ctrl(lineBuf);
155 if (res < 0) {
156 ALOGI("Deleting tag data with tag %" PRIx64 "/%d for uid %d failed with cnt=%d errno=%d",
157 kTag, tag, uid, cnt, errno);
158 }
159
160 return res;
161}
162
163int qtaguid_setPacifier(int on) {
164 const char *value;
165
166 value = on ? "Y" : "N";
167 if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) {
168 return -errno;
169 }
170 if (write_param(TAG_PACIFIER_PARAM, value) < 0) {
171 return -errno;
172 }
173 return 0;
174}
diff --git a/libcutils/qtaguid.cpp b/libcutils/qtaguid.cpp
new file mode 100644
index 000000000..86a5dc4b3
--- /dev/null
+++ b/libcutils/qtaguid.cpp
@@ -0,0 +1,125 @@
1/*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// #define LOG_NDEBUG 0
18
19#define LOG_TAG "qtaguid"
20
21#include <dlfcn.h>
22#include <errno.h>
23#include <fcntl.h>
24#include <inttypes.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28
29#include <cutils/qtaguid.h>
30#include <log/log.h>
31
32class netdHandler {
33 public:
34 int (*netdTagSocket)(int, uint32_t, uid_t);
35 int (*netdUntagSocket)(int);
36 int (*netdSetCounterSet)(uint32_t, uid_t);
37 int (*netdDeleteTagData)(uint32_t, uid_t);
38};
39
40int dummyTagSocket(int, uint32_t, uid_t) {
41 return -EREMOTEIO;
42}
43
44int dummyUntagSocket(int) {
45 return -EREMOTEIO;
46}
47
48int dummySetCounterSet(uint32_t, uid_t) {
49 return -EREMOTEIO;
50}
51
52int dummyDeleteTagData(uint32_t, uid_t) {
53 return -EREMOTEIO;
54}
55
56netdHandler initHandler(void) {
57 netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData};
58
59 void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
60 if (!netdClientHandle) {
61 ALOGE("Failed to open libnetd_client.so: %s", dlerror());
62 return handler;
63 }
64
65 handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket");
66 if (!handler.netdTagSocket) {
67 ALOGE("load netdTagSocket handler failed: %s", dlerror());
68 }
69
70 handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket");
71 if (!handler.netdUntagSocket) {
72 ALOGE("load netdUntagSocket handler failed: %s", dlerror());
73 }
74
75 handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet");
76 if (!handler.netdSetCounterSet) {
77 ALOGE("load netdSetCounterSet handler failed: %s", dlerror());
78 }
79
80 handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData");
81 if (!handler.netdDeleteTagData) {
82 ALOGE("load netdDeleteTagData handler failed: %s", dlerror());
83 }
84 return handler;
85}
86
87// The language guarantees that this object will be initialized in a thread-safe way.
88static netdHandler& getHandler() {
89 static netdHandler instance = initHandler();
90 return instance;
91}
92
93int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
94 // Check the socket fd passed to us is still valid before we load the netd
95 // client. Pass a already closed socket fd to netd client may let netd open
96 // the unix socket with the same fd number and pass it to server for
97 // tagging.
98 // TODO: move the check into netdTagSocket.
99 int res = fcntl(sockfd, F_GETFD);
100 if (res < 0) return res;
101
102 ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid);
103 return getHandler().netdTagSocket(sockfd, tag, uid);
104}
105
106int qtaguid_untagSocket(int sockfd) {
107 // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail
108 // as expected.
109 // TODO: move the check into netdTagSocket.
110 int res = fcntl(sockfd, F_GETFD);
111 if (res < 0) return res;
112
113 ALOGV("Untagging socket %d", sockfd);
114 return getHandler().netdUntagSocket(sockfd);
115}
116
117int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
118 ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid);
119 return getHandler().netdSetCounterSet(counterSetNum, uid);
120}
121
122int qtaguid_deleteTagData(int tag, uid_t uid) {
123 ALOGV("Deleting tag data with tag %u for uid %d", tag, uid);
124 return getHandler().netdDeleteTagData(tag, uid);
125}