qtaguid.c revision 69f4cd7f5add7a7c7f5915e5292aab7eb2a42e9f
18626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma/* libcutils/qtaguid.c 28626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** 38626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** Copyright 2011, The Android Open Source Project 48626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** 58626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** Licensed under the Apache License, Version 2.0 (the "License"); 68626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** you may not use this file except in compliance with the License. 78626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** You may obtain a copy of the License at 88626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** 98626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** http://www.apache.org/licenses/LICENSE-2.0 108626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** 118626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** Unless required by applicable law or agreed to in writing, software 128626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** distributed under the License is distributed on an "AS IS" BASIS, 138626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** See the License for the specific language governing permissions and 158626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma** limitations under the License. 168626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma*/ 178626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma 1829656d34a21f4bc3899264027664c9321b0b94e0JP Abgrall// #define LOG_NDEBUG 0 1929656d34a21f4bc3899264027664c9321b0b94e0JP Abgrall 208626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#define LOG_TAG "qtaguid" 218626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma 228626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <cutils/qtaguid.h> 238626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <cutils/log.h> 249b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma#include <errno.h> 258626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <fcntl.h> 268626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <stdio.h> 278626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <string.h> 288626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma#include <unistd.h> 29243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall#include <pthread.h> 308626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma 31243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl"; 32243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic const int CTRL_MAX_INPUT_LEN = 128; 33243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive"; 34243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive"; 35243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 36243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall/* 37243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * One per proccess. 38243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * Once the device is open, this process will have its socket tags tracked. 39243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * And on exit or untimely death, all socket tags will be removed. 40243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * A process can only open /dev/xt_qtaguid once. 41243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * It should not close it unless it is really done with all the socket tags. 42243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * Failure to open it will be visible when socket tagging will be attempted. 43243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall */ 44243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic int resTrackFd = -1; 45243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallpthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT; 46243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 47243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall/* Only call once per process. */ 48243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallvoid qtaguid_resTrack(void) { 49243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY)); 50243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (resTrackFd >=0) { 51243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall TEMP_FAILURE_RETRY(fcntl(resTrackFd, F_SETFD, FD_CLOEXEC)); 52243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 53243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 548626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma 55243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall/* 56243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * Returns: 57243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * 0 on success. 58243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall * -errno on failure. 59243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall */ 60243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic int write_ctrl(const char *cmd) { 61243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int fd, res, savedErrno; 62243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 6369f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("write_ctrl(%s)", cmd); 64243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 65243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall fd = TEMP_FAILURE_RETRY(open(CTRL_PROCPATH, O_WRONLY)); 669b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma if (fd < 0) { 679b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma return -errno; 689b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 699b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 70243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = TEMP_FAILURE_RETRY(write(fd, cmd, strlen(cmd))); 71243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 72243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall savedErrno = errno; 73243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } else { 74243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall savedErrno = 0; 75243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 76243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 77243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall LOGI("Failed write_ctrl(%s) res=%d errno=%d", cmd, res, savedErrno); 789b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 799b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma close(fd); 80243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -savedErrno; 81243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 82243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 83243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallstatic int write_param(const char *param_path, const char *value) { 84243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int param_fd; 85243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 86243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 87243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY)); 88243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (param_fd < 0) { 89243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 90243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 91243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value))); 92243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 93243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 94243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 95243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall close(param_fd); 96243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return 0; 97243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 98243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 99243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_tagSocket(int sockfd, int tag, uid_t uid) { 100243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 101243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 102243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall /* Doing java-land a favor, enforcing "long" */ 103243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall uint64_t kTag = ((uint64_t)tag << 32) & ~(1LLU<<63); 104243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 105243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 106243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall pthread_once(&resTrackInitDone, qtaguid_resTrack); 107243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 108243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "t %d %llu %d", sockfd, kTag, uid); 109243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 11069f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Tagging socket %d with tag %llx{%u,0} for uid %d", sockfd, kTag, tag, uid); 111243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 112243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 113243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 114243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall LOGI("Tagging socket %d with tag %llx(%d) for uid %d failed errno=%d", 115243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall sockfd, kTag, tag, uid, res); 116243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 117243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 1189b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma return res; 1199b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma} 1209b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 121243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_untagSocket(int sockfd) { 122243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 123243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 1249b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 12569f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Untagging socket %d", sockfd); 126243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 127243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "u %d", sockfd); 128243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 129243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 130243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall LOGI("Untagging socket %d failed errno=%d", sockfd, res); 1319b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 1329b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 133243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return res; 134243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 135243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 136243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_setCounterSet(int counterSetNum, uid_t uid) { 137243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 138243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 139243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 14069f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid); 141243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 142243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "s %d %d", counterSetNum, uid); 143243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 144243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return res; 145243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 146243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 147243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_deleteTagData(int tag, uid_t uid) { 148243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 149243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int fd, cnt = 0, res = 0; 150243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall uint64_t kTag = (uint64_t)tag << 32; 151243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 15269f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Deleting tag data with tag %llx{%d,0} for uid %d", kTag, tag, uid); 153243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 154243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall pthread_once(&resTrackInitDone, qtaguid_resTrack); 155243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 156243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "d %llu %d", kTag, uid); 157243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 158243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 159243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall LOGI("Deleteing tag data with tag %llx/%d for uid %d failed with cnt=%d errno=%d", 160243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall kTag, tag, uid, cnt, errno); 1619b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 1629b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 1639b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma return res; 1648626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma} 165243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 166243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_setPacifier(int on) { 167243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int param_fd; 168243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 169243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall const char *value; 170243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 171243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall value = on ? "Y" : "N"; 172243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) { 173243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 174243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 175243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (write_param(TAG_PACIFIER_PARAM, value) < 0) { 176243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 177243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 178243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return 0; 179243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 180