diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2017-11-10 18:34:36 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-11-10 18:34:36 +0000 |
commit | 6707ef139d9786887649e3e3c2e3e251a95dc96d (patch) | |
tree | fd9e724c7f64b29fccd94feec62f8bbbfa8bb222 | |
parent | c021b75cfd067963eb40d18b6be893cdde60943f (diff) | |
parent | baede73bd92d8d0ae11e42c438fe2ca7f209e2c4 (diff) | |
download | system_core-6707ef139d9786887649e3e3c2e3e251a95dc96d.tar.gz system_core-6707ef139d9786887649e3e3c2e3e251a95dc96d.tar.bz2 system_core-6707ef139d9786887649e3e3c2e3e251a95dc96d.zip |
Merge changes from topic "qtaguidReplace"
* changes:
Redirect qtaguid native call to netd fwmark client
Move qtaguid API out of libcutils
-rw-r--r-- | libcutils/Android.bp | 2 | ||||
-rw-r--r-- | libcutils/include/cutils/qtaguid.h | 12 | ||||
-rw-r--r-- | libcutils/qtaguid.cpp | 125 | ||||
-rw-r--r-- | libqtaguid/Android.bp | 56 | ||||
-rw-r--r-- | libqtaguid/include/qtaguid/qtaguid.h | 62 | ||||
-rw-r--r-- | libqtaguid/qtaguid.c (renamed from libcutils/qtaguid.c) | 55 |
6 files changed, 260 insertions, 52 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 { "klog.cpp", "partition_utils.c", "properties.cpp", - "qtaguid.c", + "qtaguid.cpp", "trace-dev.c", "uevent.cpp", ], 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 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,14 @@ #ifndef __CUTILS_QTAGUID_H #define __CUTILS_QTAGUID_H -#include <stdint.h> #include <sys/types.h> -#include <unistd.h> #ifdef __cplusplus extern "C" { #endif /* - * Set tags (and owning UIDs) for network sockets. The socket must be untagged - * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid - * module will keep a reference to it even after close. + * Set tags (and owning UIDs) for network sockets. */ extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid); @@ -46,8 +42,8 @@ extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid); /* * Delete all tag info that relates to the given tag an uid. - * If the tag is 0, then ALL info about the uid is freeded. - * The delete data also affects active tagged socketd, which are + * If the tag is 0, then ALL info about the uid is freed. + * The delete data also affects active tagged sockets, which are * then untagged. * The calling process can only operate on its own tags. * Unless it is part of the happy AID_NET_BW_ACCT group. 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 @@ +/* + * Copyright 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// #define LOG_NDEBUG 0 + +#define LOG_TAG "qtaguid" + +#include <dlfcn.h> +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <cutils/qtaguid.h> +#include <log/log.h> + +class netdHandler { + public: + int (*netdTagSocket)(int, uint32_t, uid_t); + int (*netdUntagSocket)(int); + int (*netdSetCounterSet)(uint32_t, uid_t); + int (*netdDeleteTagData)(uint32_t, uid_t); +}; + +int dummyTagSocket(int, uint32_t, uid_t) { + return -EREMOTEIO; +} + +int dummyUntagSocket(int) { + return -EREMOTEIO; +} + +int dummySetCounterSet(uint32_t, uid_t) { + return -EREMOTEIO; +} + +int dummyDeleteTagData(uint32_t, uid_t) { + return -EREMOTEIO; +} + +netdHandler initHandler(void) { + netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData}; + + void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW); + if (!netdClientHandle) { + ALOGE("Failed to open libnetd_client.so: %s", dlerror()); + return handler; + } + + handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket"); + if (!handler.netdTagSocket) { + ALOGE("load netdTagSocket handler failed: %s", dlerror()); + } + + handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket"); + if (!handler.netdUntagSocket) { + ALOGE("load netdUntagSocket handler failed: %s", dlerror()); + } + + handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet"); + if (!handler.netdSetCounterSet) { + ALOGE("load netdSetCounterSet handler failed: %s", dlerror()); + } + + handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData"); + if (!handler.netdDeleteTagData) { + ALOGE("load netdDeleteTagData handler failed: %s", dlerror()); + } + return handler; +} + +// The language guarantees that this object will be initialized in a thread-safe way. +static netdHandler& getHandler() { + static netdHandler instance = initHandler(); + return instance; +} + +int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) { + // Check the socket fd passed to us is still valid before we load the netd + // client. Pass a already closed socket fd to netd client may let netd open + // the unix socket with the same fd number and pass it to server for + // tagging. + // TODO: move the check into netdTagSocket. + int res = fcntl(sockfd, F_GETFD); + if (res < 0) return res; + + ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid); + return getHandler().netdTagSocket(sockfd, tag, uid); +} + +int qtaguid_untagSocket(int sockfd) { + // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail + // as expected. + // TODO: move the check into netdTagSocket. + int res = fcntl(sockfd, F_GETFD); + if (res < 0) return res; + + ALOGV("Untagging socket %d", sockfd); + return getHandler().netdUntagSocket(sockfd); +} + +int qtaguid_setCounterSet(int counterSetNum, uid_t uid) { + ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid); + return getHandler().netdSetCounterSet(counterSetNum, uid); +} + +int qtaguid_deleteTagData(int tag, uid_t uid) { + ALOGV("Deleting tag data with tag %u for uid %d", tag, uid); + return getHandler().netdDeleteTagData(tag, uid); +} diff --git a/libqtaguid/Android.bp b/libqtaguid/Android.bp new file mode 100644 index 000000000..de632caa2 --- /dev/null +++ b/libqtaguid/Android.bp @@ -0,0 +1,56 @@ +// +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_headers { + name: "libqtaguid_headers", + vendor_available: false, + host_supported: false, + export_include_dirs: ["include"], + target: { + linux_bionic: { + enabled: true, + }, + }, +} + +cc_library { + name: "libqtaguid", + vendor_available: false, + host_supported: false, + target: { + android: { + srcs: [ + "qtaguid.c", + ], + sanitize: { + misc_undefined: ["integer"], + }, + }, + }, + + shared_libs: ["liblog"], + header_libs: [ + "libqtaguid_headers", + ], + export_header_lib_headers: ["libqtaguid_headers"], + local_include_dirs: ["include"], + + cflags: [ + "-Werror", + "-Wall", + "-Wextra", + ], +} diff --git a/libqtaguid/include/qtaguid/qtaguid.h b/libqtaguid/include/qtaguid/qtaguid.h new file mode 100644 index 000000000..72285e532 --- /dev/null +++ b/libqtaguid/include/qtaguid/qtaguid.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LEGACY_QTAGUID_H +#define __LEGACY_QTAGUID_H + +#include <stdint.h> +#include <sys/types.h> +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Set tags (and owning UIDs) for network sockets. The socket must be untagged + * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid + * module will keep a reference to it even after close. + */ +extern int legacy_tagSocket(int sockfd, int tag, uid_t uid); + +/* + * Untag a network socket before closing. + */ +extern int legacy_untagSocket(int sockfd); + +/* + * For the given uid, switch counter sets. + * The kernel only keeps a limited number of sets. + * 2 for now. + */ +extern int legacy_setCounterSet(int counterSetNum, uid_t uid); + +/* + * Delete all tag info that relates to the given tag an uid. + * If the tag is 0, then ALL info about the uid is freeded. + * The delete data also affects active tagged socketd, which are + * then untagged. + * The calling process can only operate on its own tags. + * Unless it is part of the happy AID_NET_BW_ACCT group. + * In which case it can clobber everything. + */ +extern int legacy_deleteTagData(int tag, uid_t uid); + +#ifdef __cplusplus +} +#endif + +#endif /* __LEGACY_QTAGUID_H */ diff --git a/libcutils/qtaguid.c b/libqtaguid/qtaguid.c index 22b83253f..cd38bad77 100644 --- a/libcutils/qtaguid.c +++ b/libqtaguid/qtaguid.c @@ -27,12 +27,10 @@ #include <unistd.h> #include <log/log.h> -#include <cutils/qtaguid.h> +#include <qtaguid/qtaguid.h> static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl"; static const int CTRL_MAX_INPUT_LEN = 128; -static const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive"; -static const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive"; /* * One per proccess. @@ -46,7 +44,7 @@ static int resTrackFd = -1; pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT; /* Only call once per process. */ -void qtaguid_resTrack(void) { +void legacy_resTrack(void) { resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC)); } @@ -55,7 +53,7 @@ void qtaguid_resTrack(void) { * 0 on success. * -errno on failure. */ -static int write_ctrl(const char *cmd) { +static int write_ctrl(const char* cmd) { int fd, res, savedErrno; ALOGV("write_ctrl(%s)", cmd); @@ -79,28 +77,12 @@ static int write_ctrl(const char *cmd) { return -savedErrno; } -static int write_param(const char *param_path, const char *value) { - int param_fd; - int res; - - param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY | O_CLOEXEC)); - if (param_fd < 0) { - return -errno; - } - res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value))); - if (res < 0) { - return -errno; - } - close(param_fd); - return 0; -} - -int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) { +int legacy_tagSocket(int sockfd, int tag, uid_t uid) { char lineBuf[CTRL_MAX_INPUT_LEN]; int res; uint64_t kTag = ((uint64_t)tag << 32); - pthread_once(&resTrackInitDone, qtaguid_resTrack); + pthread_once(&resTrackInitDone, legacy_resTrack); snprintf(lineBuf, sizeof(lineBuf), "t %d %" PRIu64 " %d", sockfd, kTag, uid); @@ -108,14 +90,14 @@ int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) { res = write_ctrl(lineBuf); if (res < 0) { - ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d", - sockfd, kTag, tag, uid, res); + ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d", sockfd, kTag, + tag, uid, res); } return res; } -int qtaguid_untagSocket(int sockfd) { +int legacy_untagSocket(int sockfd) { char lineBuf[CTRL_MAX_INPUT_LEN]; int res; @@ -130,7 +112,7 @@ int qtaguid_untagSocket(int sockfd) { return res; } -int qtaguid_setCounterSet(int counterSetNum, uid_t uid) { +int legacy_setCounterSet(int counterSetNum, uid_t uid) { char lineBuf[CTRL_MAX_INPUT_LEN]; int res; @@ -141,34 +123,21 @@ int qtaguid_setCounterSet(int counterSetNum, uid_t uid) { return res; } -int qtaguid_deleteTagData(int tag, uid_t uid) { +int legacy_deleteTagData(int tag, uid_t uid) { char lineBuf[CTRL_MAX_INPUT_LEN]; int cnt = 0, res = 0; uint64_t kTag = (uint64_t)tag << 32; ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid); - pthread_once(&resTrackInitDone, qtaguid_resTrack); + pthread_once(&resTrackInitDone, legacy_resTrack); snprintf(lineBuf, sizeof(lineBuf), "d %" PRIu64 " %d", kTag, uid); res = write_ctrl(lineBuf); if (res < 0) { ALOGI("Deleting tag data with tag %" PRIx64 "/%d for uid %d failed with cnt=%d errno=%d", - kTag, tag, uid, cnt, errno); + kTag, tag, uid, cnt, errno); } return res; } - -int qtaguid_setPacifier(int on) { - const char *value; - - value = on ? "Y" : "N"; - if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) { - return -errno; - } - if (write_param(TAG_PACIFIER_PARAM, value) < 0) { - return -errno; - } - return 0; -} |