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 #include <cutils/qtaguid.h>
18
19 // #define LOG_NDEBUG 0
20
21 #define LOG_TAG "qtaguid"
22
23 #include <dlfcn.h>
24 #include <errno.h>
25 #include <inttypes.h>
26
27 #include <log/log.h>
28
29 struct netdHandler {
30 int (*netdTagSocket)(int, uint32_t, uid_t);
31 int (*netdUntagSocket)(int);
32 };
33
stubTagSocket(int,uint32_t,uid_t)34 static int stubTagSocket(int, uint32_t, uid_t) {
35 return -EREMOTEIO;
36 }
37
stubUntagSocket(int)38 static int stubUntagSocket(int) {
39 return -EREMOTEIO;
40 }
41
initHandler(void)42 static netdHandler initHandler(void) {
43 const netdHandler stubHandler = { stubTagSocket, stubUntagSocket };
44
45 void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
46 if (!netdClientHandle) {
47 ALOGE("Failed to open libnetd_client.so: %s", dlerror());
48 return stubHandler;
49 }
50
51 netdHandler handler;
52 handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket");
53 if (!handler.netdTagSocket) {
54 ALOGE("load netdTagSocket handler failed: %s", dlerror());
55 return stubHandler;
56 }
57
58 handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket");
59 if (!handler.netdUntagSocket) {
60 ALOGE("load netdUntagSocket handler failed: %s", dlerror());
61 return stubHandler;
62 }
63
64 return handler;
65 }
66
67 // The language guarantees that this object will be initialized in a thread-safe way.
getHandler()68 static const netdHandler& getHandler() {
69 static const netdHandler instance = initHandler();
70 return instance;
71 }
72
qtaguid_tagSocket(int sockfd,int tag,uid_t uid)73 int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
74 ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid);
75 return getHandler().netdTagSocket(sockfd, tag, uid);
76 }
77
qtaguid_untagSocket(int sockfd)78 int qtaguid_untagSocket(int sockfd) {
79 ALOGV("Untagging socket %d", sockfd);
80 return getHandler().netdUntagSocket(sockfd);
81 }
82