• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "ServiceUtilities"
18 
19 #include <audio_utils/clock.h>
20 #include <binder/AppOpsManager.h>
21 #include <binder/IPCThreadState.h>
22 #include <binder/IServiceManager.h>
23 #include <binder/PermissionCache.h>
24 #include "mediautils/ServiceUtilities.h"
25 
26 #include <iterator>
27 #include <algorithm>
28 #include <pwd.h>
29 
30 /* When performing permission checks we do not use permission cache for
31  * runtime permissions (protection level dangerous) as they may change at
32  * runtime. All other permissions (protection level normal and dangerous)
33  * can be cached as they never change. Of course all permission checked
34  * here are platform defined.
35  */
36 
37 namespace android {
38 
39 static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
40 static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
41 static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
42 
resolveCallingPackage(PermissionController & permissionController,const String16 & opPackageName,uid_t uid)43 static String16 resolveCallingPackage(PermissionController& permissionController,
44         const String16& opPackageName, uid_t uid) {
45     if (opPackageName.size() > 0) {
46         return opPackageName;
47     }
48     // In some cases the calling code has no access to the package it runs under.
49     // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
50     // case we will get the packages for the calling UID and pick the first one
51     // for attributing the app op. This will work correctly for runtime permissions
52     // as for legacy apps we will toggle the app op for all packages in the UID.
53     // The caveat is that the operation may be attributed to the wrong package and
54     // stats based on app ops may be slightly off.
55     Vector<String16> packages;
56     permissionController.getPackagesForUid(uid, packages);
57     if (packages.isEmpty()) {
58         ALOGE("No packages for uid %d", uid);
59         return opPackageName; // empty string
60     }
61     return packages[0];
62 }
63 
checkRecordingInternal(const String16 & opPackageName,pid_t pid,uid_t uid,bool start,bool isHotwordSource)64 static bool checkRecordingInternal(const String16& opPackageName, pid_t pid,
65         uid_t uid, bool start, bool isHotwordSource) {
66     // Okay to not track in app ops as audio server or media server is us and if
67     // device is rooted security model is considered compromised.
68     // system_server loses its RECORD_AUDIO permission when a secondary
69     // user is active, but it is a core system service so let it through.
70     // TODO(b/141210120): UserManager.DISALLOW_RECORD_AUDIO should not affect system user 0
71     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(uid)) return true;
72 
73     // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
74     // may open a record track on behalf of a client.  Note that pid may be a tid.
75     // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
76     PermissionController permissionController;
77     const bool ok = permissionController.checkPermission(sAndroidPermissionRecordAudio, pid, uid);
78     if (!ok) {
79         ALOGE("Request requires %s", String8(sAndroidPermissionRecordAudio).c_str());
80         return false;
81     }
82 
83     String16 resolvedOpPackageName = resolveCallingPackage(
84             permissionController, opPackageName, uid);
85     if (resolvedOpPackageName.size() == 0) {
86         return false;
87     }
88 
89     AppOpsManager appOps;
90     const int32_t opRecordAudio = appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
91 
92     if (start) {
93         const int32_t op = isHotwordSource ?
94                 AppOpsManager::OP_RECORD_AUDIO_HOTWORD : opRecordAudio;
95         if (appOps.startOpNoThrow(op, uid, resolvedOpPackageName, /*startIfModeDefault*/ false)
96                 != AppOpsManager::MODE_ALLOWED) {
97             ALOGE("Request denied by app op: %d", op);
98             return false;
99         }
100     } else {
101         // Always use OP_RECORD_AUDIO for checks at creation time.
102         if (appOps.checkOp(opRecordAudio, uid, resolvedOpPackageName)
103                 != AppOpsManager::MODE_ALLOWED) {
104             ALOGE("Request denied by app op: %d", opRecordAudio);
105             return false;
106         }
107     }
108 
109     return true;
110 }
111 
recordingAllowed(const String16 & opPackageName,pid_t pid,uid_t uid)112 bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
113     return checkRecordingInternal(opPackageName, pid, uid, /*start*/ false,
114             /*is_hotword_source*/ false);
115 }
116 
startRecording(const String16 & opPackageName,pid_t pid,uid_t uid,bool isHotwordSource)117 bool startRecording(const String16& opPackageName, pid_t pid, uid_t uid, bool isHotwordSource) {
118      return checkRecordingInternal(opPackageName, pid, uid, /*start*/ true, isHotwordSource);
119 }
120 
finishRecording(const String16 & opPackageName,uid_t uid,bool isHotwordSource)121 void finishRecording(const String16& opPackageName, uid_t uid, bool isHotwordSource) {
122     // Okay to not track in app ops as audio server is us and if
123     // device is rooted security model is considered compromised.
124     if (isAudioServerOrRootUid(uid)) return;
125 
126     PermissionController permissionController;
127     String16 resolvedOpPackageName = resolveCallingPackage(
128             permissionController, opPackageName, uid);
129     if (resolvedOpPackageName.size() == 0) {
130         return;
131     }
132 
133     AppOpsManager appOps;
134     const int32_t op = isHotwordSource ? AppOpsManager::OP_RECORD_AUDIO_HOTWORD
135             : appOps.permissionToOpCode(sAndroidPermissionRecordAudio);
136     appOps.finishOp(op, uid, resolvedOpPackageName);
137 }
138 
captureAudioOutputAllowed(pid_t pid,uid_t uid)139 bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
140     if (isAudioServerOrRootUid(uid)) return true;
141     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
142     bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
143     if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
144     return ok;
145 }
146 
captureMediaOutputAllowed(pid_t pid,uid_t uid)147 bool captureMediaOutputAllowed(pid_t pid, uid_t uid) {
148     if (isAudioServerOrRootUid(uid)) return true;
149     static const String16 sCaptureMediaOutput("android.permission.CAPTURE_MEDIA_OUTPUT");
150     bool ok = PermissionCache::checkPermission(sCaptureMediaOutput, pid, uid);
151     if (!ok) ALOGE("Request requires android.permission.CAPTURE_MEDIA_OUTPUT");
152     return ok;
153 }
154 
captureVoiceCommunicationOutputAllowed(pid_t pid,uid_t uid)155 bool captureVoiceCommunicationOutputAllowed(pid_t pid, uid_t uid) {
156     if (isAudioServerOrRootUid(uid)) return true;
157     static const String16 sCaptureVoiceCommOutput(
158         "android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
159     bool ok = PermissionCache::checkPermission(sCaptureVoiceCommOutput, pid, uid);
160     if (!ok) ALOGE("Request requires android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
161     return ok;
162 }
163 
captureHotwordAllowed(const String16 & opPackageName,pid_t pid,uid_t uid)164 bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
165     // CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
166     bool ok = recordingAllowed(opPackageName, pid, uid);
167 
168     if (ok) {
169         static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
170         // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
171         ok = PermissionCache::checkPermission(sCaptureHotwordAllowed, pid, uid);
172     }
173     if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
174     return ok;
175 }
176 
settingsAllowed()177 bool settingsAllowed() {
178     // given this is a permission check, could this be isAudioServerOrRootUid()?
179     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
180     static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
181     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
182     bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
183     if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
184     return ok;
185 }
186 
modifyAudioRoutingAllowed()187 bool modifyAudioRoutingAllowed() {
188     return modifyAudioRoutingAllowed(
189         IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
190 }
191 
modifyAudioRoutingAllowed(pid_t pid,uid_t uid)192 bool modifyAudioRoutingAllowed(pid_t pid, uid_t uid) {
193     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
194     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
195     bool ok = PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
196     if (!ok) ALOGE("%s(): android.permission.MODIFY_AUDIO_ROUTING denied for uid %d",
197         __func__, uid);
198     return ok;
199 }
200 
modifyDefaultAudioEffectsAllowed()201 bool modifyDefaultAudioEffectsAllowed() {
202     return modifyDefaultAudioEffectsAllowed(
203         IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
204 }
205 
modifyDefaultAudioEffectsAllowed(pid_t pid,uid_t uid)206 bool modifyDefaultAudioEffectsAllowed(pid_t pid, uid_t uid) {
207     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
208 
209     static const String16 sModifyDefaultAudioEffectsAllowed(
210             "android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
211     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
212     bool ok = PermissionCache::checkPermission(sModifyDefaultAudioEffectsAllowed, pid, uid);
213     ALOGE_IF(!ok, "%s(): android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS denied for uid %d",
214             __func__, uid);
215     return ok;
216 }
217 
dumpAllowed()218 bool dumpAllowed() {
219     static const String16 sDump("android.permission.DUMP");
220     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
221     bool ok = PermissionCache::checkCallingPermission(sDump);
222     // convention is for caller to dump an error message to fd instead of logging here
223     //if (!ok) ALOGE("Request requires android.permission.DUMP");
224     return ok;
225 }
226 
modifyPhoneStateAllowed(pid_t pid,uid_t uid)227 bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
228     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
229     ALOGE_IF(!ok, "Request requires %s", String8(sModifyPhoneState).c_str());
230     return ok;
231 }
232 
233 // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
bypassInterruptionPolicyAllowed(pid_t pid,uid_t uid)234 bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
235     static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
236     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid)
237         || PermissionCache::checkPermission(sWriteSecureSettings, pid, uid)
238         || PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
239     ALOGE_IF(!ok, "Request requires %s or %s",
240              String8(sModifyPhoneState).c_str(), String8(sWriteSecureSettings).c_str());
241     return ok;
242 }
243 
checkIMemory(const sp<IMemory> & iMemory)244 status_t checkIMemory(const sp<IMemory>& iMemory)
245 {
246     if (iMemory == 0) {
247         ALOGE("%s check failed: NULL IMemory pointer", __FUNCTION__);
248         return BAD_VALUE;
249     }
250 
251     sp<IMemoryHeap> heap = iMemory->getMemory();
252     if (heap == 0) {
253         ALOGE("%s check failed: NULL heap pointer", __FUNCTION__);
254         return BAD_VALUE;
255     }
256 
257     off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
258     lseek(heap->getHeapID(), 0, SEEK_SET);
259 
260     if (iMemory->unsecurePointer() == NULL || size < (off_t)iMemory->size()) {
261         ALOGE("%s check failed: pointer %p size %zu fd size %u",
262               __FUNCTION__, iMemory->unsecurePointer(), iMemory->size(), (uint32_t)size);
263         return BAD_VALUE;
264     }
265 
266     return NO_ERROR;
267 }
268 
retreivePackageManager()269 sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
270     const sp<IServiceManager> sm = defaultServiceManager();
271     if (sm == nullptr) {
272         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
273         return nullptr;
274     }
275     sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
276     if (packageManager == nullptr) {
277         ALOGW("%s: failed to retrieve native package manager", __func__);
278         return nullptr;
279     }
280     return interface_cast<content::pm::IPackageManagerNative>(packageManager);
281 }
282 
doIsAllowed(uid_t uid)283 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
284     if (mPackageManager == nullptr) {
285         /** Can not fetch package manager at construction it may not yet be registered. */
286         mPackageManager = retreivePackageManager();
287         if (mPackageManager == nullptr) {
288             ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
289             return std::nullopt;
290         }
291     }
292 
293     std::vector<std::string> packageNames;
294     auto status = mPackageManager->getNamesForUids({(int32_t)uid}, &packageNames);
295     if (!status.isOk()) {
296         ALOGW("%s: Playback capture is denied for uid %u as the package names could not be "
297               "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
298         return std::nullopt;
299     }
300     if (packageNames.empty()) {
301         ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
302               "from the package manager: %s", __func__, uid, status.toString8().c_str());
303         return std::nullopt;
304     }
305     std::vector<bool> isAllowed;
306     status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
307     if (!status.isOk()) {
308         ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
309               "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
310         return std::nullopt;
311     }
312     if (packageNames.size() != isAllowed.size()) {
313         ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent"
314               " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size());
315         return std::nullopt;
316     }
317 
318     // Zip together packageNames and isAllowed for debug logs
319     Packages& packages = mDebugLog[uid];
320     packages.resize(packageNames.size()); // Reuse all objects
321     std::transform(begin(packageNames), end(packageNames), begin(isAllowed),
322                    begin(packages), [] (auto& name, bool isAllowed) -> Package {
323                        return {std::move(name), isAllowed};
324                    });
325 
326     // Only allow playback record if all packages in this UID allow it
327     bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed),
328                                                   [](bool b) { return b; });
329 
330     return playbackCaptureAllowed;
331 }
332 
dump(int fd,int spaces) const333 void MediaPackageManager::dump(int fd, int spaces) const {
334     dprintf(fd, "%*sAllow playback capture log:\n", spaces, "");
335     if (mPackageManager == nullptr) {
336         dprintf(fd, "%*sNo package manager\n", spaces + 2, "");
337     }
338     dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors);
339 
340     for (const auto& uidCache : mDebugLog) {
341         for (const auto& package : std::get<Packages>(uidCache)) {
342             dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "",
343                     std::get<const uid_t>(uidCache),
344                     package.playbackCaptureAllowed ? "true " : "false",
345                     package.name.c_str());
346         }
347     }
348 }
349 
350 // How long we hold info before we re-fetch it (24 hours) if we found it previously.
351 static constexpr nsecs_t INFO_EXPIRATION_NS = 24 * 60 * 60 * NANOS_PER_SECOND;
352 // Maximum info records we retain before clearing everything.
353 static constexpr size_t INFO_CACHE_MAX = 1000;
354 
355 // The original code is from MediaMetricsService.cpp.
getInfo(uid_t uid)356 mediautils::UidInfo::Info mediautils::UidInfo::getInfo(uid_t uid)
357 {
358     const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
359     struct mediautils::UidInfo::Info info;
360     {
361         std::lock_guard _l(mLock);
362         auto it = mInfoMap.find(uid);
363         if (it != mInfoMap.end()) {
364             info = it->second;
365             ALOGV("%s: uid %d expiration %lld now %lld",
366                     __func__, uid, (long long)info.expirationNs, (long long)now);
367             if (info.expirationNs <= now) {
368                 // purge the stale entry and fall into re-fetching
369                 ALOGV("%s: entry for uid %d expired, now %lld",
370                         __func__, uid, (long long)now);
371                 mInfoMap.erase(it);
372                 info.uid = (uid_t)-1;  // this is always fully overwritten
373             }
374         }
375     }
376 
377     // if we did not find it in our map, look it up
378     if (info.uid == (uid_t)(-1)) {
379         sp<IServiceManager> sm = defaultServiceManager();
380         sp<content::pm::IPackageManagerNative> package_mgr;
381         if (sm.get() == nullptr) {
382             ALOGE("%s: Cannot find service manager", __func__);
383         } else {
384             sp<IBinder> binder = sm->getService(String16("package_native"));
385             if (binder.get() == nullptr) {
386                 ALOGE("%s: Cannot find package_native", __func__);
387             } else {
388                 package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder);
389             }
390         }
391 
392         // find package name
393         std::string pkg;
394         if (package_mgr != nullptr) {
395             std::vector<std::string> names;
396             binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names);
397             if (!status.isOk()) {
398                 ALOGE("%s: getNamesForUids failed: %s",
399                         __func__, status.exceptionMessage().c_str());
400             } else {
401                 if (!names[0].empty()) {
402                     pkg = names[0].c_str();
403                 }
404             }
405         }
406 
407         if (pkg.empty()) {
408             struct passwd pw{}, *result;
409             char buf[8192]; // extra buffer space - should exceed what is
410                             // required in struct passwd_pw (tested),
411                             // and even then this is only used in backup
412                             // when the package manager is unavailable.
413             if (getpwuid_r(uid, &pw, buf, sizeof(buf), &result) == 0
414                     && result != nullptr
415                     && result->pw_name != nullptr) {
416                 pkg = result->pw_name;
417             }
418         }
419 
420         // strip any leading "shared:" strings that came back
421         if (pkg.compare(0, 7, "shared:") == 0) {
422             pkg.erase(0, 7);
423         }
424 
425         // determine how pkg was installed and the versionCode
426         std::string installer;
427         int64_t versionCode = 0;
428         bool notFound = false;
429         if (pkg.empty()) {
430             pkg = std::to_string(uid); // not found
431             notFound = true;
432         } else if (strchr(pkg.c_str(), '.') == nullptr) {
433             // not of form 'com.whatever...'; assume internal
434             // so we don't need to look it up in package manager.
435         } else if (strncmp(pkg.c_str(), "android.", 8) == 0) {
436             // android.* packages are assumed fine
437         } else if (package_mgr.get() != nullptr) {
438             String16 pkgName16(pkg.c_str());
439             binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer);
440             if (!status.isOk()) {
441                 ALOGE("%s: getInstallerForPackage failed: %s",
442                         __func__, status.exceptionMessage().c_str());
443             }
444 
445             // skip if we didn't get an installer
446             if (status.isOk()) {
447                 status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode);
448                 if (!status.isOk()) {
449                     ALOGE("%s: getVersionCodeForPackage failed: %s",
450                             __func__, status.exceptionMessage().c_str());
451                 }
452             }
453 
454             ALOGV("%s: package '%s' installed by '%s' versioncode %lld",
455                     __func__, pkg.c_str(), installer.c_str(), (long long)versionCode);
456         }
457 
458         // add it to the map, to save a subsequent lookup
459         std::lock_guard _l(mLock);
460         // first clear if we have too many cached elements.  This would be rare.
461         if (mInfoMap.size() >= INFO_CACHE_MAX) mInfoMap.clear();
462 
463         // always overwrite
464         info.uid = uid;
465         info.package = std::move(pkg);
466         info.installer = std::move(installer);
467         info.versionCode = versionCode;
468         info.expirationNs = now + (notFound ? 0 : INFO_EXPIRATION_NS);
469         ALOGV("%s: adding uid %d package '%s' expirationNs: %lld",
470                 __func__, uid, info.package.c_str(), (long long)info.expirationNs);
471         mInfoMap[uid] = info;
472     }
473     return info;
474 }
475 
476 } // namespace android
477