1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, versionCode 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 #define DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "hash.h"
20 #include "stats_log_util.h"
21 #include "guardrail/StatsdStats.h"
22 #include "packages/UidMap.h"
23 
24 #include <android/os/IStatsCompanionService.h>
25 #include <binder/IServiceManager.h>
26 #include <utils/Errors.h>
27 
28 #include <inttypes.h>
29 
30 using namespace android;
31 
32 using android::base::StringPrintf;
33 using android::util::FIELD_COUNT_REPEATED;
34 using android::util::FIELD_TYPE_BOOL;
35 using android::util::FIELD_TYPE_FLOAT;
36 using android::util::FIELD_TYPE_INT32;
37 using android::util::FIELD_TYPE_INT64;
38 using android::util::FIELD_TYPE_UINT64;
39 using android::util::FIELD_TYPE_MESSAGE;
40 using android::util::FIELD_TYPE_STRING;
41 using android::util::ProtoOutputStream;
42 
43 namespace android {
44 namespace os {
45 namespace statsd {
46 
47 const int FIELD_ID_SNAPSHOT_PACKAGE_NAME = 1;
48 const int FIELD_ID_SNAPSHOT_PACKAGE_VERSION = 2;
49 const int FIELD_ID_SNAPSHOT_PACKAGE_UID = 3;
50 const int FIELD_ID_SNAPSHOT_PACKAGE_DELETED = 4;
51 const int FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH = 5;
52 const int FIELD_ID_SNAPSHOT_TIMESTAMP = 1;
53 const int FIELD_ID_SNAPSHOT_PACKAGE_INFO = 2;
54 const int FIELD_ID_SNAPSHOTS = 1;
55 const int FIELD_ID_CHANGES = 2;
56 const int FIELD_ID_CHANGE_DELETION = 1;
57 const int FIELD_ID_CHANGE_TIMESTAMP = 2;
58 const int FIELD_ID_CHANGE_PACKAGE = 3;
59 const int FIELD_ID_CHANGE_UID = 4;
60 const int FIELD_ID_CHANGE_NEW_VERSION = 5;
61 const int FIELD_ID_CHANGE_PREV_VERSION = 6;
62 const int FIELD_ID_CHANGE_PACKAGE_HASH = 7;
63 
UidMap()64 UidMap::UidMap() : mBytesUsed(0) {}
65 
~UidMap()66 UidMap::~UidMap() {}
67 
hasApp(int uid,const string & packageName) const68 bool UidMap::hasApp(int uid, const string& packageName) const {
69     lock_guard<mutex> lock(mMutex);
70 
71     auto it = mMap.find(std::make_pair(uid, packageName));
72     return it != mMap.end() && !it->second.deleted;
73 }
74 
normalizeAppName(const string & appName) const75 string UidMap::normalizeAppName(const string& appName) const {
76     string normalizedName = appName;
77     std::transform(normalizedName.begin(), normalizedName.end(), normalizedName.begin(), ::tolower);
78     return normalizedName;
79 }
80 
getAppNamesFromUid(const int32_t & uid,bool returnNormalized) const81 std::set<string> UidMap::getAppNamesFromUid(const int32_t& uid, bool returnNormalized) const {
82     lock_guard<mutex> lock(mMutex);
83     return getAppNamesFromUidLocked(uid,returnNormalized);
84 }
85 
getAppNamesFromUidLocked(const int32_t & uid,bool returnNormalized) const86 std::set<string> UidMap::getAppNamesFromUidLocked(const int32_t& uid, bool returnNormalized) const {
87     std::set<string> names;
88     for (const auto& kv : mMap) {
89         if (kv.first.first == uid && !kv.second.deleted) {
90             names.insert(returnNormalized ? normalizeAppName(kv.first.second) : kv.first.second);
91         }
92     }
93     return names;
94 }
95 
getAppVersion(int uid,const string & packageName) const96 int64_t UidMap::getAppVersion(int uid, const string& packageName) const {
97     lock_guard<mutex> lock(mMutex);
98 
99     auto it = mMap.find(std::make_pair(uid, packageName));
100     if (it == mMap.end() || it->second.deleted) {
101         return 0;
102     }
103     return it->second.versionCode;
104 }
105 
updateMap(const int64_t & timestamp,const vector<int32_t> & uid,const vector<int64_t> & versionCode,const vector<String16> & packageName)106 void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid,
107                        const vector<int64_t>& versionCode, const vector<String16>& packageName) {
108     vector<wp<PackageInfoListener>> broadcastList;
109     {
110         lock_guard<mutex> lock(mMutex);  // Exclusively lock for updates.
111 
112         std::unordered_map<std::pair<int, string>, AppData, PairHash> deletedApps;
113 
114         // Copy all the deleted apps.
115         for (const auto& kv : mMap) {
116             if (kv.second.deleted) {
117                 deletedApps[kv.first] = kv.second;
118             }
119         }
120 
121         mMap.clear();
122         for (size_t j = 0; j < uid.size(); j++) {
123             string package = string(String8(packageName[j]).string());
124             mMap[std::make_pair(uid[j], package)] = AppData(versionCode[j]);
125         }
126 
127         for (const auto& kv : deletedApps) {
128             auto mMapIt = mMap.find(kv.first);
129             if (mMapIt != mMap.end()) {
130                 // Insert this deleted app back into the current map.
131                 mMap[kv.first] = kv.second;
132             }
133         }
134 
135         ensureBytesUsedBelowLimit();
136         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
137         getListenerListCopyLocked(&broadcastList);
138     }
139     // To avoid invoking callback while holding the internal lock. we get a copy of the listener
140     // list and invoke the callback. It's still possible that after we copy the list, a
141     // listener removes itself before we call it. It's then the listener's job to handle it (expect
142     // the callback to be called after listener is removed, and the listener should properly
143     // ignore it).
144     for (auto weakPtr : broadcastList) {
145         auto strongPtr = weakPtr.promote();
146         if (strongPtr != NULL) {
147             strongPtr->onUidMapReceived(timestamp);
148         }
149     }
150 }
151 
updateApp(const int64_t & timestamp,const String16 & app_16,const int32_t & uid,const int64_t & versionCode)152 void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid,
153                        const int64_t& versionCode) {
154     vector<wp<PackageInfoListener>> broadcastList;
155     string appName = string(String8(app_16).string());
156     {
157         lock_guard<mutex> lock(mMutex);
158         int32_t prevVersion = 0;
159         bool found = false;
160         auto it = mMap.find(std::make_pair(uid, appName));
161         if (it != mMap.end()) {
162             found = true;
163             prevVersion = it->second.versionCode;
164             it->second.versionCode = versionCode;
165             it->second.deleted = false;
166         }
167         if (!found) {
168             // Otherwise, we need to add an app at this uid.
169             mMap[std::make_pair(uid, appName)] = AppData(versionCode);
170         } else {
171             // Only notify the listeners if this is an app upgrade. If this app is being installed
172             // for the first time, then we don't notify the listeners.
173             // It's also OK to split again if we're forming a partial bucket after re-installing an
174             // app after deletion.
175             getListenerListCopyLocked(&broadcastList);
176         }
177         mChanges.emplace_back(false, timestamp, appName, uid, versionCode, prevVersion);
178         mBytesUsed += kBytesChangeRecord;
179         ensureBytesUsedBelowLimit();
180         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
181         StatsdStats::getInstance().setUidMapChanges(mChanges.size());
182     }
183 
184     for (auto weakPtr : broadcastList) {
185         auto strongPtr = weakPtr.promote();
186         if (strongPtr != NULL) {
187             strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
188         }
189     }
190 }
191 
ensureBytesUsedBelowLimit()192 void UidMap::ensureBytesUsedBelowLimit() {
193     size_t limit;
194     if (maxBytesOverride <= 0) {
195         limit = StatsdStats::kMaxBytesUsedUidMap;
196     } else {
197         limit = maxBytesOverride;
198     }
199     while (mBytesUsed > limit) {
200         ALOGI("Bytes used %zu is above limit %zu, need to delete something", mBytesUsed, limit);
201         if (mChanges.size() > 0) {
202             mBytesUsed -= kBytesChangeRecord;
203             mChanges.pop_front();
204             StatsdStats::getInstance().noteUidMapDropped(1);
205         }
206     }
207 }
208 
getListenerListCopyLocked(vector<wp<PackageInfoListener>> * output)209 void UidMap::getListenerListCopyLocked(vector<wp<PackageInfoListener>>* output) {
210     for (auto weakIt = mSubscribers.begin(); weakIt != mSubscribers.end();) {
211         auto strongPtr = weakIt->promote();
212         if (strongPtr != NULL) {
213             output->push_back(*weakIt);
214             weakIt++;
215         } else {
216             weakIt = mSubscribers.erase(weakIt);
217             VLOG("The UidMap listener is gone, remove it now");
218         }
219     }
220 }
221 
removeApp(const int64_t & timestamp,const String16 & app_16,const int32_t & uid)222 void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const int32_t& uid) {
223     vector<wp<PackageInfoListener>> broadcastList;
224     string app = string(String8(app_16).string());
225     {
226         lock_guard<mutex> lock(mMutex);
227 
228         int64_t prevVersion = 0;
229         auto key = std::make_pair(uid, app);
230         auto it = mMap.find(key);
231         if (it != mMap.end() && !it->second.deleted) {
232             prevVersion = it->second.versionCode;
233             it->second.deleted = true;
234             mDeletedApps.push_back(key);
235         }
236         if (mDeletedApps.size() > StatsdStats::kMaxDeletedAppsInUidMap) {
237             // Delete the oldest one.
238             auto oldest = mDeletedApps.front();
239             mDeletedApps.pop_front();
240             mMap.erase(oldest);
241             StatsdStats::getInstance().noteUidMapAppDeletionDropped();
242         }
243         mChanges.emplace_back(true, timestamp, app, uid, 0, prevVersion);
244         mBytesUsed += kBytesChangeRecord;
245         ensureBytesUsedBelowLimit();
246         StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
247         StatsdStats::getInstance().setUidMapChanges(mChanges.size());
248         getListenerListCopyLocked(&broadcastList);
249     }
250 
251     for (auto weakPtr : broadcastList) {
252         auto strongPtr = weakPtr.promote();
253         if (strongPtr != NULL) {
254             strongPtr->notifyAppRemoved(timestamp, app, uid);
255         }
256     }
257 }
258 
addListener(wp<PackageInfoListener> producer)259 void UidMap::addListener(wp<PackageInfoListener> producer) {
260     lock_guard<mutex> lock(mMutex);  // Lock for updates
261     mSubscribers.insert(producer);
262 }
263 
removeListener(wp<PackageInfoListener> producer)264 void UidMap::removeListener(wp<PackageInfoListener> producer) {
265     lock_guard<mutex> lock(mMutex);  // Lock for updates
266     mSubscribers.erase(producer);
267 }
268 
assignIsolatedUid(int isolatedUid,int parentUid)269 void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) {
270     lock_guard<mutex> lock(mIsolatedMutex);
271 
272     mIsolatedUidMap[isolatedUid] = parentUid;
273 }
274 
removeIsolatedUid(int isolatedUid,int parentUid)275 void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) {
276     lock_guard<mutex> lock(mIsolatedMutex);
277 
278     auto it = mIsolatedUidMap.find(isolatedUid);
279     if (it != mIsolatedUidMap.end()) {
280         mIsolatedUidMap.erase(it);
281     }
282 }
283 
getHostUidOrSelf(int uid) const284 int UidMap::getHostUidOrSelf(int uid) const {
285     lock_guard<mutex> lock(mIsolatedMutex);
286 
287     auto it = mIsolatedUidMap.find(uid);
288     if (it != mIsolatedUidMap.end()) {
289         return it->second;
290     }
291     return uid;
292 }
293 
clearOutput()294 void UidMap::clearOutput() {
295     mChanges.clear();
296     // Also update the guardrail trackers.
297     StatsdStats::getInstance().setUidMapChanges(0);
298     mBytesUsed = 0;
299     StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
300 }
301 
getMinimumTimestampNs()302 int64_t UidMap::getMinimumTimestampNs() {
303     int64_t m = 0;
304     for (const auto& kv : mLastUpdatePerConfigKey) {
305         if (m == 0) {
306             m = kv.second;
307         } else if (kv.second < m) {
308             m = kv.second;
309         }
310     }
311     return m;
312 }
313 
getBytesUsed() const314 size_t UidMap::getBytesUsed() const {
315     return mBytesUsed;
316 }
317 
appendUidMap(const int64_t & timestamp,const ConfigKey & key,std::set<string> * str_set,ProtoOutputStream * proto)318 void UidMap::appendUidMap(const int64_t& timestamp, const ConfigKey& key,
319                           std::set<string> *str_set, ProtoOutputStream* proto) {
320     lock_guard<mutex> lock(mMutex);  // Lock for updates
321 
322     for (const ChangeRecord& record : mChanges) {
323         if (record.timestampNs > mLastUpdatePerConfigKey[key]) {
324             uint64_t changesToken =
325                     proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CHANGES);
326             proto->write(FIELD_TYPE_BOOL | FIELD_ID_CHANGE_DELETION, (bool)record.deletion);
327             proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_TIMESTAMP,
328                          (long long)record.timestampNs);
329             if (str_set != nullptr) {
330                 str_set->insert(record.package);
331                 proto->write(FIELD_TYPE_UINT64 | FIELD_ID_CHANGE_PACKAGE_HASH,
332                              (long long)Hash64(record.package));
333             } else {
334                 proto->write(FIELD_TYPE_STRING | FIELD_ID_CHANGE_PACKAGE, record.package);
335             }
336 
337             proto->write(FIELD_TYPE_INT32 | FIELD_ID_CHANGE_UID, (int)record.uid);
338             proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_NEW_VERSION, (long long)record.version);
339             proto->write(FIELD_TYPE_INT64 | FIELD_ID_CHANGE_PREV_VERSION,
340                          (long long)record.prevVersion);
341             proto->end(changesToken);
342         }
343     }
344 
345     // Write snapshot from current uid map state.
346     uint64_t snapshotsToken =
347             proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_SNAPSHOTS);
348     proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_TIMESTAMP, (long long)timestamp);
349     for (const auto& kv : mMap) {
350         uint64_t token = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
351                                       FIELD_ID_SNAPSHOT_PACKAGE_INFO);
352 
353         if (str_set != nullptr) {
354             str_set->insert(kv.first.second);
355             proto->write(FIELD_TYPE_UINT64 | FIELD_ID_SNAPSHOT_PACKAGE_NAME_HASH,
356                          (long long)Hash64(kv.first.second));
357         } else {
358             proto->write(FIELD_TYPE_STRING | FIELD_ID_SNAPSHOT_PACKAGE_NAME, kv.first.second);
359         }
360 
361         proto->write(FIELD_TYPE_INT64 | FIELD_ID_SNAPSHOT_PACKAGE_VERSION,
362                      (long long)kv.second.versionCode);
363         proto->write(FIELD_TYPE_INT32 | FIELD_ID_SNAPSHOT_PACKAGE_UID, kv.first.first);
364         proto->write(FIELD_TYPE_BOOL | FIELD_ID_SNAPSHOT_PACKAGE_DELETED, kv.second.deleted);
365         proto->end(token);
366     }
367     proto->end(snapshotsToken);
368 
369     int64_t prevMin = getMinimumTimestampNs();
370     mLastUpdatePerConfigKey[key] = timestamp;
371     int64_t newMin = getMinimumTimestampNs();
372 
373     if (newMin > prevMin) {  // Delete anything possible now that the minimum has
374                              // moved forward.
375         int64_t cutoff_nanos = newMin;
376         for (auto it_changes = mChanges.begin(); it_changes != mChanges.end();) {
377             if (it_changes->timestampNs < cutoff_nanos) {
378                 mBytesUsed -= kBytesChangeRecord;
379                 it_changes = mChanges.erase(it_changes);
380             } else {
381                 ++it_changes;
382             }
383         }
384     }
385     StatsdStats::getInstance().setCurrentUidMapMemory(mBytesUsed);
386     StatsdStats::getInstance().setUidMapChanges(mChanges.size());
387 }
388 
printUidMap(FILE * out) const389 void UidMap::printUidMap(FILE* out) const {
390     lock_guard<mutex> lock(mMutex);
391 
392     for (const auto& kv : mMap) {
393         if (!kv.second.deleted) {
394             fprintf(out, "%s, v%" PRId64 " (%i)\n", kv.first.second.c_str(), kv.second.versionCode,
395                     kv.first.first);
396         }
397     }
398 }
399 
OnConfigUpdated(const ConfigKey & key)400 void UidMap::OnConfigUpdated(const ConfigKey& key) {
401     mLastUpdatePerConfigKey[key] = -1;
402 }
403 
OnConfigRemoved(const ConfigKey & key)404 void UidMap::OnConfigRemoved(const ConfigKey& key) {
405     mLastUpdatePerConfigKey.erase(key);
406 }
407 
getAppUid(const string & package) const408 set<int32_t> UidMap::getAppUid(const string& package) const {
409     lock_guard<mutex> lock(mMutex);
410 
411     set<int32_t> results;
412     for (const auto& kv : mMap) {
413         if (kv.first.second == package && !kv.second.deleted) {
414             results.insert(kv.first.first);
415         }
416     }
417     return results;
418 }
419 
420 // Note not all the following AIDs are used as uids. Some are used only for gids.
421 // It's ok to leave them in the map, but we won't ever see them in the log's uid field.
422 // App's uid starts from 10000, and will not overlap with the following AIDs.
423 const std::map<string, uint32_t> UidMap::sAidToUidMapping = {{"AID_ROOT", 0},
424                                                              {"AID_SYSTEM", 1000},
425                                                              {"AID_RADIO", 1001},
426                                                              {"AID_BLUETOOTH", 1002},
427                                                              {"AID_GRAPHICS", 1003},
428                                                              {"AID_INPUT", 1004},
429                                                              {"AID_AUDIO", 1005},
430                                                              {"AID_CAMERA", 1006},
431                                                              {"AID_LOG", 1007},
432                                                              {"AID_COMPASS", 1008},
433                                                              {"AID_MOUNT", 1009},
434                                                              {"AID_WIFI", 1010},
435                                                              {"AID_ADB", 1011},
436                                                              {"AID_INSTALL", 1012},
437                                                              {"AID_MEDIA", 1013},
438                                                              {"AID_DHCP", 1014},
439                                                              {"AID_SDCARD_RW", 1015},
440                                                              {"AID_VPN", 1016},
441                                                              {"AID_KEYSTORE", 1017},
442                                                              {"AID_USB", 1018},
443                                                              {"AID_DRM", 1019},
444                                                              {"AID_MDNSR", 1020},
445                                                              {"AID_GPS", 1021},
446                                                              // {"AID_UNUSED1", 1022},
447                                                              {"AID_MEDIA_RW", 1023},
448                                                              {"AID_MTP", 1024},
449                                                              // {"AID_UNUSED2", 1025},
450                                                              {"AID_DRMRPC", 1026},
451                                                              {"AID_NFC", 1027},
452                                                              {"AID_SDCARD_R", 1028},
453                                                              {"AID_CLAT", 1029},
454                                                              {"AID_LOOP_RADIO", 1030},
455                                                              {"AID_MEDIA_DRM", 1031},
456                                                              {"AID_PACKAGE_INFO", 1032},
457                                                              {"AID_SDCARD_PICS", 1033},
458                                                              {"AID_SDCARD_AV", 1034},
459                                                              {"AID_SDCARD_ALL", 1035},
460                                                              {"AID_LOGD", 1036},
461                                                              {"AID_SHARED_RELRO", 1037},
462                                                              {"AID_DBUS", 1038},
463                                                              {"AID_TLSDATE", 1039},
464                                                              {"AID_MEDIA_EX", 1040},
465                                                              {"AID_AUDIOSERVER", 1041},
466                                                              {"AID_METRICS_COLL", 1042},
467                                                              {"AID_METRICSD", 1043},
468                                                              {"AID_WEBSERV", 1044},
469                                                              {"AID_DEBUGGERD", 1045},
470                                                              {"AID_MEDIA_CODEC", 1046},
471                                                              {"AID_CAMERASERVER", 1047},
472                                                              {"AID_FIREWALL", 1048},
473                                                              {"AID_TRUNKS", 1049},
474                                                              {"AID_NVRAM", 1050},
475                                                              {"AID_DNS", 1051},
476                                                              {"AID_DNS_TETHER", 1052},
477                                                              {"AID_WEBVIEW_ZYGOTE", 1053},
478                                                              {"AID_VEHICLE_NETWORK", 1054},
479                                                              {"AID_MEDIA_AUDIO", 1055},
480                                                              {"AID_MEDIA_VIDEO", 1056},
481                                                              {"AID_MEDIA_IMAGE", 1057},
482                                                              {"AID_TOMBSTONED", 1058},
483                                                              {"AID_MEDIA_OBB", 1059},
484                                                              {"AID_ESE", 1060},
485                                                              {"AID_OTA_UPDATE", 1061},
486                                                              {"AID_AUTOMOTIVE_EVS", 1062},
487                                                              {"AID_LOWPAN", 1063},
488                                                              {"AID_HSM", 1064},
489                                                              {"AID_RESERVED_DISK", 1065},
490                                                              {"AID_STATSD", 1066},
491                                                              {"AID_INCIDENTD", 1067},
492                                                              {"AID_SHELL", 2000},
493                                                              {"AID_CACHE", 2001},
494                                                              {"AID_DIAG", 2002}};
495 
496 }  // namespace statsd
497 }  // namespace os
498 }  // namespace android
499