blob: 36fc1202006f5b8443218cfcd6062cfc4a1c5a41 [file] [log] [blame]
Todd Kennedy0eb97382017-10-03 16:57:22 -07001/*
2 * Copyright (C) 2017 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
17package com.android.server.pm.permission;
18
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Todd Kennedy3bc94722017-10-10 09:55:53 -070021import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070022import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
23import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
24import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
25import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
26import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
27import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedy0eb97382017-10-03 16:57:22 -070028
29import android.Manifest;
30import android.annotation.NonNull;
31import android.annotation.Nullable;
Todd Kennedy0eb97382017-10-03 16:57:22 -070032import android.content.Context;
33import android.content.pm.PackageManager;
34import android.content.pm.PackageManagerInternal;
35import android.content.pm.PackageParser;
Todd Kennedy460f28c2017-10-06 13:46:22 -070036import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070037import android.content.pm.PermissionInfo;
38import android.content.pm.PackageParser.Package;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070039import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070040import android.os.Binder;
41import android.os.Build;
42import android.os.Handler;
43import android.os.HandlerThread;
44import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070045import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070046import android.os.UserHandle;
47import android.os.UserManager;
48import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070049import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070050import android.os.storage.StorageManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070051import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070052import android.util.ArrayMap;
53import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070054import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070055import android.util.Log;
56import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070057import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070058
Todd Kennedyc29b11a2017-10-23 15:55:59 -070059import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070060import com.android.internal.logging.MetricsLogger;
61import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070062import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070063import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070064import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemConfig;
67import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070068import com.android.server.pm.PackageManagerServiceUtils;
69import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070070import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070071import com.android.server.pm.UserManagerService;
Todd Kennedy0eb97382017-10-03 16:57:22 -070072import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
73import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
74import com.android.server.pm.permission.PermissionsState.PermissionState;
75
76import libcore.util.EmptyArray;
77
78import java.util.ArrayList;
79import java.util.Arrays;
80import java.util.Collection;
81import java.util.Iterator;
82import java.util.List;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070083import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -070084import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -070085
86/**
87 * Manages all permissions and handles permissions related tasks.
88 */
89public class PermissionManagerService {
90 private static final String TAG = "PackageManager";
91
Todd Kennedyc29b11a2017-10-23 15:55:59 -070092 /** Permission grant: not grant the permission. */
93 private static final int GRANT_DENIED = 1;
94 /** Permission grant: grant the permission as an install permission. */
95 private static final int GRANT_INSTALL = 2;
96 /** Permission grant: grant the permission as a runtime one. */
97 private static final int GRANT_RUNTIME = 3;
98 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
99 private static final int GRANT_UPGRADE = 4;
100
101 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
102 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
103 /** Empty array to avoid allocations */
104 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700105
106 /** Lock to protect internal data access */
107 private final Object mLock;
108
109 /** Internal connection to the package manager */
110 private final PackageManagerInternal mPackageManagerInt;
111
112 /** Internal connection to the user manager */
113 private final UserManagerInternal mUserManagerInt;
114
115 /** Default permission policy to provide proper behaviour out-of-the-box */
116 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
117
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700118 /**
119 * Built-in permissions. Read from system configuration files. Mapping is from
120 * UID to permission name.
121 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700122 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700123
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700124 /** Built-in group IDs given to all packages. Read from system configuration files. */
125 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700126
127 private final HandlerThread mHandlerThread;
128 private final Handler mHandler;
129 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700130 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700131
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700132 /** Internal storage for permissions and related settings */
133 @GuardedBy("mLock")
134 private final PermissionSettings mSettings;
135
136 @GuardedBy("mLock")
137 private ArraySet<String> mPrivappPermissionsViolations;
138
139 @GuardedBy("mLock")
140 private boolean mSystemReady;
141
Todd Kennedy0eb97382017-10-03 16:57:22 -0700142 PermissionManagerService(Context context,
143 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
144 @NonNull Object externalLock) {
145 mContext = context;
146 mLock = externalLock;
147 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
148 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
149 mSettings = new PermissionSettings(context, mLock);
150
151 mHandlerThread = new ServiceThread(TAG,
152 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
153 mHandlerThread.start();
154 mHandler = new Handler(mHandlerThread.getLooper());
155 Watchdog.getInstance().addThread(mHandler);
156
157 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
158 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700159 SystemConfig systemConfig = SystemConfig.getInstance();
160 mSystemPermissions = systemConfig.getSystemPermissions();
161 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700162
163 // propagate permission configuration
164 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
165 SystemConfig.getInstance().getPermissions();
166 synchronized (mLock) {
167 for (int i=0; i<permConfig.size(); i++) {
168 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
169 BasePermission bp = mSettings.getPermissionLocked(perm.name);
170 if (bp == null) {
171 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
172 mSettings.putPermissionLocked(perm.name, bp);
173 }
174 if (perm.gids != null) {
175 bp.setGids(perm.gids, perm.perUser);
176 }
177 }
178 }
179
180 LocalServices.addService(
181 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
182 }
183
184 /**
185 * Creates and returns an initialized, internal service for use by other components.
186 * <p>
187 * The object returned is identical to the one returned by the LocalServices class using:
188 * {@code LocalServices.getService(PermissionManagerInternal.class);}
189 * <p>
190 * NOTE: The external lock is temporary and should be removed. This needs to be a
191 * lock created by the permission manager itself.
192 */
193 public static PermissionManagerInternal create(Context context,
194 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
195 @NonNull Object externalLock) {
196 final PermissionManagerInternal permMgrInt =
197 LocalServices.getService(PermissionManagerInternal.class);
198 if (permMgrInt != null) {
199 return permMgrInt;
200 }
201 new PermissionManagerService(context, defaultGrantCallback, externalLock);
202 return LocalServices.getService(PermissionManagerInternal.class);
203 }
204
205 @Nullable BasePermission getPermission(String permName) {
206 synchronized (mLock) {
207 return mSettings.getPermissionLocked(permName);
208 }
209 }
210
211 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
212 if (!mUserManagerInt.exists(userId)) {
213 return PackageManager.PERMISSION_DENIED;
214 }
215
Patrick Baumann97b9b532018-04-11 14:51:30 +0000216 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
217 if (pkg != null && pkg.mExtras != null) {
218 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700219 return PackageManager.PERMISSION_DENIED;
220 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000221 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700222 final boolean instantApp = ps.getInstantApp(userId);
223 final PermissionsState permissionsState = ps.getPermissionsState();
224 if (permissionsState.hasPermission(permName, userId)) {
225 if (instantApp) {
226 synchronized (mLock) {
227 BasePermission bp = mSettings.getPermissionLocked(permName);
228 if (bp != null && bp.isInstant()) {
229 return PackageManager.PERMISSION_GRANTED;
230 }
231 }
232 } else {
233 return PackageManager.PERMISSION_GRANTED;
234 }
235 }
236 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
237 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
238 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
239 return PackageManager.PERMISSION_GRANTED;
240 }
241 }
242
243 return PackageManager.PERMISSION_DENIED;
244 }
245
Todd Kennedy3c714492017-10-27 09:12:50 -0700246 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
247 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700248 final int callingUserId = UserHandle.getUserId(callingUid);
249 final boolean isCallerInstantApp =
250 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
251 final boolean isUidInstantApp =
252 mPackageManagerInt.getInstantAppPackageName(uid) != null;
253 final int userId = UserHandle.getUserId(uid);
254 if (!mUserManagerInt.exists(userId)) {
255 return PackageManager.PERMISSION_DENIED;
256 }
257
Todd Kennedy3c714492017-10-27 09:12:50 -0700258 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700259 if (pkg.mSharedUserId != null) {
260 if (isCallerInstantApp) {
261 return PackageManager.PERMISSION_DENIED;
262 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700263 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
264 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700265 }
266 final PermissionsState permissionsState =
267 ((PackageSetting) pkg.mExtras).getPermissionsState();
268 if (permissionsState.hasPermission(permName, userId)) {
269 if (isUidInstantApp) {
270 if (mSettings.isPermissionInstant(permName)) {
271 return PackageManager.PERMISSION_GRANTED;
272 }
273 } else {
274 return PackageManager.PERMISSION_GRANTED;
275 }
276 }
277 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
278 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
279 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
280 return PackageManager.PERMISSION_GRANTED;
281 }
282 } else {
283 ArraySet<String> perms = mSystemPermissions.get(uid);
284 if (perms != null) {
285 if (perms.contains(permName)) {
286 return PackageManager.PERMISSION_GRANTED;
287 }
288 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
289 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
290 return PackageManager.PERMISSION_GRANTED;
291 }
292 }
293 }
294 return PackageManager.PERMISSION_DENIED;
295 }
296
Todd Kennedy460f28c2017-10-06 13:46:22 -0700297 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
298 int callingUid) {
299 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
300 return null;
301 }
302 synchronized (mLock) {
303 return PackageParser.generatePermissionGroupInfo(
304 mSettings.mPermissionGroups.get(groupName), flags);
305 }
306 }
307
308 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
309 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
310 return null;
311 }
312 synchronized (mLock) {
313 final int N = mSettings.mPermissionGroups.size();
314 final ArrayList<PermissionGroupInfo> out
315 = new ArrayList<PermissionGroupInfo>(N);
316 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
317 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
318 }
319 return out;
320 }
321 }
322
323 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700324 int callingUid) {
325 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
326 return null;
327 }
328 // reader
329 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700330 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700331 if (bp == null) {
332 return null;
333 }
334 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
335 bp.getProtectionLevel(), packageName, callingUid);
336 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
337 }
338 }
339
340 private List<PermissionInfo> getPermissionInfoByGroup(
341 String groupName, int flags, int callingUid) {
342 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
343 return null;
344 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700345 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700346 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
347 return null;
348 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700349 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700350 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700351 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
352 if (pi != null) {
353 out.add(pi);
354 }
355 }
356 return out;
357 }
358 }
359
360 private int adjustPermissionProtectionFlagsLocked(
361 int protectionLevel, String packageName, int uid) {
362 // Signature permission flags area always reported
363 final int protectionLevelMasked = protectionLevel
364 & (PermissionInfo.PROTECTION_NORMAL
365 | PermissionInfo.PROTECTION_DANGEROUS
366 | PermissionInfo.PROTECTION_SIGNATURE);
367 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
368 return protectionLevel;
369 }
370 // System sees all flags.
371 final int appId = UserHandle.getAppId(uid);
372 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
373 || appId == Process.SHELL_UID) {
374 return protectionLevel;
375 }
376 // Normalize package name to handle renamed packages and static libs
377 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
378 if (pkg == null) {
379 return protectionLevel;
380 }
381 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
382 return protectionLevelMasked;
383 }
384 // Apps that target O see flags for all protection levels.
385 final PackageSetting ps = (PackageSetting) pkg.mExtras;
386 if (ps == null) {
387 return protectionLevel;
388 }
389 if (ps.getAppId() != appId) {
390 return protectionLevel;
391 }
392 return protectionLevel;
393 }
394
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700395 /**
396 * We might auto-grant permissions if any permission of the group is already granted. Hence if
397 * the group of a granted permission changes we need to revoke it to avoid having permissions of
398 * the new group auto-granted.
399 *
400 * @param newPackage The new package that was installed
401 * @param oldPackage The old package that was updated
402 * @param allPackageNames All package names
403 * @param permissionCallback Callback for permission changed
404 */
405 private void revokeRuntimePermissionsIfGroupChanged(
406 @NonNull PackageParser.Package newPackage,
407 @NonNull PackageParser.Package oldPackage,
408 @NonNull ArrayList<String> allPackageNames,
409 @NonNull PermissionCallback permissionCallback) {
410 final int numOldPackagePermissions = oldPackage.permissions.size();
411 final ArrayMap<String, String> oldPermissionNameToGroupName
412 = new ArrayMap<>(numOldPackagePermissions);
413
414 for (int i = 0; i < numOldPackagePermissions; i++) {
415 final PackageParser.Permission permission = oldPackage.permissions.get(i);
416
417 if (permission.group != null) {
418 oldPermissionNameToGroupName.put(permission.info.name,
419 permission.group.info.name);
420 }
421 }
422
423 final int numNewPackagePermissions = newPackage.permissions.size();
424 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
425 newPermissionNum++) {
426 final PackageParser.Permission newPermission =
427 newPackage.permissions.get(newPermissionNum);
428 final int newProtection = newPermission.info.getProtection();
429
430 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
431 final String permissionName = newPermission.info.name;
432 final String newPermissionGroupName =
433 newPermission.group == null ? null : newPermission.group.info.name;
434 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
435 permissionName);
436
437 if (newPermissionGroupName != null
438 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
439 final int[] userIds = mUserManagerInt.getUserIds();
440 final int numUserIds = userIds.length;
441 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
442 final int userId = userIds[userIdNum];
443
444 final int numPackages = allPackageNames.size();
445 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
446 final String packageName = allPackageNames.get(packageNum);
447
448 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
449 userId) == PackageManager.PERMISSION_GRANTED) {
450 EventLog.writeEvent(0x534e4554, "72710897",
451 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900452 "Revoking permission " + permissionName +
453 " from package " + packageName +
454 " as the group changed from " + oldPermissionGroupName +
455 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700456
457 try {
458 revokeRuntimePermission(permissionName, packageName, false,
459 Process.SYSTEM_UID, userId, permissionCallback);
460 } catch (IllegalArgumentException e) {
461 Slog.e(TAG, "Could not revoke " + permissionName + " from "
462 + packageName, e);
463 }
464 }
465 }
466 }
467 }
468 }
469 }
470 }
471
Todd Kennedyc8423932017-10-05 08:58:36 -0700472 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
473 final int N = pkg.permissions.size();
474 for (int i=0; i<N; i++) {
475 PackageParser.Permission p = pkg.permissions.get(i);
476
477 // Assume by default that we did not install this permission into the system.
478 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
479
Todd Kennedyc8423932017-10-05 08:58:36 -0700480 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700481 // Now that permission groups have a special meaning, we ignore permission
482 // groups for legacy apps to prevent unexpected behavior. In particular,
483 // permissions for one app being granted to someone just because they happen
484 // to be in a group defined by another app (before this had no implications).
485 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
486 p.group = mSettings.mPermissionGroups.get(p.info.group);
487 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700488 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700489 && p.info.group != null && p.group == null) {
490 Slog.i(TAG, "Permission " + p.info.name + " from package "
491 + p.info.packageName + " in an unknown group " + p.info.group);
492 }
493 }
494
Todd Kennedyc8423932017-10-05 08:58:36 -0700495 if (p.tree) {
496 final BasePermission bp = BasePermission.createOrUpdate(
497 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
498 mSettings.getAllPermissionTreesLocked(), chatty);
499 mSettings.putPermissionTreeLocked(p.info.name, bp);
500 } else {
501 final BasePermission bp = BasePermission.createOrUpdate(
502 mSettings.getPermissionLocked(p.info.name),
503 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
504 mSettings.putPermissionLocked(p.info.name, bp);
505 }
506 }
507 }
508 }
509
Todd Kennedy460f28c2017-10-06 13:46:22 -0700510 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
511 final int N = pkg.permissionGroups.size();
512 StringBuilder r = null;
513 for (int i=0; i<N; i++) {
514 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
515 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
516 final String curPackageName = (cur == null) ? null : cur.info.packageName;
517 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
518 if (cur == null || isPackageUpdate) {
519 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700520 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700521 if (r == null) {
522 r = new StringBuilder(256);
523 } else {
524 r.append(' ');
525 }
526 if (isPackageUpdate) {
527 r.append("UPD:");
528 }
529 r.append(pg.info.name);
530 }
531 } else {
532 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
533 + pg.info.packageName + " ignored: original from "
534 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700535 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700536 if (r == null) {
537 r = new StringBuilder(256);
538 } else {
539 r.append(' ');
540 }
541 r.append("DUP:");
542 r.append(pg.info.name);
543 }
544 }
545 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700546 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700547 Log.d(TAG, " Permission Groups: " + r);
548 }
549
550 }
551
Todd Kennedyc8423932017-10-05 08:58:36 -0700552 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
553 synchronized (mLock) {
554 int N = pkg.permissions.size();
555 StringBuilder r = null;
556 for (int i=0; i<N; i++) {
557 PackageParser.Permission p = pkg.permissions.get(i);
558 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
559 if (bp == null) {
560 bp = mSettings.mPermissionTrees.get(p.info.name);
561 }
562 if (bp != null && bp.isPermission(p)) {
563 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700564 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700565 if (r == null) {
566 r = new StringBuilder(256);
567 } else {
568 r.append(' ');
569 }
570 r.append(p.info.name);
571 }
572 }
573 if (p.isAppOp()) {
574 ArraySet<String> appOpPkgs =
575 mSettings.mAppOpPermissionPackages.get(p.info.name);
576 if (appOpPkgs != null) {
577 appOpPkgs.remove(pkg.packageName);
578 }
579 }
580 }
581 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700582 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700583 }
584
585 N = pkg.requestedPermissions.size();
586 r = null;
587 for (int i=0; i<N; i++) {
588 String perm = pkg.requestedPermissions.get(i);
589 if (mSettings.isPermissionAppOp(perm)) {
590 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
591 if (appOpPkgs != null) {
592 appOpPkgs.remove(pkg.packageName);
593 if (appOpPkgs.isEmpty()) {
594 mSettings.mAppOpPermissionPackages.remove(perm);
595 }
596 }
597 }
598 }
599 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700600 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700601 }
602 }
603 }
604
605 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700606 PermissionInfo info, int callingUid, PermissionCallback callback) {
607 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
608 throw new SecurityException("Instant apps can't add permissions");
609 }
610 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
611 throw new SecurityException("Label must be specified in permission");
612 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700613 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700614 final boolean added;
615 final boolean changed;
616 synchronized (mLock) {
617 BasePermission bp = mSettings.getPermissionLocked(info.name);
618 added = bp == null;
619 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
620 if (added) {
621 enforcePermissionCapLocked(info, tree);
622 bp = new BasePermission(info.name, tree.getSourcePackageName(),
623 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700624 } else if (!bp.isDynamic()) {
625 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700626 + info.name);
627 }
628 changed = bp.addToTree(fixedLevel, info, tree);
629 if (added) {
630 mSettings.putPermissionLocked(info.name, bp);
631 }
632 }
633 if (changed && callback != null) {
634 callback.onPermissionChanged();
635 }
636 return added;
637 }
638
Todd Kennedyc8423932017-10-05 08:58:36 -0700639 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700640 String permName, int callingUid, PermissionCallback callback) {
641 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
642 throw new SecurityException("Instant applications don't have access to this method");
643 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700644 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700645 synchronized (mLock) {
646 final BasePermission bp = mSettings.getPermissionLocked(permName);
647 if (bp == null) {
648 return;
649 }
650 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600651 // TODO: switch this back to SecurityException
652 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700653 + permName);
654 }
655 mSettings.removePermissionLocked(permName);
656 if (callback != null) {
657 callback.onPermissionRemoved();
658 }
659 }
660 }
661
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700662 private void grantPermissions(PackageParser.Package pkg, boolean replace,
663 String packageOfInterest, PermissionCallback callback) {
664 // IMPORTANT: There are two types of permissions: install and runtime.
665 // Install time permissions are granted when the app is installed to
666 // all device users and users added in the future. Runtime permissions
667 // are granted at runtime explicitly to specific users. Normal and signature
668 // protected permissions are install time permissions. Dangerous permissions
669 // are install permissions if the app's target SDK is Lollipop MR1 or older,
670 // otherwise they are runtime permissions. This function does not manage
671 // runtime permissions except for the case an app targeting Lollipop MR1
672 // being upgraded to target a newer SDK, in which case dangerous permissions
673 // are transformed from install time to runtime ones.
674
675 final PackageSetting ps = (PackageSetting) pkg.mExtras;
676 if (ps == null) {
677 return;
678 }
679 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
680
681 final PermissionsState permissionsState = ps.getPermissionsState();
682 PermissionsState origPermissions = permissionsState;
683
684 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
685
686 boolean runtimePermissionsRevoked = false;
687 int[] updatedUserIds = EMPTY_INT_ARRAY;
688
689 boolean changedInstallPermission = false;
690
691 if (replace) {
692 ps.setInstallPermissionsFixed(false);
693 if (!ps.isSharedUser()) {
694 origPermissions = new PermissionsState(permissionsState);
695 permissionsState.reset();
696 } else {
697 // We need to know only about runtime permission changes since the
698 // calling code always writes the install permissions state but
699 // the runtime ones are written only if changed. The only cases of
700 // changed runtime permissions here are promotion of an install to
701 // runtime and revocation of a runtime from a shared user.
702 synchronized (mLock) {
703 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
704 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
705 if (!ArrayUtils.isEmpty(updatedUserIds)) {
706 runtimePermissionsRevoked = true;
707 }
708 }
709 }
710 }
711
712 permissionsState.setGlobalGids(mGlobalGids);
713
714 synchronized (mLock) {
715 final int N = pkg.requestedPermissions.size();
716 for (int i = 0; i < N; i++) {
717 final String permName = pkg.requestedPermissions.get(i);
718 final BasePermission bp = mSettings.getPermissionLocked(permName);
719 final boolean appSupportsRuntimePermissions =
720 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
721
722 if (DEBUG_INSTALL) {
723 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
724 }
725
726 if (bp == null || bp.getSourcePackageSetting() == null) {
727 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
728 if (DEBUG_PERMISSIONS) {
729 Slog.i(TAG, "Unknown permission " + permName
730 + " in package " + pkg.packageName);
731 }
732 }
733 continue;
734 }
735
736 // Limit ephemeral apps to ephemeral allowed permissions.
737 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
738 if (DEBUG_PERMISSIONS) {
739 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
740 + " for package " + pkg.packageName);
741 }
742 continue;
743 }
744
745 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
746 if (DEBUG_PERMISSIONS) {
747 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
748 + " for package " + pkg.packageName);
749 }
750 continue;
751 }
752
753 final String perm = bp.getName();
754 boolean allowedSig = false;
755 int grant = GRANT_DENIED;
756
757 // Keep track of app op permissions.
758 if (bp.isAppOp()) {
759 mSettings.addAppOpPackage(perm, pkg.packageName);
760 }
761
762 if (bp.isNormal()) {
763 // For all apps normal permissions are install time ones.
764 grant = GRANT_INSTALL;
765 } else if (bp.isRuntime()) {
766 // If a permission review is required for legacy apps we represent
767 // their permissions as always granted runtime ones since we need
768 // to keep the review required permission flag per user while an
769 // install permission's state is shared across all users.
770 if (!appSupportsRuntimePermissions && !mSettings.mPermissionReviewRequired) {
771 // For legacy apps dangerous permissions are install time ones.
772 grant = GRANT_INSTALL;
773 } else if (origPermissions.hasInstallPermission(bp.getName())) {
774 // For legacy apps that became modern, install becomes runtime.
775 grant = GRANT_UPGRADE;
776 } else if (isLegacySystemApp) {
777 // For legacy system apps, install becomes runtime.
778 // We cannot check hasInstallPermission() for system apps since those
779 // permissions were granted implicitly and not persisted pre-M.
780 grant = GRANT_UPGRADE;
781 } else {
782 // For modern apps keep runtime permissions unchanged.
783 grant = GRANT_RUNTIME;
784 }
785 } else if (bp.isSignature()) {
786 // For all apps signature permissions are install time ones.
787 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
788 if (allowedSig) {
789 grant = GRANT_INSTALL;
790 }
791 }
792
793 if (DEBUG_PERMISSIONS) {
794 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
795 }
796
797 if (grant != GRANT_DENIED) {
798 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
799 // If this is an existing, non-system package, then
800 // we can't add any new permissions to it.
801 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
802 // Except... if this is a permission that was added
803 // to the platform (note: need to only do this when
804 // updating the platform).
805 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
806 grant = GRANT_DENIED;
807 }
808 }
809 }
810
811 switch (grant) {
812 case GRANT_INSTALL: {
813 // Revoke this as runtime permission to handle the case of
814 // a runtime permission being downgraded to an install one.
815 // Also in permission review mode we keep dangerous permissions
816 // for legacy apps
817 for (int userId : UserManagerService.getInstance().getUserIds()) {
818 if (origPermissions.getRuntimePermissionState(
819 perm, userId) != null) {
820 // Revoke the runtime permission and clear the flags.
821 origPermissions.revokeRuntimePermission(bp, userId);
822 origPermissions.updatePermissionFlags(bp, userId,
823 PackageManager.MASK_PERMISSION_FLAGS, 0);
824 // If we revoked a permission permission, we have to write.
825 updatedUserIds = ArrayUtils.appendInt(
826 updatedUserIds, userId);
827 }
828 }
829 // Grant an install permission.
830 if (permissionsState.grantInstallPermission(bp) !=
831 PermissionsState.PERMISSION_OPERATION_FAILURE) {
832 changedInstallPermission = true;
833 }
834 } break;
835
836 case GRANT_RUNTIME: {
837 // Grant previously granted runtime permissions.
838 for (int userId : UserManagerService.getInstance().getUserIds()) {
839 final PermissionState permissionState = origPermissions
840 .getRuntimePermissionState(perm, userId);
841 int flags = permissionState != null
842 ? permissionState.getFlags() : 0;
843 if (origPermissions.hasRuntimePermission(perm, userId)) {
844 // Don't propagate the permission in a permission review
845 // mode if the former was revoked, i.e. marked to not
846 // propagate on upgrade. Note that in a permission review
847 // mode install permissions are represented as constantly
848 // granted runtime ones since we need to keep a per user
849 // state associated with the permission. Also the revoke
850 // on upgrade flag is no longer applicable and is reset.
851 final boolean revokeOnUpgrade = (flags & PackageManager
852 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
853 if (revokeOnUpgrade) {
854 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
855 // Since we changed the flags, we have to write.
856 updatedUserIds = ArrayUtils.appendInt(
857 updatedUserIds, userId);
858 }
859 if (!mSettings.mPermissionReviewRequired || !revokeOnUpgrade) {
860 if (permissionsState.grantRuntimePermission(bp, userId) ==
861 PermissionsState.PERMISSION_OPERATION_FAILURE) {
862 // If we cannot put the permission as it was,
863 // we have to write.
864 updatedUserIds = ArrayUtils.appendInt(
865 updatedUserIds, userId);
866 }
867 }
868
869 // If the app supports runtime permissions no need for a review.
870 if (mSettings.mPermissionReviewRequired
871 && appSupportsRuntimePermissions
872 && (flags & PackageManager
873 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
874 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
875 // Since we changed the flags, we have to write.
876 updatedUserIds = ArrayUtils.appendInt(
877 updatedUserIds, userId);
878 }
879 } else if (mSettings.mPermissionReviewRequired
880 && !appSupportsRuntimePermissions) {
881 // For legacy apps that need a permission review, every new
882 // runtime permission is granted but it is pending a review.
883 // We also need to review only platform defined runtime
884 // permissions as these are the only ones the platform knows
885 // how to disable the API to simulate revocation as legacy
886 // apps don't expect to run with revoked permissions.
887 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
888 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
889 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
890 // We changed the flags, hence have to write.
891 updatedUserIds = ArrayUtils.appendInt(
892 updatedUserIds, userId);
893 }
894 }
895 if (permissionsState.grantRuntimePermission(bp, userId)
896 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
897 // We changed the permission, hence have to write.
898 updatedUserIds = ArrayUtils.appendInt(
899 updatedUserIds, userId);
900 }
901 }
902 // Propagate the permission flags.
903 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
904 }
905 } break;
906
907 case GRANT_UPGRADE: {
908 // Grant runtime permissions for a previously held install permission.
909 final PermissionState permissionState = origPermissions
910 .getInstallPermissionState(perm);
911 final int flags =
912 (permissionState != null) ? permissionState.getFlags() : 0;
913
914 if (origPermissions.revokeInstallPermission(bp)
915 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
916 // We will be transferring the permission flags, so clear them.
917 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
918 PackageManager.MASK_PERMISSION_FLAGS, 0);
919 changedInstallPermission = true;
920 }
921
922 // If the permission is not to be promoted to runtime we ignore it and
923 // also its other flags as they are not applicable to install permissions.
924 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
925 for (int userId : currentUserIds) {
926 if (permissionsState.grantRuntimePermission(bp, userId) !=
927 PermissionsState.PERMISSION_OPERATION_FAILURE) {
928 // Transfer the permission flags.
929 permissionsState.updatePermissionFlags(bp, userId,
930 flags, flags);
931 // If we granted the permission, we have to write.
932 updatedUserIds = ArrayUtils.appendInt(
933 updatedUserIds, userId);
934 }
935 }
936 }
937 } break;
938
939 default: {
940 if (packageOfInterest == null
941 || packageOfInterest.equals(pkg.packageName)) {
942 if (DEBUG_PERMISSIONS) {
943 Slog.i(TAG, "Not granting permission " + perm
944 + " to package " + pkg.packageName
945 + " because it was previously installed without");
946 }
947 }
948 } break;
949 }
950 } else {
951 if (permissionsState.revokeInstallPermission(bp) !=
952 PermissionsState.PERMISSION_OPERATION_FAILURE) {
953 // Also drop the permission flags.
954 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
955 PackageManager.MASK_PERMISSION_FLAGS, 0);
956 changedInstallPermission = true;
957 Slog.i(TAG, "Un-granting permission " + perm
958 + " from package " + pkg.packageName
959 + " (protectionLevel=" + bp.getProtectionLevel()
960 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
961 + ")");
962 } else if (bp.isAppOp()) {
963 // Don't print warning for app op permissions, since it is fine for them
964 // not to be granted, there is a UI for the user to decide.
965 if (DEBUG_PERMISSIONS
966 && (packageOfInterest == null
967 || packageOfInterest.equals(pkg.packageName))) {
968 Slog.i(TAG, "Not granting permission " + perm
969 + " to package " + pkg.packageName
970 + " (protectionLevel=" + bp.getProtectionLevel()
971 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
972 + ")");
973 }
974 }
975 }
976 }
977
978 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
979 !ps.isSystem() || ps.isUpdatedSystem()) {
980 // This is the first that we have heard about this package, so the
981 // permissions we have now selected are fixed until explicitly
982 // changed.
983 ps.setInstallPermissionsFixed(true);
984 }
985 }
986
987 // Persist the runtime permissions state for users with changes. If permissions
988 // were revoked because no app in the shared user declares them we have to
989 // write synchronously to avoid losing runtime permissions state.
990 if (callback != null) {
991 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
992 }
993 }
994
995 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
996 boolean allowed = false;
997 final int NP = PackageParser.NEW_PERMISSIONS.length;
998 for (int ip=0; ip<NP; ip++) {
999 final PackageParser.NewPermissionInfo npi
1000 = PackageParser.NEW_PERMISSIONS[ip];
1001 if (npi.name.equals(perm)
1002 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1003 allowed = true;
1004 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1005 + pkg.packageName);
1006 break;
1007 }
1008 }
1009 return allowed;
1010 }
1011
1012 /**
1013 * Determines whether a package is whitelisted for a particular privapp permission.
1014 *
1015 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1016 *
1017 * <p>This handles parent/child apps.
1018 */
1019 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001020 ArraySet<String> wlPermissions = null;
1021 if (pkg.isVendor()) {
1022 wlPermissions =
1023 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1024 } else if (pkg.isProduct()) {
1025 wlPermissions =
1026 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
1027 } else {
1028 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1029 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001030 // Let's check if this package is whitelisted...
1031 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1032 // If it's not, we'll also tail-recurse to the parent.
1033 return whitelisted ||
1034 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1035 }
1036
1037 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1038 BasePermission bp, PermissionsState origPermissions) {
1039 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001040 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1041 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001042 boolean privappPermissionsDisable =
1043 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1044 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1045 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1046 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1047 && !platformPackage && platformPermission) {
1048 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001049 // Only report violations for apps on system image
1050 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1051 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001052 ArraySet<String> deniedPermissions = null;
1053 if (pkg.isVendor()) {
1054 deniedPermissions = SystemConfig.getInstance()
1055 .getVendorPrivAppDenyPermissions(pkg.packageName);
1056 } else if (pkg.isProduct()) {
1057 deniedPermissions = SystemConfig.getInstance()
1058 .getProductPrivAppDenyPermissions(pkg.packageName);
1059 } else {
1060 deniedPermissions = SystemConfig.getInstance()
1061 .getPrivAppDenyPermissions(pkg.packageName);
1062 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001063 final boolean permissionViolation =
1064 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001065 if (permissionViolation) {
1066 Slog.w(TAG, "Privileged permission " + perm + " for package "
1067 + pkg.packageName + " - not in privapp-permissions whitelist");
1068
1069 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1070 if (mPrivappPermissionsViolations == null) {
1071 mPrivappPermissionsViolations = new ArraySet<>();
1072 }
1073 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001074 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001075 } else {
1076 return false;
1077 }
1078 }
1079 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1080 return false;
1081 }
1082 }
1083 }
1084 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1085 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1086 final PackageParser.Package systemPackage =
1087 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001088
1089 // check if the package is allow to use this signature permission. A package is allowed to
1090 // use a signature permission if:
1091 // - it has the same set of signing certificates as the source package
1092 // - or its signing certificate was rotated from the source package's certificate
1093 // - or its signing certificate is a previous signing certificate of the defining
1094 // package, and the defining package still trusts the old certificate for permissions
1095 // - or it shares the above relationships with the system package
1096 boolean allowed =
1097 pkg.mSigningDetails.hasAncestorOrSelf(
1098 bp.getSourcePackageSetting().getSigningDetails())
1099 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1100 pkg.mSigningDetails,
1101 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1102 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1103 || systemPackage.mSigningDetails.checkCapability(
1104 pkg.mSigningDetails,
1105 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001106 if (!allowed && (privilegedPermission || oemPermission)) {
1107 if (pkg.isSystem()) {
1108 // For updated system applications, a privileged/oem permission
1109 // is granted only if it had been defined by the original application.
1110 if (pkg.isUpdatedSystemApp()) {
1111 final PackageParser.Package disabledPkg =
1112 mPackageManagerInt.getDisabledPackage(pkg.packageName);
1113 final PackageSetting disabledPs =
1114 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1115 if (disabledPs != null
1116 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1117 // If the original was granted this permission, we take
1118 // that grant decision as read and propagate it to the
1119 // update.
1120 if ((privilegedPermission && disabledPs.isPrivileged())
1121 || (oemPermission && disabledPs.isOem()
1122 && canGrantOemPermission(disabledPs, perm))) {
1123 allowed = true;
1124 }
1125 } else {
1126 // The system apk may have been updated with an older
1127 // version of the one on the data partition, but which
1128 // granted a new system permission that it didn't have
1129 // before. In this case we do want to allow the app to
1130 // now get the new permission if the ancestral apk is
1131 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001132 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001133 && isPackageRequestingPermission(disabledPkg, perm)
1134 && ((privilegedPermission && disabledPs.isPrivileged())
1135 || (oemPermission && disabledPs.isOem()
1136 && canGrantOemPermission(disabledPs, perm)))) {
1137 allowed = true;
1138 }
1139 // Also if a privileged parent package on the system image or any of
1140 // its children requested a privileged/oem permission, the updated child
1141 // packages can also get the permission.
1142 if (pkg.parentPackage != null) {
1143 final PackageParser.Package disabledParentPkg = mPackageManagerInt
1144 .getDisabledPackage(pkg.parentPackage.packageName);
1145 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1146 ? (PackageSetting) disabledParentPkg.mExtras : null;
1147 if (disabledParentPkg != null
1148 && ((privilegedPermission && disabledParentPs.isPrivileged())
1149 || (oemPermission && disabledParentPs.isOem()))) {
1150 if (isPackageRequestingPermission(disabledParentPkg, perm)
1151 && canGrantOemPermission(disabledParentPs, perm)) {
1152 allowed = true;
1153 } else if (disabledParentPkg.childPackages != null) {
1154 for (PackageParser.Package disabledChildPkg
1155 : disabledParentPkg.childPackages) {
1156 final PackageSetting disabledChildPs =
1157 (disabledChildPkg != null)
1158 ? (PackageSetting) disabledChildPkg.mExtras
1159 : null;
1160 if (isPackageRequestingPermission(disabledChildPkg, perm)
1161 && canGrantOemPermission(
1162 disabledChildPs, perm)) {
1163 allowed = true;
1164 break;
1165 }
1166 }
1167 }
1168 }
1169 }
1170 }
1171 } else {
1172 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1173 allowed = (privilegedPermission && pkg.isPrivileged())
1174 || (oemPermission && pkg.isOem()
1175 && canGrantOemPermission(ps, perm));
1176 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001177 // In any case, don't grant a privileged permission to privileged vendor apps, if
1178 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1179 // flag.
1180 if (allowed && privilegedPermission &&
1181 !vendorPrivilegedPermission && pkg.isVendor()) {
1182 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1183 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1184 allowed = false;
1185 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001186 }
1187 }
1188 if (!allowed) {
1189 if (!allowed
1190 && bp.isPre23()
1191 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1192 // If this was a previously normal/dangerous permission that got moved
1193 // to a system permission as part of the runtime permission redesign, then
1194 // we still want to blindly grant it to old apps.
1195 allowed = true;
1196 }
1197 if (!allowed && bp.isInstaller()
1198 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1199 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))) {
1200 // If this permission is to be granted to the system installer and
1201 // this app is an installer, then it gets the permission.
1202 allowed = true;
1203 }
1204 if (!allowed && bp.isVerifier()
1205 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1206 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1207 // If this permission is to be granted to the system verifier and
1208 // this app is a verifier, then it gets the permission.
1209 allowed = true;
1210 }
1211 if (!allowed && bp.isPreInstalled()
1212 && pkg.isSystem()) {
1213 // Any pre-installed system app is allowed to get this permission.
1214 allowed = true;
1215 }
1216 if (!allowed && bp.isDevelopment()) {
1217 // For development permissions, a development permission
1218 // is granted only if it was already granted.
1219 allowed = origPermissions.hasInstallPermission(perm);
1220 }
1221 if (!allowed && bp.isSetup()
1222 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1223 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1224 // If this permission is to be granted to the system setup wizard and
1225 // this app is a setup wizard, then it gets the permission.
1226 allowed = true;
1227 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001228 if (!allowed && bp.isSystemTextClassifier()
1229 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1230 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1231 UserHandle.USER_SYSTEM))) {
1232 // Special permissions for the system default text classifier.
1233 allowed = true;
1234 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001235 }
1236 return allowed;
1237 }
1238
1239 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1240 if (!ps.isOem()) {
1241 return false;
1242 }
1243 // all oem permissions must explicitly be granted or denied
1244 final Boolean granted =
1245 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1246 if (granted == null) {
1247 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1248 + ps.name + " must be explicitly declared granted or not");
1249 }
1250 return Boolean.TRUE == granted;
1251 }
1252
1253 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
1254 if (!mSettings.mPermissionReviewRequired) {
1255 return false;
1256 }
1257
1258 // Permission review applies only to apps not supporting the new permission model.
1259 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1260 return false;
1261 }
1262
1263 // Legacy apps have the permission and get user consent on launch.
1264 if (pkg == null || pkg.mExtras == null) {
1265 return false;
1266 }
1267 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1268 final PermissionsState permissionsState = ps.getPermissionsState();
1269 return permissionsState.isPermissionReviewRequired(userId);
1270 }
1271
1272 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1273 final int permCount = pkg.requestedPermissions.size();
1274 for (int j = 0; j < permCount; j++) {
1275 String requestedPermission = pkg.requestedPermissions.get(j);
1276 if (permission.equals(requestedPermission)) {
1277 return true;
1278 }
1279 }
1280 return false;
1281 }
1282
Andreas Gampea36dc622018-02-05 17:19:22 -08001283 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001284 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1285 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1286 if (pkg.parentPackage == null) {
1287 return;
1288 }
1289 if (pkg.requestedPermissions == null) {
1290 return;
1291 }
1292 final PackageParser.Package disabledPkg =
1293 mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName);
1294 if (disabledPkg == null || disabledPkg.mExtras == null) {
1295 return;
1296 }
1297 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1298 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1299 return;
1300 }
1301 final int permCount = pkg.requestedPermissions.size();
1302 for (int i = 0; i < permCount; i++) {
1303 String permission = pkg.requestedPermissions.get(i);
1304 BasePermission bp = mSettings.getPermissionLocked(permission);
1305 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1306 continue;
1307 }
1308 for (int userId : mUserManagerInt.getUserIds()) {
1309 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1310 grantRuntimePermission(
1311 permission, pkg.packageName, false, callingUid, userId, callback);
1312 }
1313 }
1314 }
1315 }
1316
1317 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1318 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1319 for (int userId : userIds) {
1320 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1321 callback);
1322 }
1323 }
1324
1325 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1326 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1327 PackageSetting ps = (PackageSetting) pkg.mExtras;
1328 if (ps == null) {
1329 return;
1330 }
1331
1332 PermissionsState permissionsState = ps.getPermissionsState();
1333
1334 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1335 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1336
1337 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1338 >= Build.VERSION_CODES.M;
1339
1340 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1341
1342 for (String permission : pkg.requestedPermissions) {
1343 final BasePermission bp;
1344 synchronized (mLock) {
1345 bp = mSettings.getPermissionLocked(permission);
1346 }
1347 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1348 && (!instantApp || bp.isInstant())
1349 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1350 && (grantedPermissions == null
1351 || ArrayUtils.contains(grantedPermissions, permission))) {
1352 final int flags = permissionsState.getPermissionFlags(permission, userId);
1353 if (supportsRuntimePermissions) {
1354 // Installer cannot change immutable permissions.
1355 if ((flags & immutableFlags) == 0) {
1356 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1357 userId, callback);
1358 }
1359 } else if (mSettings.mPermissionReviewRequired) {
1360 // In permission review mode we clear the review flag when we
1361 // are asked to install the app with all permissions granted.
1362 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1363 updatePermissionFlags(permission, pkg.packageName,
1364 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1365 userId, callback);
1366 }
1367 }
1368 }
1369 }
1370 }
1371
1372 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1373 int callingUid, final int userId, PermissionCallback callback) {
1374 if (!mUserManagerInt.exists(userId)) {
1375 Log.e(TAG, "No such user:" + userId);
1376 return;
1377 }
1378
1379 mContext.enforceCallingOrSelfPermission(
1380 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1381 "grantRuntimePermission");
1382
1383 enforceCrossUserPermission(callingUid, userId,
1384 true /* requireFullPermission */, true /* checkShell */,
1385 "grantRuntimePermission");
1386
1387 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1388 if (pkg == null || pkg.mExtras == null) {
1389 throw new IllegalArgumentException("Unknown package: " + packageName);
1390 }
1391 final BasePermission bp;
1392 synchronized(mLock) {
1393 bp = mSettings.getPermissionLocked(permName);
1394 }
1395 if (bp == null) {
1396 throw new IllegalArgumentException("Unknown permission: " + permName);
1397 }
1398 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1399 throw new IllegalArgumentException("Unknown package: " + packageName);
1400 }
1401
1402 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1403
1404 // If a permission review is required for legacy apps we represent
1405 // their permissions as always granted runtime ones since we need
1406 // to keep the review required permission flag per user while an
1407 // install permission's state is shared across all users.
1408 if (mSettings.mPermissionReviewRequired
1409 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1410 && bp.isRuntime()) {
1411 return;
1412 }
1413
1414 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1415
1416 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1417 final PermissionsState permissionsState = ps.getPermissionsState();
1418
1419 final int flags = permissionsState.getPermissionFlags(permName, userId);
1420 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1421 throw new SecurityException("Cannot grant system fixed permission "
1422 + permName + " for package " + packageName);
1423 }
1424 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1425 throw new SecurityException("Cannot grant policy fixed permission "
1426 + permName + " for package " + packageName);
1427 }
1428
1429 if (bp.isDevelopment()) {
1430 // Development permissions must be handled specially, since they are not
1431 // normal runtime permissions. For now they apply to all users.
1432 if (permissionsState.grantInstallPermission(bp) !=
1433 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1434 if (callback != null) {
1435 callback.onInstallPermissionGranted();
1436 }
1437 }
1438 return;
1439 }
1440
1441 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1442 throw new SecurityException("Cannot grant non-ephemeral permission"
1443 + permName + " for package " + packageName);
1444 }
1445
1446 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1447 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1448 return;
1449 }
1450
1451 final int result = permissionsState.grantRuntimePermission(bp, userId);
1452 switch (result) {
1453 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1454 return;
1455 }
1456
1457 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1458 if (callback != null) {
1459 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1460 }
1461 }
1462 break;
1463 }
1464
1465 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001466 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001467 }
1468
1469 if (callback != null) {
1470 callback.onPermissionGranted(uid, userId);
1471 }
1472
1473 // Only need to do this if user is initialized. Otherwise it's a new user
1474 // and there are no processes running as the user yet and there's no need
1475 // to make an expensive call to remount processes for the changed permissions.
1476 if (READ_EXTERNAL_STORAGE.equals(permName)
1477 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1478 final long token = Binder.clearCallingIdentity();
1479 try {
1480 if (mUserManagerInt.isUserInitialized(userId)) {
1481 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1482 StorageManagerInternal.class);
1483 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1484 }
1485 } finally {
1486 Binder.restoreCallingIdentity(token);
1487 }
1488 }
1489
1490 }
1491
1492 private void revokeRuntimePermission(String permName, String packageName,
1493 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
1494 if (!mUserManagerInt.exists(userId)) {
1495 Log.e(TAG, "No such user:" + userId);
1496 return;
1497 }
1498
1499 mContext.enforceCallingOrSelfPermission(
1500 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1501 "revokeRuntimePermission");
1502
1503 enforceCrossUserPermission(Binder.getCallingUid(), userId,
1504 true /* requireFullPermission */, true /* checkShell */,
1505 "revokeRuntimePermission");
1506
1507 final int appId;
1508
1509 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1510 if (pkg == null || pkg.mExtras == null) {
1511 throw new IllegalArgumentException("Unknown package: " + packageName);
1512 }
1513 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1514 throw new IllegalArgumentException("Unknown package: " + packageName);
1515 }
1516 final BasePermission bp = mSettings.getPermissionLocked(permName);
1517 if (bp == null) {
1518 throw new IllegalArgumentException("Unknown permission: " + permName);
1519 }
1520
1521 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1522
1523 // If a permission review is required for legacy apps we represent
1524 // their permissions as always granted runtime ones since we need
1525 // to keep the review required permission flag per user while an
1526 // install permission's state is shared across all users.
1527 if (mSettings.mPermissionReviewRequired
1528 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
1529 && bp.isRuntime()) {
1530 return;
1531 }
1532
1533 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1534 final PermissionsState permissionsState = ps.getPermissionsState();
1535
1536 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07001537 // Only the system may revoke SYSTEM_FIXED permissions.
1538 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1539 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1540 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07001541 + permName + " for package " + packageName);
1542 }
1543 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1544 throw new SecurityException("Cannot revoke policy fixed permission "
1545 + permName + " for package " + packageName);
1546 }
1547
1548 if (bp.isDevelopment()) {
1549 // Development permissions must be handled specially, since they are not
1550 // normal runtime permissions. For now they apply to all users.
1551 if (permissionsState.revokeInstallPermission(bp) !=
1552 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1553 if (callback != null) {
1554 callback.onInstallPermissionRevoked();
1555 }
1556 }
1557 return;
1558 }
1559
1560 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1561 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1562 return;
1563 }
1564
1565 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001566 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001567 }
1568
1569 if (callback != null) {
1570 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1571 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1572 }
1573 }
1574
Andreas Gampea36dc622018-02-05 17:19:22 -08001575 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001576 private int[] revokeUnusedSharedUserPermissionsLocked(
1577 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001578 // Collect all used permissions in the UID
1579 final ArraySet<String> usedPermissions = new ArraySet<>();
1580 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1581 if (pkgList == null || pkgList.size() == 0) {
1582 return EmptyArray.INT;
1583 }
1584 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07001585 if (pkg.requestedPermissions == null) {
1586 continue;
1587 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07001588 final int requestedPermCount = pkg.requestedPermissions.size();
1589 for (int j = 0; j < requestedPermCount; j++) {
1590 String permission = pkg.requestedPermissions.get(j);
1591 BasePermission bp = mSettings.getPermissionLocked(permission);
1592 if (bp != null) {
1593 usedPermissions.add(permission);
1594 }
1595 }
1596 }
1597
1598 PermissionsState permissionsState = suSetting.getPermissionsState();
1599 // Prune install permissions
1600 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1601 final int installPermCount = installPermStates.size();
1602 for (int i = installPermCount - 1; i >= 0; i--) {
1603 PermissionState permissionState = installPermStates.get(i);
1604 if (!usedPermissions.contains(permissionState.getName())) {
1605 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1606 if (bp != null) {
1607 permissionsState.revokeInstallPermission(bp);
1608 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1609 PackageManager.MASK_PERMISSION_FLAGS, 0);
1610 }
1611 }
1612 }
1613
1614 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1615
1616 // Prune runtime permissions
1617 for (int userId : allUserIds) {
1618 List<PermissionState> runtimePermStates = permissionsState
1619 .getRuntimePermissionStates(userId);
1620 final int runtimePermCount = runtimePermStates.size();
1621 for (int i = runtimePermCount - 1; i >= 0; i--) {
1622 PermissionState permissionState = runtimePermStates.get(i);
1623 if (!usedPermissions.contains(permissionState.getName())) {
1624 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1625 if (bp != null) {
1626 permissionsState.revokeRuntimePermission(bp, userId);
1627 permissionsState.updatePermissionFlags(bp, userId,
1628 PackageManager.MASK_PERMISSION_FLAGS, 0);
1629 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
1630 runtimePermissionChangedUserIds, userId);
1631 }
1632 }
1633 }
1634 }
1635
1636 return runtimePermissionChangedUserIds;
1637 }
1638
Todd Kennedyc8423932017-10-05 08:58:36 -07001639 private String[] getAppOpPermissionPackages(String permName) {
1640 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1641 return null;
1642 }
1643 synchronized (mLock) {
1644 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
1645 if (pkgs == null) {
1646 return null;
1647 }
1648 return pkgs.toArray(new String[pkgs.size()]);
1649 }
1650 }
1651
1652 private int getPermissionFlags(
1653 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001654 if (!mUserManagerInt.exists(userId)) {
1655 return 0;
1656 }
1657
1658 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
1659
1660 enforceCrossUserPermission(callingUid, userId,
1661 true /* requireFullPermission */, false /* checkShell */,
1662 "getPermissionFlags");
1663
1664 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1665 if (pkg == null || pkg.mExtras == null) {
1666 return 0;
1667 }
1668 synchronized (mLock) {
1669 if (mSettings.getPermissionLocked(permName) == null) {
1670 return 0;
1671 }
1672 }
1673 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1674 return 0;
1675 }
1676 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1677 PermissionsState permissionsState = ps.getPermissionsState();
1678 return permissionsState.getPermissionFlags(permName, userId);
1679 }
1680
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001681 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
1682 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
1683 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
1684
1685 private void updatePermissions(String packageName, PackageParser.Package pkg,
1686 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
1687 PermissionCallback callback) {
1688 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
1689 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
1690 updatePermissions(
1691 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
1692 if (pkg != null && pkg.childPackages != null) {
1693 for (PackageParser.Package childPkg : pkg.childPackages) {
1694 updatePermissions(childPkg.packageName, childPkg,
1695 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
1696 }
1697 }
1698 }
1699
1700 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
1701 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
1702 final int flags = UPDATE_PERMISSIONS_ALL |
1703 (sdkUpdated
1704 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
1705 : 0);
1706 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
1707 }
1708
1709 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
1710 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
1711 PermissionCallback callback) {
1712 // TODO: Most of the methods exposing BasePermission internals [source package name,
1713 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
1714 // have package settings, we should make note of it elsewhere [map between
1715 // source package name and BasePermission] and cycle through that here. Then we
1716 // define a single method on BasePermission that takes a PackageSetting, changing
1717 // package name and a package.
1718 // NOTE: With this approach, we also don't need to tree trees differently than
1719 // normal permissions. Today, we need two separate loops because these BasePermission
1720 // objects are stored separately.
1721 // Make sure there are no dangling permission trees.
1722 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
1723
1724 // Make sure all dynamic permissions have been assigned to a package,
1725 // and make sure there are no dangling permissions.
1726 flags = updatePermissions(changingPkgName, changingPkg, flags);
1727
1728 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
1729 // Now update the permissions for all packages, in particular
1730 // replace the granted permissions of the system packages.
1731 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
1732 for (PackageParser.Package pkg : allPackages) {
1733 if (pkg != changingPkg) {
1734 // Only replace for packages on requested volume
1735 final String volumeUuid = getVolumeUuidForPackage(pkg);
1736 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
1737 && Objects.equals(replaceVolumeUuid, volumeUuid);
1738 grantPermissions(pkg, replace, changingPkgName, callback);
1739 }
1740 }
1741 }
1742
1743 if (changingPkg != null) {
1744 // Only replace for packages on requested volume
1745 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
1746 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
1747 && Objects.equals(replaceVolumeUuid, volumeUuid);
1748 grantPermissions(changingPkg, replace, changingPkgName, callback);
1749 }
1750 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1751 }
1752
1753 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001754 Set<BasePermission> needsUpdate = null;
1755 synchronized (mLock) {
1756 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
1757 while (it.hasNext()) {
1758 final BasePermission bp = it.next();
1759 if (bp.isDynamic()) {
1760 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
1761 }
1762 if (bp.getSourcePackageSetting() != null) {
1763 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001764 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001765 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1766 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001767 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001768 it.remove();
1769 }
1770 continue;
1771 }
1772 if (needsUpdate == null) {
1773 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
1774 }
1775 needsUpdate.add(bp);
1776 }
1777 }
1778 if (needsUpdate != null) {
1779 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001780 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001781 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1782 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001783 if (sourcePkg != null && sourcePkg.mExtras != null) {
1784 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001785 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001786 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001787 }
1788 continue;
1789 }
1790 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
1791 + " from package " + bp.getSourcePackageName());
1792 mSettings.removePermissionLocked(bp.getName());
1793 }
1794 }
1795 }
1796 return flags;
1797 }
1798
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001799 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07001800 int flags) {
1801 Set<BasePermission> needsUpdate = null;
1802 synchronized (mLock) {
1803 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
1804 while (it.hasNext()) {
1805 final BasePermission bp = it.next();
1806 if (bp.getSourcePackageSetting() != null) {
1807 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001808 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001809 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1810 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001811 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001812 it.remove();
1813 }
1814 continue;
1815 }
1816 if (needsUpdate == null) {
1817 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
1818 }
1819 needsUpdate.add(bp);
1820 }
1821 }
1822 if (needsUpdate != null) {
1823 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001824 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001825 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1826 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001827 if (sourcePkg != null && sourcePkg.mExtras != null) {
1828 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001829 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001830 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001831 }
1832 continue;
1833 }
1834 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
1835 + " from package " + bp.getSourcePackageName());
1836 mSettings.removePermissionLocked(bp.getName());
1837 }
1838 }
1839 }
1840 return flags;
1841 }
1842
Todd Kennedy0eb97382017-10-03 16:57:22 -07001843 private void updatePermissionFlags(String permName, String packageName, int flagMask,
1844 int flagValues, int callingUid, int userId, PermissionCallback callback) {
1845 if (!mUserManagerInt.exists(userId)) {
1846 return;
1847 }
1848
1849 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
1850
1851 enforceCrossUserPermission(callingUid, userId,
1852 true /* requireFullPermission */, true /* checkShell */,
1853 "updatePermissionFlags");
1854
1855 // Only the system can change these flags and nothing else.
1856 if (callingUid != Process.SYSTEM_UID) {
1857 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1858 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1859 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1860 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1861 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
1862 }
1863
1864 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1865 if (pkg == null || pkg.mExtras == null) {
1866 throw new IllegalArgumentException("Unknown package: " + packageName);
1867 }
1868 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1869 throw new IllegalArgumentException("Unknown package: " + packageName);
1870 }
1871
1872 final BasePermission bp;
1873 synchronized (mLock) {
1874 bp = mSettings.getPermissionLocked(permName);
1875 }
1876 if (bp == null) {
1877 throw new IllegalArgumentException("Unknown permission: " + permName);
1878 }
1879
1880 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1881 final PermissionsState permissionsState = ps.getPermissionsState();
1882 final boolean hadState =
1883 permissionsState.getRuntimePermissionState(permName, userId) != null;
1884 final boolean permissionUpdated =
1885 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
1886 if (permissionUpdated && callback != null) {
1887 // Install and runtime permissions are stored in different places,
1888 // so figure out what permission changed and persist the change.
1889 if (permissionsState.getInstallPermissionState(permName) != null) {
1890 callback.onInstallPermissionUpdated();
1891 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
1892 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001893 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001894 }
1895 }
1896 }
1897
1898 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
1899 int userId, Collection<Package> packages, PermissionCallback callback) {
1900 if (!mUserManagerInt.exists(userId)) {
1901 return false;
1902 }
1903
1904 enforceGrantRevokeRuntimePermissionPermissions(
1905 "updatePermissionFlagsForAllApps");
1906 enforceCrossUserPermission(callingUid, userId,
1907 true /* requireFullPermission */, true /* checkShell */,
1908 "updatePermissionFlagsForAllApps");
1909
1910 // Only the system can change system fixed flags.
1911 if (callingUid != Process.SYSTEM_UID) {
1912 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1913 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1914 }
1915
1916 boolean changed = false;
1917 for (PackageParser.Package pkg : packages) {
1918 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1919 if (ps == null) {
1920 continue;
1921 }
1922 PermissionsState permissionsState = ps.getPermissionsState();
1923 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
1924 userId, flagMask, flagValues);
1925 }
1926 return changed;
1927 }
1928
1929 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
1930 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
1931 != PackageManager.PERMISSION_GRANTED
1932 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
1933 != PackageManager.PERMISSION_GRANTED) {
1934 throw new SecurityException(message + " requires "
1935 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
1936 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
1937 }
1938 }
1939
1940 /**
1941 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
1942 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
1943 * @param checkShell whether to prevent shell from access if there's a debugging restriction
1944 * @param message the message to log on security exception
1945 */
1946 private void enforceCrossUserPermission(int callingUid, int userId,
1947 boolean requireFullPermission, boolean checkShell, String message) {
1948 if (userId < 0) {
1949 throw new IllegalArgumentException("Invalid userId " + userId);
1950 }
1951 if (checkShell) {
1952 PackageManagerServiceUtils.enforceShellRestriction(
1953 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
1954 }
1955 if (userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07001956 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001957 if (requireFullPermission) {
1958 mContext.enforceCallingOrSelfPermission(
1959 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1960 } else {
1961 try {
1962 mContext.enforceCallingOrSelfPermission(
1963 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
1964 } catch (SecurityException se) {
1965 mContext.enforceCallingOrSelfPermission(
1966 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
1967 }
1968 }
1969 }
1970 }
1971
1972 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
1973 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07001974 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001975 size += tree.calculateFootprint(perm);
1976 }
1977 return size;
1978 }
1979
1980 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
1981 // We calculate the max size of permissions defined by this uid and throw
1982 // if that plus the size of 'info' would exceed our stated maximum.
1983 if (tree.getUid() != Process.SYSTEM_UID) {
1984 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
1985 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
1986 throw new SecurityException("Permission tree size cap exceeded");
1987 }
1988 }
1989 }
1990
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001991 private void systemReady() {
1992 mSystemReady = true;
1993 if (mPrivappPermissionsViolations != null) {
1994 throw new IllegalStateException("Signature|privileged permissions not in "
1995 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
1996 }
1997 }
1998
1999 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2000 if (pkg == null) {
2001 return StorageManager.UUID_PRIVATE_INTERNAL;
2002 }
2003 if (pkg.isExternal()) {
2004 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2005 return StorageManager.UUID_PRIMARY_PHYSICAL;
2006 } else {
2007 return pkg.volumeUuid;
2008 }
2009 } else {
2010 return StorageManager.UUID_PRIVATE_INTERNAL;
2011 }
2012 }
2013
Todd Kennedyc8423932017-10-05 08:58:36 -07002014 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2015 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2016 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2017 return true;
2018 }
2019 }
2020 return false;
2021 }
2022
Todd Kennedy0eb97382017-10-03 16:57:22 -07002023 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002024 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002025 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002026 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002027 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002028 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002029 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002030 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2031 final LogMaker log = new LogMaker(action);
2032 log.setPackageName(packageName);
2033 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002034
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002035 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002036 }
2037
2038 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2039 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002040 public void systemReady() {
2041 PermissionManagerService.this.systemReady();
2042 }
2043 @Override
2044 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2045 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2046 }
2047 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002048 public void revokeRuntimePermissionsIfGroupChanged(
2049 @NonNull PackageParser.Package newPackage,
2050 @NonNull PackageParser.Package oldPackage,
2051 @NonNull ArrayList<String> allPackageNames,
2052 @NonNull PermissionCallback permissionCallback) {
2053 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2054 oldPackage, allPackageNames, permissionCallback);
2055 }
2056 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002057 public void addAllPermissions(Package pkg, boolean chatty) {
2058 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002059 }
2060 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002061 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2062 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2063 }
2064 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002065 public void removeAllPermissions(Package pkg, boolean chatty) {
2066 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
2067 }
2068 @Override
2069 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002070 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002071 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2072 }
2073 @Override
2074 public void removeDynamicPermission(String permName, int callingUid,
2075 PermissionCallback callback) {
2076 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002077 }
2078 @Override
2079 public void grantRuntimePermission(String permName, String packageName,
2080 boolean overridePolicy, int callingUid, int userId,
2081 PermissionCallback callback) {
2082 PermissionManagerService.this.grantRuntimePermission(
2083 permName, packageName, overridePolicy, callingUid, userId, callback);
2084 }
2085 @Override
2086 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2087 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2088 PermissionManagerService.this.grantRequestedRuntimePermissions(
2089 pkg, userIds, grantedPermissions, callingUid, callback);
2090 }
2091 @Override
2092 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2093 int callingUid, PermissionCallback callback) {
2094 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2095 pkg, callingUid, callback);
2096 }
2097 @Override
2098 public void revokeRuntimePermission(String permName, String packageName,
2099 boolean overridePolicy, int callingUid, int userId,
2100 PermissionCallback callback) {
2101 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
2102 overridePolicy, callingUid, userId, callback);
2103 }
2104 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002105 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2106 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2107 PermissionManagerService.this.updatePermissions(
2108 packageName, pkg, replaceGrant, allPackages, callback);
2109 }
2110 @Override
2111 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2112 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2113 PermissionManagerService.this.updateAllPermissions(
2114 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002115 }
2116 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002117 public String[] getAppOpPermissionPackages(String permName) {
2118 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2119 }
2120 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002121 public int getPermissionFlags(String permName, String packageName, int callingUid,
2122 int userId) {
2123 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2124 callingUid, userId);
2125 }
2126 @Override
2127 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2128 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2129 PermissionManagerService.this.updatePermissionFlags(
2130 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2131 }
2132 @Override
2133 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2134 int userId, Collection<Package> packages, PermissionCallback callback) {
2135 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2136 flagMask, flagValues, callingUid, userId, packages, callback);
2137 }
2138 @Override
2139 public void enforceCrossUserPermission(int callingUid, int userId,
2140 boolean requireFullPermission, boolean checkShell, String message) {
2141 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2142 requireFullPermission, checkShell, message);
2143 }
2144 @Override
2145 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2146 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2147 }
2148 @Override
2149 public int checkPermission(String permName, String packageName, int callingUid,
2150 int userId) {
2151 return PermissionManagerService.this.checkPermission(
2152 permName, packageName, callingUid, userId);
2153 }
2154 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002155 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2156 int callingUid) {
2157 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002158 }
2159 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002160 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2161 int callingUid) {
2162 return PermissionManagerService.this.getPermissionGroupInfo(
2163 groupName, flags, callingUid);
2164 }
2165 @Override
2166 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2167 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2168 }
2169 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002170 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2171 int callingUid) {
2172 return PermissionManagerService.this.getPermissionInfo(
2173 permName, packageName, flags, callingUid);
2174 }
2175 @Override
2176 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2177 int callingUid) {
2178 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2179 }
2180 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002181 public PermissionSettings getPermissionSettings() {
2182 return mSettings;
2183 }
2184 @Override
2185 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2186 return mDefaultPermissionGrantPolicy;
2187 }
2188 @Override
2189 public BasePermission getPermissionTEMP(String permName) {
2190 synchronized (PermissionManagerService.this.mLock) {
2191 return mSettings.getPermissionLocked(permName);
2192 }
2193 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002194 }
2195}