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 <fcntl.h> 26 #include <inttypes.h> 27 #include <stdio.h> 28 #include <string.h> 29 #include <unistd.h> 30 31 #include <log/log.h> 32 33 class netdHandler { 34 public: 35 int (*netdTagSocket)(int, uint32_t, uid_t); 36 int (*netdUntagSocket)(int); 37 int (*netdSetCounterSet)(uint32_t, uid_t); 38 int (*netdDeleteTagData)(uint32_t, uid_t); 39 }; 40 41 int dummyTagSocket(int, uint32_t, uid_t) { 42 return -EREMOTEIO; 43 } 44 45 int dummyUntagSocket(int) { 46 return -EREMOTEIO; 47 } 48 49 int dummySetCounterSet(uint32_t, uid_t) { 50 return -EREMOTEIO; 51 } 52 53 int dummyDeleteTagData(uint32_t, uid_t) { 54 return -EREMOTEIO; 55 } 56 57 netdHandler initHandler(void) { 58 netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData}; 59 60 void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW); 61 if (!netdClientHandle) { 62 ALOGE("Failed to open libnetd_client.so: %s", dlerror()); 63 return handler; 64 } 65 66 handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket"); 67 if (!handler.netdTagSocket) { 68 ALOGE("load netdTagSocket handler failed: %s", dlerror()); 69 } 70 71 handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket"); 72 if (!handler.netdUntagSocket) { 73 ALOGE("load netdUntagSocket handler failed: %s", dlerror()); 74 } 75 76 handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet"); 77 if (!handler.netdSetCounterSet) { 78 ALOGE("load netdSetCounterSet handler failed: %s", dlerror()); 79 } 80 81 handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData"); 82 if (!handler.netdDeleteTagData) { 83 ALOGE("load netdDeleteTagData handler failed: %s", dlerror()); 84 } 85 return handler; 86 } 87 88 // The language guarantees that this object will be initialized in a thread-safe way. 89 static netdHandler& getHandler() { 90 static netdHandler instance = initHandler(); 91 return instance; 92 } 93 94 int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) { 95 // Check the socket fd passed to us is still valid before we load the netd 96 // client. Pass a already closed socket fd to netd client may let netd open 97 // the unix socket with the same fd number and pass it to server for 98 // tagging. 99 // TODO: move the check into netdTagSocket. 100 int res = fcntl(sockfd, F_GETFD); 101 if (res < 0) return res; 102 103 ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid); 104 return getHandler().netdTagSocket(sockfd, tag, uid); 105 } 106 107 int qtaguid_untagSocket(int sockfd) { 108 // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail 109 // as expected. 110 // TODO: move the check into netdTagSocket. 111 int res = fcntl(sockfd, F_GETFD); 112 if (res < 0) return res; 113 114 ALOGV("Untagging socket %d", sockfd); 115 return getHandler().netdUntagSocket(sockfd); 116 } 117 118 int qtaguid_setCounterSet(int counterSetNum, uid_t uid) { 119 ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid); 120 return getHandler().netdSetCounterSet(counterSetNum, uid); 121 } 122 123 int qtaguid_deleteTagData(int tag, uid_t uid) { 124 ALOGV("Deleting tag data with tag %u for uid %d", tag, uid); 125 return getHandler().netdDeleteTagData(tag, uid); 126 } 127