PermissionCache.cpp revision 99b49840d309727678b77403d6cc9f920111623f
199b49840d309727678b77403d6cc9f920111623fMathias Agopian/* 299b49840d309727678b77403d6cc9f920111623fMathias Agopian * Copyright (C) 2009 The Android Open Source Project 399b49840d309727678b77403d6cc9f920111623fMathias Agopian * 499b49840d309727678b77403d6cc9f920111623fMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 599b49840d309727678b77403d6cc9f920111623fMathias Agopian * you may not use this file except in compliance with the License. 699b49840d309727678b77403d6cc9f920111623fMathias Agopian * You may obtain a copy of the License at 799b49840d309727678b77403d6cc9f920111623fMathias Agopian * 899b49840d309727678b77403d6cc9f920111623fMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 999b49840d309727678b77403d6cc9f920111623fMathias Agopian * 1099b49840d309727678b77403d6cc9f920111623fMathias Agopian * Unless required by applicable law or agreed to in writing, software 1199b49840d309727678b77403d6cc9f920111623fMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 1299b49840d309727678b77403d6cc9f920111623fMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1399b49840d309727678b77403d6cc9f920111623fMathias Agopian * See the License for the specific language governing permissions and 1499b49840d309727678b77403d6cc9f920111623fMathias Agopian * limitations under the License. 1599b49840d309727678b77403d6cc9f920111623fMathias Agopian */ 1699b49840d309727678b77403d6cc9f920111623fMathias Agopian 1799b49840d309727678b77403d6cc9f920111623fMathias Agopian#define LOG_TAG "PermissionCache" 1899b49840d309727678b77403d6cc9f920111623fMathias Agopian 1999b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <stdint.h> 2099b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/Log.h> 2199b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/IPCThreadState.h> 2299b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/IServiceManager.h> 2399b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <binder/PermissionCache.h> 2499b49840d309727678b77403d6cc9f920111623fMathias Agopian#include <utils/String8.h> 2599b49840d309727678b77403d6cc9f920111623fMathias Agopian 2699b49840d309727678b77403d6cc9f920111623fMathias Agopiannamespace android { 2799b49840d309727678b77403d6cc9f920111623fMathias Agopian 2899b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------- 2999b49840d309727678b77403d6cc9f920111623fMathias Agopian 3099b49840d309727678b77403d6cc9f920111623fMathias AgopianANDROID_SINGLETON_STATIC_INSTANCE(PermissionCache) ; 3199b49840d309727678b77403d6cc9f920111623fMathias Agopian 3299b49840d309727678b77403d6cc9f920111623fMathias Agopian// ---------------------------------------------------------------------------- 3399b49840d309727678b77403d6cc9f920111623fMathias Agopian 3499b49840d309727678b77403d6cc9f920111623fMathias AgopianPermissionCache::PermissionCache() { 3599b49840d309727678b77403d6cc9f920111623fMathias Agopian} 3699b49840d309727678b77403d6cc9f920111623fMathias Agopian 3799b49840d309727678b77403d6cc9f920111623fMathias Agopianstatus_t PermissionCache::check(bool* granted, 3899b49840d309727678b77403d6cc9f920111623fMathias Agopian const String16& permission, uid_t uid) const { 3999b49840d309727678b77403d6cc9f920111623fMathias Agopian Mutex::Autolock _l(mLock); 4099b49840d309727678b77403d6cc9f920111623fMathias Agopian Entry e; 4199b49840d309727678b77403d6cc9f920111623fMathias Agopian e.name = permission; 4299b49840d309727678b77403d6cc9f920111623fMathias Agopian e.uid = uid; 4399b49840d309727678b77403d6cc9f920111623fMathias Agopian ssize_t index = mCache.indexOf(e); 4499b49840d309727678b77403d6cc9f920111623fMathias Agopian if (index >= 0) { 4599b49840d309727678b77403d6cc9f920111623fMathias Agopian *granted = mCache.itemAt(index).granted; 4699b49840d309727678b77403d6cc9f920111623fMathias Agopian return NO_ERROR; 4799b49840d309727678b77403d6cc9f920111623fMathias Agopian } 4899b49840d309727678b77403d6cc9f920111623fMathias Agopian return NAME_NOT_FOUND; 4999b49840d309727678b77403d6cc9f920111623fMathias Agopian} 5099b49840d309727678b77403d6cc9f920111623fMathias Agopian 5199b49840d309727678b77403d6cc9f920111623fMathias Agopianvoid PermissionCache::cache(const String16& permission, 5299b49840d309727678b77403d6cc9f920111623fMathias Agopian uid_t uid, bool granted) { 5399b49840d309727678b77403d6cc9f920111623fMathias Agopian Mutex::Autolock _l(mLock); 5499b49840d309727678b77403d6cc9f920111623fMathias Agopian Entry e; 5599b49840d309727678b77403d6cc9f920111623fMathias Agopian ssize_t index = mPermissionNamesPool.indexOf(permission); 5699b49840d309727678b77403d6cc9f920111623fMathias Agopian if (index > 0) { 5799b49840d309727678b77403d6cc9f920111623fMathias Agopian e.name = mPermissionNamesPool.itemAt(index); 5899b49840d309727678b77403d6cc9f920111623fMathias Agopian } else { 5999b49840d309727678b77403d6cc9f920111623fMathias Agopian mPermissionNamesPool.add(permission); 6099b49840d309727678b77403d6cc9f920111623fMathias Agopian e.name = permission; 6199b49840d309727678b77403d6cc9f920111623fMathias Agopian } 6299b49840d309727678b77403d6cc9f920111623fMathias Agopian // note, we don't need to store the pid, which is not actually used in 6399b49840d309727678b77403d6cc9f920111623fMathias Agopian // permission checks 6499b49840d309727678b77403d6cc9f920111623fMathias Agopian e.uid = uid; 6599b49840d309727678b77403d6cc9f920111623fMathias Agopian e.granted = granted; 6699b49840d309727678b77403d6cc9f920111623fMathias Agopian index = mCache.indexOf(e); 6799b49840d309727678b77403d6cc9f920111623fMathias Agopian if (index < 0) { 6899b49840d309727678b77403d6cc9f920111623fMathias Agopian mCache.add(e); 6999b49840d309727678b77403d6cc9f920111623fMathias Agopian } 7099b49840d309727678b77403d6cc9f920111623fMathias Agopian} 7199b49840d309727678b77403d6cc9f920111623fMathias Agopian 7299b49840d309727678b77403d6cc9f920111623fMathias Agopianvoid PermissionCache::purge() { 7399b49840d309727678b77403d6cc9f920111623fMathias Agopian Mutex::Autolock _l(mLock); 7499b49840d309727678b77403d6cc9f920111623fMathias Agopian mCache.clear(); 7599b49840d309727678b77403d6cc9f920111623fMathias Agopian} 7699b49840d309727678b77403d6cc9f920111623fMathias Agopian 7799b49840d309727678b77403d6cc9f920111623fMathias Agopianbool PermissionCache::checkCallingPermission(const String16& permission) { 7899b49840d309727678b77403d6cc9f920111623fMathias Agopian return PermissionCache::checkCallingPermission(permission, NULL, NULL); 7999b49840d309727678b77403d6cc9f920111623fMathias Agopian} 8099b49840d309727678b77403d6cc9f920111623fMathias Agopian 8199b49840d309727678b77403d6cc9f920111623fMathias Agopianbool PermissionCache::checkCallingPermission( 8299b49840d309727678b77403d6cc9f920111623fMathias Agopian const String16& permission, int32_t* outPid, int32_t* outUid) { 8399b49840d309727678b77403d6cc9f920111623fMathias Agopian IPCThreadState* ipcState = IPCThreadState::self(); 8499b49840d309727678b77403d6cc9f920111623fMathias Agopian pid_t pid = ipcState->getCallingPid(); 8599b49840d309727678b77403d6cc9f920111623fMathias Agopian uid_t uid = ipcState->getCallingUid(); 8699b49840d309727678b77403d6cc9f920111623fMathias Agopian if (outPid) *outPid = pid; 8799b49840d309727678b77403d6cc9f920111623fMathias Agopian if (outUid) *outUid = uid; 8899b49840d309727678b77403d6cc9f920111623fMathias Agopian return PermissionCache::checkPermission(permission, pid, uid); 8999b49840d309727678b77403d6cc9f920111623fMathias Agopian} 9099b49840d309727678b77403d6cc9f920111623fMathias Agopian 9199b49840d309727678b77403d6cc9f920111623fMathias Agopianbool PermissionCache::checkPermission( 9299b49840d309727678b77403d6cc9f920111623fMathias Agopian const String16& permission, pid_t pid, uid_t uid) { 9399b49840d309727678b77403d6cc9f920111623fMathias Agopian if ((uid == 0) || (pid == getpid())) { 9499b49840d309727678b77403d6cc9f920111623fMathias Agopian // root and ourselves is always okay 9599b49840d309727678b77403d6cc9f920111623fMathias Agopian return true; 9699b49840d309727678b77403d6cc9f920111623fMathias Agopian } 9799b49840d309727678b77403d6cc9f920111623fMathias Agopian 9899b49840d309727678b77403d6cc9f920111623fMathias Agopian PermissionCache& pc(PermissionCache::getInstance()); 9999b49840d309727678b77403d6cc9f920111623fMathias Agopian bool granted = false; 10099b49840d309727678b77403d6cc9f920111623fMathias Agopian if (pc.check(&granted, permission, uid) != NO_ERROR) { 10199b49840d309727678b77403d6cc9f920111623fMathias Agopian nsecs_t t = -systemTime(); 10299b49840d309727678b77403d6cc9f920111623fMathias Agopian granted = android::checkPermission(permission, pid, uid); 10399b49840d309727678b77403d6cc9f920111623fMathias Agopian t += systemTime(); 10499b49840d309727678b77403d6cc9f920111623fMathias Agopian LOGD("checking %s for uid=%d => %s (%d us)", 10599b49840d309727678b77403d6cc9f920111623fMathias Agopian String8(permission).string(), uid, 10699b49840d309727678b77403d6cc9f920111623fMathias Agopian granted?"granted":"denied", (int)ns2us(t)); 10799b49840d309727678b77403d6cc9f920111623fMathias Agopian pc.cache(permission, uid, granted); 10899b49840d309727678b77403d6cc9f920111623fMathias Agopian } 10999b49840d309727678b77403d6cc9f920111623fMathias Agopian return granted; 11099b49840d309727678b77403d6cc9f920111623fMathias Agopian} 11199b49840d309727678b77403d6cc9f920111623fMathias Agopian 11299b49840d309727678b77403d6cc9f920111623fMathias Agopian// --------------------------------------------------------------------------- 11399b49840d309727678b77403d6cc9f920111623fMathias Agopian}; // namespace android 114