• 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 #include <system/audio-hal-enums.h>
26 #include <media/AidlConversion.h>
27 #include <media/AidlConversionUtil.h>
28 #include <android/content/AttributionSourceState.h>
29 
30 #include <iterator>
31 #include <algorithm>
32 #include <pwd.h>
33 
34 /* When performing permission checks we do not use permission cache for
35  * runtime permissions (protection level dangerous) as they may change at
36  * runtime. All other permissions (protection level normal and dangerous)
37  * can be cached as they never change. Of course all permission checked
38  * here are platform defined.
39  */
40 
41 namespace android {
42 
43 using content::AttributionSourceState;
44 
45 static const String16 sAndroidPermissionRecordAudio("android.permission.RECORD_AUDIO");
46 static const String16 sModifyPhoneState("android.permission.MODIFY_PHONE_STATE");
47 static const String16 sModifyAudioRouting("android.permission.MODIFY_AUDIO_ROUTING");
48 
resolveCallingPackage(PermissionController & permissionController,const std::optional<String16> opPackageName,uid_t uid)49 static String16 resolveCallingPackage(PermissionController& permissionController,
50         const std::optional<String16> opPackageName, uid_t uid) {
51     if (opPackageName.has_value() && opPackageName.value().size() > 0) {
52         return opPackageName.value();
53     }
54     // In some cases the calling code has no access to the package it runs under.
55     // For example, code using the wilhelm framework's OpenSL-ES APIs. In this
56     // case we will get the packages for the calling UID and pick the first one
57     // for attributing the app op. This will work correctly for runtime permissions
58     // as for legacy apps we will toggle the app op for all packages in the UID.
59     // The caveat is that the operation may be attributed to the wrong package and
60     // stats based on app ops may be slightly off.
61     Vector<String16> packages;
62     permissionController.getPackagesForUid(uid, packages);
63     if (packages.isEmpty()) {
64         ALOGE("No packages for uid %d", uid);
65         return String16();
66     }
67     return packages[0];
68 }
69 
getOpForSource(audio_source_t source)70 int32_t getOpForSource(audio_source_t source) {
71   switch (source) {
72     case AUDIO_SOURCE_HOTWORD:
73       return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
74     case AUDIO_SOURCE_REMOTE_SUBMIX:
75       return AppOpsManager::OP_RECORD_AUDIO_OUTPUT;
76     case AUDIO_SOURCE_VOICE_DOWNLINK:
77       return AppOpsManager::OP_RECORD_INCOMING_PHONE_AUDIO;
78     case AUDIO_SOURCE_DEFAULT:
79     default:
80       return AppOpsManager::OP_RECORD_AUDIO;
81   }
82 }
83 
resolveAttributionSource(const AttributionSourceState & callerAttributionSource)84 std::optional<AttributionSourceState> resolveAttributionSource(
85         const AttributionSourceState& callerAttributionSource) {
86     AttributionSourceState nextAttributionSource = callerAttributionSource;
87 
88     if (!nextAttributionSource.packageName.has_value()) {
89         nextAttributionSource = AttributionSourceState(nextAttributionSource);
90         PermissionController permissionController;
91         const uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(nextAttributionSource.uid));
92         nextAttributionSource.packageName = VALUE_OR_FATAL(legacy2aidl_String16_string(
93                 resolveCallingPackage(permissionController, VALUE_OR_FATAL(
94                 aidl2legacy_string_view_String16(nextAttributionSource.packageName.value_or(""))),
95                 uid)));
96         if (!nextAttributionSource.packageName.has_value()) {
97             return std::nullopt;
98         }
99     }
100 
101     AttributionSourceState myAttributionSource;
102     myAttributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
103     myAttributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
104     myAttributionSource.token = sp<BBinder>::make();
105     myAttributionSource.next.push_back(nextAttributionSource);
106 
107     return std::optional<AttributionSourceState>{myAttributionSource};
108 }
109 
checkRecordingInternal(const AttributionSourceState & attributionSource,const String16 & msg,bool start,audio_source_t source)110 static bool checkRecordingInternal(const AttributionSourceState& attributionSource,
111         const String16& msg, bool start, audio_source_t source) {
112     // Okay to not track in app ops as audio server or media server is us and if
113     // device is rooted security model is considered compromised.
114     // system_server loses its RECORD_AUDIO permission when a secondary
115     // user is active, but it is a core system service so let it through.
116     // TODO(b/141210120): UserManager.DISALLOW_RECORD_AUDIO should not affect system user 0
117     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
118     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(uid)) return true;
119 
120     // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
121     // may open a record track on behalf of a client. Note that pid may be a tid.
122     // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
123     const std::optional<AttributionSourceState> resolvedAttributionSource =
124             resolveAttributionSource(attributionSource);
125     if (!resolvedAttributionSource.has_value()) {
126         return false;
127     }
128 
129     const int32_t attributedOpCode = getOpForSource(source);
130 
131     permission::PermissionChecker permissionChecker;
132     bool permitted = false;
133     if (start) {
134         permitted = (permissionChecker.checkPermissionForStartDataDeliveryFromDatasource(
135                 sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
136                 attributedOpCode) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
137     } else {
138         permitted = (permissionChecker.checkPermissionForPreflightFromDatasource(
139                 sAndroidPermissionRecordAudio, resolvedAttributionSource.value(), msg,
140                 attributedOpCode) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
141     }
142 
143     return permitted;
144 }
145 
recordingAllowed(const AttributionSourceState & attributionSource,audio_source_t source)146 bool recordingAllowed(const AttributionSourceState& attributionSource, audio_source_t source) {
147     return checkRecordingInternal(attributionSource, String16(), /*start*/ false, source);
148 }
149 
startRecording(const AttributionSourceState & attributionSource,const String16 & msg,audio_source_t source)150 bool startRecording(const AttributionSourceState& attributionSource, const String16& msg,
151         audio_source_t source) {
152     return checkRecordingInternal(attributionSource, msg, /*start*/ true, source);
153 }
154 
finishRecording(const AttributionSourceState & attributionSource,audio_source_t source)155 void finishRecording(const AttributionSourceState& attributionSource, audio_source_t source) {
156     // Okay to not track in app ops as audio server is us and if
157     // device is rooted security model is considered compromised.
158     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
159     if (isAudioServerOrMediaServerOrSystemServerOrRootUid(uid)) return;
160 
161     // We specify a pid and uid here as mediaserver (aka MediaRecorder or StageFrightRecorder)
162     // may open a record track on behalf of a client. Note that pid may be a tid.
163     // IMPORTANT: DON'T USE PermissionCache - RUNTIME PERMISSIONS CHANGE.
164     const std::optional<AttributionSourceState> resolvedAttributionSource =
165             resolveAttributionSource(attributionSource);
166     if (!resolvedAttributionSource.has_value()) {
167         return;
168     }
169 
170     const int32_t attributedOpCode = getOpForSource(source);
171     permission::PermissionChecker permissionChecker;
172     permissionChecker.finishDataDeliveryFromDatasource(attributedOpCode,
173             resolvedAttributionSource.value());
174 }
175 
captureAudioOutputAllowed(const AttributionSourceState & attributionSource)176 bool captureAudioOutputAllowed(const AttributionSourceState& attributionSource) {
177     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
178     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
179     if (isAudioServerOrRootUid(uid)) return true;
180     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
181     bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
182     if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
183     return ok;
184 }
185 
captureMediaOutputAllowed(const AttributionSourceState & attributionSource)186 bool captureMediaOutputAllowed(const AttributionSourceState& attributionSource) {
187     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
188     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
189     if (isAudioServerOrRootUid(uid)) return true;
190     static const String16 sCaptureMediaOutput("android.permission.CAPTURE_MEDIA_OUTPUT");
191     bool ok = PermissionCache::checkPermission(sCaptureMediaOutput, pid, uid);
192     if (!ok) ALOGE("Request requires android.permission.CAPTURE_MEDIA_OUTPUT");
193     return ok;
194 }
195 
captureTunerAudioInputAllowed(const AttributionSourceState & attributionSource)196 bool captureTunerAudioInputAllowed(const AttributionSourceState& attributionSource) {
197     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
198     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
199     if (isAudioServerOrRootUid(uid)) return true;
200     static const String16 sCaptureTunerAudioInput("android.permission.CAPTURE_TUNER_AUDIO_INPUT");
201     bool ok = PermissionCache::checkPermission(sCaptureTunerAudioInput, pid, uid);
202     if (!ok) ALOGV("Request requires android.permission.CAPTURE_TUNER_AUDIO_INPUT");
203     return ok;
204 }
205 
captureVoiceCommunicationOutputAllowed(const AttributionSourceState & attributionSource)206 bool captureVoiceCommunicationOutputAllowed(const AttributionSourceState& attributionSource) {
207     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
208     uid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
209     if (isAudioServerOrRootUid(uid)) return true;
210     static const String16 sCaptureVoiceCommOutput(
211         "android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
212     bool ok = PermissionCache::checkPermission(sCaptureVoiceCommOutput, pid, uid);
213     if (!ok) ALOGE("Request requires android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT");
214     return ok;
215 }
216 
captureHotwordAllowed(const AttributionSourceState & attributionSource)217 bool captureHotwordAllowed(const AttributionSourceState& attributionSource) {
218     // CAPTURE_AUDIO_HOTWORD permission implies RECORD_AUDIO permission
219     bool ok = recordingAllowed(attributionSource);
220 
221     if (ok) {
222         static const String16 sCaptureHotwordAllowed("android.permission.CAPTURE_AUDIO_HOTWORD");
223         // Use PermissionChecker, which includes some logic for allowing the isolated
224         // HotwordDetectionService to hold certain permissions.
225         permission::PermissionChecker permissionChecker;
226         ok = (permissionChecker.checkPermissionForPreflight(
227                 sCaptureHotwordAllowed, attributionSource, String16(),
228                 AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED);
229     }
230     if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
231     return ok;
232 }
233 
settingsAllowed()234 bool settingsAllowed() {
235     // given this is a permission check, could this be isAudioServerOrRootUid()?
236     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
237     static const String16 sAudioSettings("android.permission.MODIFY_AUDIO_SETTINGS");
238     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
239     bool ok = PermissionCache::checkCallingPermission(sAudioSettings);
240     if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
241     return ok;
242 }
243 
modifyAudioRoutingAllowed()244 bool modifyAudioRoutingAllowed() {
245     return modifyAudioRoutingAllowed(getCallingAttributionSource());
246 }
247 
modifyAudioRoutingAllowed(const AttributionSourceState & attributionSource)248 bool modifyAudioRoutingAllowed(const AttributionSourceState& attributionSource) {
249     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
250     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
251     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
252     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
253     bool ok = PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
254     if (!ok) ALOGE("%s(): android.permission.MODIFY_AUDIO_ROUTING denied for uid %d",
255         __func__, uid);
256     return ok;
257 }
258 
modifyDefaultAudioEffectsAllowed()259 bool modifyDefaultAudioEffectsAllowed() {
260     return modifyDefaultAudioEffectsAllowed(getCallingAttributionSource());
261 }
262 
modifyDefaultAudioEffectsAllowed(const AttributionSourceState & attributionSource)263 bool modifyDefaultAudioEffectsAllowed(const AttributionSourceState& attributionSource) {
264     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
265     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
266     if (isAudioServerUid(IPCThreadState::self()->getCallingUid())) return true;
267 
268     static const String16 sModifyDefaultAudioEffectsAllowed(
269             "android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS");
270     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
271     bool ok = PermissionCache::checkPermission(sModifyDefaultAudioEffectsAllowed, pid, uid);
272     ALOGE_IF(!ok, "%s(): android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS denied for uid %d",
273             __func__, uid);
274     return ok;
275 }
276 
dumpAllowed()277 bool dumpAllowed() {
278     static const String16 sDump("android.permission.DUMP");
279     // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
280     bool ok = PermissionCache::checkCallingPermission(sDump);
281     // convention is for caller to dump an error message to fd instead of logging here
282     //if (!ok) ALOGE("Request requires android.permission.DUMP");
283     return ok;
284 }
285 
modifyPhoneStateAllowed(const AttributionSourceState & attributionSource)286 bool modifyPhoneStateAllowed(const AttributionSourceState& attributionSource) {
287     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
288     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
289     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid);
290     ALOGE_IF(!ok, "Request requires %s", String8(sModifyPhoneState).c_str());
291     return ok;
292 }
293 
294 // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
bypassInterruptionPolicyAllowed(const AttributionSourceState & attributionSource)295 bool bypassInterruptionPolicyAllowed(const AttributionSourceState& attributionSource) {
296     uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(attributionSource.uid));
297     pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(attributionSource.pid));
298     static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
299     bool ok = PermissionCache::checkPermission(sModifyPhoneState, pid, uid)
300         || PermissionCache::checkPermission(sWriteSecureSettings, pid, uid)
301         || PermissionCache::checkPermission(sModifyAudioRouting, pid, uid);
302     ALOGE_IF(!ok, "Request requires %s or %s",
303              String8(sModifyPhoneState).c_str(), String8(sWriteSecureSettings).c_str());
304     return ok;
305 }
306 
getCallingAttributionSource()307 AttributionSourceState getCallingAttributionSource() {
308     AttributionSourceState attributionSource = AttributionSourceState();
309     attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(
310             IPCThreadState::self()->getCallingPid()));
311     attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(
312             IPCThreadState::self()->getCallingUid()));
313     attributionSource.token = sp<BBinder>::make();
314   return attributionSource;
315 }
316 
purgePermissionCache()317 void purgePermissionCache() {
318     PermissionCache::purgeCache();
319 }
320 
checkIMemory(const sp<IMemory> & iMemory)321 status_t checkIMemory(const sp<IMemory>& iMemory)
322 {
323     if (iMemory == 0) {
324         ALOGE("%s check failed: NULL IMemory pointer", __FUNCTION__);
325         return BAD_VALUE;
326     }
327 
328     sp<IMemoryHeap> heap = iMemory->getMemory();
329     if (heap == 0) {
330         ALOGE("%s check failed: NULL heap pointer", __FUNCTION__);
331         return BAD_VALUE;
332     }
333 
334     off_t size = lseek(heap->getHeapID(), 0, SEEK_END);
335     lseek(heap->getHeapID(), 0, SEEK_SET);
336 
337     if (iMemory->unsecurePointer() == NULL || size < (off_t)iMemory->size()) {
338         ALOGE("%s check failed: pointer %p size %zu fd size %u",
339               __FUNCTION__, iMemory->unsecurePointer(), iMemory->size(), (uint32_t)size);
340         return BAD_VALUE;
341     }
342 
343     return NO_ERROR;
344 }
345 
retrievePackageManager()346 sp<content::pm::IPackageManagerNative> MediaPackageManager::retrievePackageManager() {
347     const sp<IServiceManager> sm = defaultServiceManager();
348     if (sm == nullptr) {
349         ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
350         return nullptr;
351     }
352     sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
353     if (packageManager == nullptr) {
354         ALOGW("%s: failed to retrieve native package manager", __func__);
355         return nullptr;
356     }
357     return interface_cast<content::pm::IPackageManagerNative>(packageManager);
358 }
359 
doIsAllowed(uid_t uid)360 std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
361     if (mPackageManager == nullptr) {
362         /** Can not fetch package manager at construction it may not yet be registered. */
363         mPackageManager = retrievePackageManager();
364         if (mPackageManager == nullptr) {
365             ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
366             return std::nullopt;
367         }
368     }
369 
370     // Retrieve package names for the UID and transform to a std::vector<std::string>.
371     Vector<String16> str16PackageNames;
372     PermissionController{}.getPackagesForUid(uid, str16PackageNames);
373     std::vector<std::string> packageNames;
374     for (const auto& str16PackageName : str16PackageNames) {
375         packageNames.emplace_back(String8(str16PackageName).string());
376     }
377     if (packageNames.empty()) {
378         ALOGW("%s: Playback capture for uid %u is denied as no package name could be retrieved "
379               "from the package manager.", __func__, uid);
380         return std::nullopt;
381     }
382     std::vector<bool> isAllowed;
383     auto status = mPackageManager->isAudioPlaybackCaptureAllowed(packageNames, &isAllowed);
384     if (!status.isOk()) {
385         ALOGW("%s: Playback capture is denied for uid %u as the manifest property could not be "
386               "retrieved from the package manager: %s", __func__, uid, status.toString8().c_str());
387         return std::nullopt;
388     }
389     if (packageNames.size() != isAllowed.size()) {
390         ALOGW("%s: Playback capture is denied for uid %u as the package manager returned incoherent"
391               " response size: %zu != %zu", __func__, uid, packageNames.size(), isAllowed.size());
392         return std::nullopt;
393     }
394 
395     // Zip together packageNames and isAllowed for debug logs
396     Packages& packages = mDebugLog[uid];
397     packages.resize(packageNames.size()); // Reuse all objects
398     std::transform(begin(packageNames), end(packageNames), begin(isAllowed),
399                    begin(packages), [] (auto& name, bool isAllowed) -> Package {
400                        return {std::move(name), isAllowed};
401                    });
402 
403     // Only allow playback record if all packages in this UID allow it
404     bool playbackCaptureAllowed = std::all_of(begin(isAllowed), end(isAllowed),
405                                                   [](bool b) { return b; });
406 
407     return playbackCaptureAllowed;
408 }
409 
dump(int fd,int spaces) const410 void MediaPackageManager::dump(int fd, int spaces) const {
411     dprintf(fd, "%*sAllow playback capture log:\n", spaces, "");
412     if (mPackageManager == nullptr) {
413         dprintf(fd, "%*sNo package manager\n", spaces + 2, "");
414     }
415     dprintf(fd, "%*sPackage manager errors: %u\n", spaces + 2, "", mPackageManagerErrors);
416 
417     for (const auto& uidCache : mDebugLog) {
418         for (const auto& package : std::get<Packages>(uidCache)) {
419             dprintf(fd, "%*s- uid=%5u, allowPlaybackCapture=%s, packageName=%s\n", spaces + 2, "",
420                     std::get<const uid_t>(uidCache),
421                     package.playbackCaptureAllowed ? "true " : "false",
422                     package.name.c_str());
423         }
424     }
425 }
426 
427 // How long we hold info before we re-fetch it (24 hours) if we found it previously.
428 static constexpr nsecs_t INFO_EXPIRATION_NS = 24 * 60 * 60 * NANOS_PER_SECOND;
429 // Maximum info records we retain before clearing everything.
430 static constexpr size_t INFO_CACHE_MAX = 1000;
431 
432 // The original code is from MediaMetricsService.cpp.
getInfo(uid_t uid)433 mediautils::UidInfo::Info mediautils::UidInfo::getInfo(uid_t uid)
434 {
435     const nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
436     struct mediautils::UidInfo::Info info;
437     {
438         std::lock_guard _l(mLock);
439         auto it = mInfoMap.find(uid);
440         if (it != mInfoMap.end()) {
441             info = it->second;
442             ALOGV("%s: uid %d expiration %lld now %lld",
443                     __func__, uid, (long long)info.expirationNs, (long long)now);
444             if (info.expirationNs <= now) {
445                 // purge the stale entry and fall into re-fetching
446                 ALOGV("%s: entry for uid %d expired, now %lld",
447                         __func__, uid, (long long)now);
448                 mInfoMap.erase(it);
449                 info.uid = (uid_t)-1;  // this is always fully overwritten
450             }
451         }
452     }
453 
454     // if we did not find it in our map, look it up
455     if (info.uid == (uid_t)(-1)) {
456         sp<IServiceManager> sm = defaultServiceManager();
457         sp<content::pm::IPackageManagerNative> package_mgr;
458         if (sm.get() == nullptr) {
459             ALOGE("%s: Cannot find service manager", __func__);
460         } else {
461             sp<IBinder> binder = sm->getService(String16("package_native"));
462             if (binder.get() == nullptr) {
463                 ALOGE("%s: Cannot find package_native", __func__);
464             } else {
465                 package_mgr = interface_cast<content::pm::IPackageManagerNative>(binder);
466             }
467         }
468 
469         // find package name
470         std::string pkg;
471         if (package_mgr != nullptr) {
472             std::vector<std::string> names;
473             binder::Status status = package_mgr->getNamesForUids({(int)uid}, &names);
474             if (!status.isOk()) {
475                 ALOGE("%s: getNamesForUids failed: %s",
476                         __func__, status.exceptionMessage().c_str());
477             } else {
478                 if (!names[0].empty()) {
479                     pkg = names[0].c_str();
480                 }
481             }
482         }
483 
484         if (pkg.empty()) {
485             struct passwd pw{}, *result;
486             char buf[8192]; // extra buffer space - should exceed what is
487                             // required in struct passwd_pw (tested),
488                             // and even then this is only used in backup
489                             // when the package manager is unavailable.
490             if (getpwuid_r(uid, &pw, buf, sizeof(buf), &result) == 0
491                     && result != nullptr
492                     && result->pw_name != nullptr) {
493                 pkg = result->pw_name;
494             }
495         }
496 
497         // strip any leading "shared:" strings that came back
498         if (pkg.compare(0, 7, "shared:") == 0) {
499             pkg.erase(0, 7);
500         }
501 
502         // determine how pkg was installed and the versionCode
503         std::string installer;
504         int64_t versionCode = 0;
505         bool notFound = false;
506         if (pkg.empty()) {
507             pkg = std::to_string(uid); // not found
508             notFound = true;
509         } else if (strchr(pkg.c_str(), '.') == nullptr) {
510             // not of form 'com.whatever...'; assume internal
511             // so we don't need to look it up in package manager.
512         } else if (strncmp(pkg.c_str(), "android.", 8) == 0) {
513             // android.* packages are assumed fine
514         } else if (package_mgr.get() != nullptr) {
515             String16 pkgName16(pkg.c_str());
516             binder::Status status = package_mgr->getInstallerForPackage(pkgName16, &installer);
517             if (!status.isOk()) {
518                 ALOGE("%s: getInstallerForPackage failed: %s",
519                         __func__, status.exceptionMessage().c_str());
520             }
521 
522             // skip if we didn't get an installer
523             if (status.isOk()) {
524                 status = package_mgr->getVersionCodeForPackage(pkgName16, &versionCode);
525                 if (!status.isOk()) {
526                     ALOGE("%s: getVersionCodeForPackage failed: %s",
527                             __func__, status.exceptionMessage().c_str());
528                 }
529             }
530 
531             ALOGV("%s: package '%s' installed by '%s' versioncode %lld",
532                     __func__, pkg.c_str(), installer.c_str(), (long long)versionCode);
533         }
534 
535         // add it to the map, to save a subsequent lookup
536         std::lock_guard _l(mLock);
537         // first clear if we have too many cached elements.  This would be rare.
538         if (mInfoMap.size() >= INFO_CACHE_MAX) mInfoMap.clear();
539 
540         // always overwrite
541         info.uid = uid;
542         info.package = std::move(pkg);
543         info.installer = std::move(installer);
544         info.versionCode = versionCode;
545         info.expirationNs = now + (notFound ? 0 : INFO_EXPIRATION_NS);
546         ALOGV("%s: adding uid %d package '%s' expirationNs: %lld",
547                 __func__, uid, info.package.c_str(), (long long)info.expirationNs);
548         mInfoMap[uid] = info;
549     }
550     return info;
551 }
552 
553 } // namespace android
554