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