Apply package visibility to cached ServiceRecord

Once the service resolve in retrieveServiceLocked is done, ActiveService
would store the ServiceRecord in a ServiceMap to save additional query
next time. However, the package visibility check isn't applied when the
ServiceRecord is retrieved from the ServiceMap. Hence, apps may bypass
the package visibility check and bind the target service successfully.

Bug: 177790677
Test: atest AppsFilterTest
Test: atest AppEnumerationTests
Change-Id: If362627fc6b02120a30ed10080d0d61b3ddbb98b
This commit is contained in:
Jackal Guo
2021-01-20 15:33:26 +08:00
parent 551929ac9a
commit 75e03a9596

View File

@@ -2815,12 +2815,24 @@ public final class ActiveServices {
r = smap.mServicesByIntent.get(filter);
if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by intent: " + r);
}
if (r != null && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
&& !callingPackage.equals(r.packageName)) {
// If an external service is running within its own package, other packages
// should not bind to that instance.
r = null;
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Whoops, can't use existing external service");
if (r != null) {
// Compared to resolveService below, the ServiceRecord here is retrieved from
// ServiceMap so the package visibility doesn't apply to it. We need to filter it.
if (mAm.getPackageManagerInternal().filterAppAccess(r.packageName, callingUid,
userId)) {
Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId
+ ": not found");
return null;
}
if ((r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
&& !callingPackage.equals(r.packageName)) {
// If an external service is running within its own package, other packages
// should not bind to that instance.
r = null;
if (DEBUG_SERVICE) {
Slog.v(TAG_SERVICE, "Whoops, can't use existing external service");
}
}
}
if (r == null) {
try {