ServiceUtilities.cpp revision 40b26470dd29e44f1601ceb6e60948586a4d9f88
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License. 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License. 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/AppOpsManager.h> 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/IPCThreadState.h> 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/IServiceManager.h> 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <binder/PermissionCache.h> 2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <private/android_filesystem_config.h> 2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "ServiceUtilities.h" 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* When performing permission checks we do not use permission cache for 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * runtime permissions (protection level dangerous) as they may change at 267cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang * runtime. All other permissions (protection level normal and dangerous) 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * can be cached as they never change. Of course all permission checked 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * here are platform defined. 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */ 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 316f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopiannamespace android { 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3314d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania// Not valid until initialized by AudioFlinger constructor. It would have to be 346f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian// re-initialized if the process containing AudioFlinger service forks (which it doesn't). 356f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopianpid_t getpid_cached; 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 377562408b2261d38415453378b6188f74fda99d88Mathias Agopianbool recordingAllowed(const String16& opPackageName) { 387562408b2261d38415453378b6188f74fda99d88Mathias Agopian // Note: We are getting the UID from the calling IPC thread state because all 397562408b2261d38415453378b6188f74fda99d88Mathias Agopian // clients that perform recording create AudioRecord in their own processes 407562408b2261d38415453378b6188f74fda99d88Mathias Agopian // and the system does not create AudioRecord objects on behalf of apps. This 41b1e7cd156ca3e1747374e0d20cdd1ce467210453Mathias Agopian // differs from playback where in some situations the system recreates AudioTrack 421d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania // instances associated with a client's MediaPlayer on behalf of this client. 431d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania // In the latter case we have to store the client UID and pass in along for 4410dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen // security checks. 4506ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar 461d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project static const String16 sRecordAudio("android.permission.RECORD_AUDIO"); 484356269be6d2b62bbb945364e8fc4beb99e1aadaEric Laurent 491b86fe063badb5f28c467ade39be0f4008688947Andreas Huber // IMPORTANT: Don't use PermissionCache - a runtime permission and may change. 502013a54981d4ffb036dff279b88cc9f08c0ee1c2Jeff Brown const bool ok = checkCallingPermission(sRecordAudio); 512013a54981d4ffb036dff279b88cc9f08c0ee1c2Jeff Brown if (!ok) { 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ALOGE("Request requires android.permission.RECORD_AUDIO"); 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return false; 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 55a64c8c79af1a15911c55306d83a797fa50969f77niko 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const uid_t uid = IPCThreadState::self()->getCallingUid(); 578635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 581381d4b5c0385aec3741073e5998773b064c1fb0Lajos Molnar // To permit command-line native tests 599cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent if (uid == AID_ROOT) return true; 6083b0fd9997b558f6c2ebf5e6e4db20570cb233b8Marco Nelissen 61d89532e133b881c7e0dac089333ad7642fc510f1Richard Fitzgerald String16 checkedOpPackageName = opPackageName; 62f09611f2f33752afc28141e1bbaa897651c05d6fMarco Nelissen 63181fd9b5b64bab24bb49a34208f60a16e98488c5Chong Zhang // In some cases the calling code has no access to the package it runs under. 6499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk // For example, code using the wilhelm framework's OpenSL-ES APIs. In this 6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project // case we will get the packages for the calling UID and pick the first one 66535412965145a1df2ec1770331e8477e52cd37b5Andy Hung // for attributing the app op. This will work correctly for runtime permissions 6764760240f931714858a59c1579f07264d7182ba2Dima Zavin // as for legacy apps we will toggle the app op for all packages in the UID. 68fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin // The caveat is that the operation may be attributed to the wrong package and 697cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang // stats based on app ops may be slightly off. 707cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang if (checkedOpPackageName.size() <= 0) { 71559bf2836f5da25b75bfb229fec0d20d540ee426James Dong sp<IServiceManager> sm = defaultServiceManager(); 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IBinder> binder = sm->getService(String16("permission")); 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (binder == 0) { 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project ALOGE("Cannot get permission service"); 7544a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman return false; 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7714d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder); 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Vector<String16> packages; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8114d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania permCtrl->getPackagesForUid(uid, packages); 8259451f8ced48874427ff1550391c4f3cd2ba2e35Andreas Huber 83b7319a7eb0a06ef4fd3a0c9157ee63e637ad7aa1Andreas Huber if (packages.isEmpty()) { 8435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber ALOGE("No packages for calling UID"); 85ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return false; 86a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania } 87a64c8c79af1a15911c55306d83a797fa50969f77niko checkedOpPackageName = packages[0]; 88a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania } 89a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 90a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania AppOpsManager appOps; 91a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (appOps.noteOp(AppOpsManager::OP_RECORD_AUDIO, uid, checkedOpPackageName) 92a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania != AppOpsManager::MODE_ALLOWED) { 93a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania ALOGE("Request denied by app op OP_RECORD_AUDIO"); 94a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return false; 95a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania } 96a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 97ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung return true; 98ff874dc957f9ea70d87f4d627bf903e1fc86d58bAndy Hung} 99a64c8c79af1a15911c55306d83a797fa50969f77niko 100d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cnikobool captureAudioOutputAllowed() { 101a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; 102a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT"); 103a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. 104a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput); 105a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT"); 106a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return ok; 107a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania} 108a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 109a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniabool captureHotwordAllowed() { 110a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD"); 111a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. 112a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania bool ok = PermissionCache::checkCallingPermission(sCaptureHotwordAllowed); 113a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD"); 114a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return ok; 115a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania} 116a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 117a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniabool settingsAllowed() { 118a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true; 119a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS"); 120a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. 121a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania bool ok = PermissionCache::checkCallingPermission(sAudioSettings); 122a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS"); 123a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return ok; 124a64c8c79af1a15911c55306d83a797fa50969f77niko} 125a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 126a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniabool modifyAudioRoutingAllowed() { 1274829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania static const String16 sModifyAudioRoutingAllowed("android.permission.MODIFY_AUDIO_ROUTING"); 1284829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. 129a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania bool ok = PermissionCache::checkCallingPermission(sModifyAudioRoutingAllowed); 13029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block if (!ok) ALOGE("android.permission.MODIFY_AUDIO_ROUTING"); 131a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return ok; 132a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania} 133a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 134a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniabool dumpAllowed() { 1354829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania // don't optimize for same pid, since mediaserver never dumps itself 136a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania static const String16 sDump("android.permission.DUMP"); 13729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block // IMPORTANT: Use PermissionCache - not a runtime permission and may not change. 138a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania bool ok = PermissionCache::checkCallingPermission(sDump); 139a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania // convention is for caller to dump an error message to fd instead of logging here 140a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania //if (!ok) ALOGE("Request requires android.permission.DUMP"); 141a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania return ok; 1424829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania} 143a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania 144a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania} // namespace android 1454829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania