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) { 77fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("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; 102e34b91719c031f273d43781e5d96363a10ab44bdJeff Sharkey uint64_t kTag = ((uint64_t)tag << 32); 103243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 104243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall pthread_once(&resTrackInitDone, qtaguid_resTrack); 105243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 106243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "t %d %llu %d", sockfd, kTag, uid); 107243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 10869f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Tagging socket %d with tag %llx{%u,0} for uid %d", sockfd, kTag, tag, uid); 109243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 110243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 111243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 112fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Tagging socket %d with tag %llx(%d) for uid %d failed errno=%d", 113243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall sockfd, kTag, tag, uid, res); 114243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 115243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 1169b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma return res; 1179b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma} 1189b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 119243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_untagSocket(int sockfd) { 120243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 121243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 1229b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 12369f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Untagging socket %d", sockfd); 124243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 125243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "u %d", sockfd); 126243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 127243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 128fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Untagging socket %d failed errno=%d", sockfd, res); 1299b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 1309b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 131243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return res; 132243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 133243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 134243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_setCounterSet(int counterSetNum, uid_t uid) { 135243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 136243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 137243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 13869f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid); 139243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 140243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "s %d %d", counterSetNum, uid); 141243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 142243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return res; 143243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 144243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 145243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_deleteTagData(int tag, uid_t uid) { 146243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall char lineBuf[CTRL_MAX_INPUT_LEN]; 147243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int fd, cnt = 0, res = 0; 148243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall uint64_t kTag = (uint64_t)tag << 32; 149243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 15069f4cd7f5add7a7c7f5915e5292aab7eb2a42e9fSteve Block ALOGV("Deleting tag data with tag %llx{%d,0} for uid %d", kTag, tag, uid); 151243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 152243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall pthread_once(&resTrackInitDone, qtaguid_resTrack); 153243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 154243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall snprintf(lineBuf, sizeof(lineBuf), "d %llu %d", kTag, uid); 155243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall res = write_ctrl(lineBuf); 156243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (res < 0) { 157fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Deleteing tag data with tag %llx/%d for uid %d failed with cnt=%d errno=%d", 158243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall kTag, tag, uid, cnt, errno); 1599b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma } 1609b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma 1619b5c774369fcbd4460751f9b01e692d688c386baAshish Sharma return res; 1628626cce5f381899f47e3a82e2ef4c98f183391b0Ashish Sharma} 163243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 164243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrallint qtaguid_setPacifier(int on) { 165243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int param_fd; 166243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall int res; 167243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall const char *value; 168243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall 169243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall value = on ? "Y" : "N"; 170243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) { 171243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 172243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 173243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall if (write_param(TAG_PACIFIER_PARAM, value) < 0) { 174243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return -errno; 175243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall } 176243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall return 0; 177243123fb41d7d2981116bd5d11ba168b127d68e9JP Abgrall} 178