blob: c4f90a125c71441d10bc464fce4468c2a5c27a61 [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;
Hongwei Wangf391b552018-04-06 13:52:46 -070022import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
23
Todd Kennedyc29b11a2017-10-23 15:55:59 -070024import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
25import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
26import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
27import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
28import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Todd Kennedy0eb97382017-10-03 16:57:22 -070029
30import android.Manifest;
31import android.annotation.NonNull;
32import android.annotation.Nullable;
Todd Kennedy0eb97382017-10-03 16:57:22 -070033import android.content.Context;
Hongming Jine264f6e2018-06-19 12:35:37 -070034import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070035import android.content.pm.PackageManager;
36import android.content.pm.PackageManagerInternal;
37import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070038import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070039import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070040import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070041import android.metrics.LogMaker;
Hongming Jine264f6e2018-06-19 12:35:37 -070042import android.os.AsyncTask;
Todd Kennedy0eb97382017-10-03 16:57:22 -070043import android.os.Binder;
44import android.os.Build;
45import android.os.Handler;
46import android.os.HandlerThread;
47import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070048import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070049import android.os.UserHandle;
50import android.os.UserManager;
51import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070052import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.os.storage.StorageManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070054import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070055import android.util.ArrayMap;
56import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070057import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070058import android.util.Log;
59import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070060import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070061
Todd Kennedyc29b11a2017-10-23 15:55:59 -070062import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070063import com.android.internal.logging.MetricsLogger;
64import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070065import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070066import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070067import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemConfig;
70import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070071import com.android.server.pm.PackageManagerServiceUtils;
72import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070073import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070074import com.android.server.pm.UserManagerService;
Hongwei Wangf391b552018-04-06 13:52:46 -070075import com.android.server.pm.permission.DefaultPermissionGrantPolicy
76 .DefaultPermissionGrantedCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070077import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
78import com.android.server.pm.permission.PermissionsState.PermissionState;
79
80import libcore.util.EmptyArray;
81
82import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -070083import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -070084import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -070085import java.util.Iterator;
86import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -070087import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070088import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -070089import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -070090
91/**
92 * Manages all permissions and handles permissions related tasks.
93 */
94public class PermissionManagerService {
95 private static final String TAG = "PackageManager";
96
Todd Kennedyc29b11a2017-10-23 15:55:59 -070097 /** Permission grant: not grant the permission. */
98 private static final int GRANT_DENIED = 1;
99 /** Permission grant: grant the permission as an install permission. */
100 private static final int GRANT_INSTALL = 2;
101 /** Permission grant: grant the permission as a runtime one. */
102 private static final int GRANT_RUNTIME = 3;
103 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
104 private static final int GRANT_UPGRADE = 4;
105
106 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
107 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
108 /** Empty array to avoid allocations */
109 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700110
Hongwei Wangf391b552018-04-06 13:52:46 -0700111 /** If the permission of the value is granted, so is the key */
112 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
113
114 static {
115 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
116 Manifest.permission.ACCESS_FINE_LOCATION);
117 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
118 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
119 }
120
Todd Kennedy0eb97382017-10-03 16:57:22 -0700121 /** Lock to protect internal data access */
122 private final Object mLock;
123
124 /** Internal connection to the package manager */
125 private final PackageManagerInternal mPackageManagerInt;
126
127 /** Internal connection to the user manager */
128 private final UserManagerInternal mUserManagerInt;
129
130 /** Default permission policy to provide proper behaviour out-of-the-box */
131 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
132
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700133 /**
134 * Built-in permissions. Read from system configuration files. Mapping is from
135 * UID to permission name.
136 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700137 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700138
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700139 /** Built-in group IDs given to all packages. Read from system configuration files. */
140 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700141
142 private final HandlerThread mHandlerThread;
143 private final Handler mHandler;
144 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700145 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700146
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700147 /** Internal storage for permissions and related settings */
148 @GuardedBy("mLock")
149 private final PermissionSettings mSettings;
150
151 @GuardedBy("mLock")
152 private ArraySet<String> mPrivappPermissionsViolations;
153
154 @GuardedBy("mLock")
155 private boolean mSystemReady;
156
Todd Kennedy0eb97382017-10-03 16:57:22 -0700157 PermissionManagerService(Context context,
158 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
159 @NonNull Object externalLock) {
160 mContext = context;
161 mLock = externalLock;
162 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
163 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700164 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700165
166 mHandlerThread = new ServiceThread(TAG,
167 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
168 mHandlerThread.start();
169 mHandler = new Handler(mHandlerThread.getLooper());
170 Watchdog.getInstance().addThread(mHandler);
171
172 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
173 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700174 SystemConfig systemConfig = SystemConfig.getInstance();
175 mSystemPermissions = systemConfig.getSystemPermissions();
176 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700177
178 // propagate permission configuration
179 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
180 SystemConfig.getInstance().getPermissions();
181 synchronized (mLock) {
182 for (int i=0; i<permConfig.size(); i++) {
183 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
184 BasePermission bp = mSettings.getPermissionLocked(perm.name);
185 if (bp == null) {
186 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
187 mSettings.putPermissionLocked(perm.name, bp);
188 }
189 if (perm.gids != null) {
190 bp.setGids(perm.gids, perm.perUser);
191 }
192 }
193 }
194
195 LocalServices.addService(
196 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
197 }
198
199 /**
200 * Creates and returns an initialized, internal service for use by other components.
201 * <p>
202 * The object returned is identical to the one returned by the LocalServices class using:
203 * {@code LocalServices.getService(PermissionManagerInternal.class);}
204 * <p>
205 * NOTE: The external lock is temporary and should be removed. This needs to be a
206 * lock created by the permission manager itself.
207 */
208 public static PermissionManagerInternal create(Context context,
209 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
210 @NonNull Object externalLock) {
211 final PermissionManagerInternal permMgrInt =
212 LocalServices.getService(PermissionManagerInternal.class);
213 if (permMgrInt != null) {
214 return permMgrInt;
215 }
216 new PermissionManagerService(context, defaultGrantCallback, externalLock);
217 return LocalServices.getService(PermissionManagerInternal.class);
218 }
219
220 @Nullable BasePermission getPermission(String permName) {
221 synchronized (mLock) {
222 return mSettings.getPermissionLocked(permName);
223 }
224 }
225
226 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
227 if (!mUserManagerInt.exists(userId)) {
228 return PackageManager.PERMISSION_DENIED;
229 }
230
Patrick Baumann97b9b532018-04-11 14:51:30 +0000231 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
232 if (pkg != null && pkg.mExtras != null) {
233 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700234 return PackageManager.PERMISSION_DENIED;
235 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000236 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700237 final boolean instantApp = ps.getInstantApp(userId);
238 final PermissionsState permissionsState = ps.getPermissionsState();
239 if (permissionsState.hasPermission(permName, userId)) {
240 if (instantApp) {
241 synchronized (mLock) {
242 BasePermission bp = mSettings.getPermissionLocked(permName);
243 if (bp != null && bp.isInstant()) {
244 return PackageManager.PERMISSION_GRANTED;
245 }
246 }
247 } else {
248 return PackageManager.PERMISSION_GRANTED;
249 }
250 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700251 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700252 return PackageManager.PERMISSION_GRANTED;
253 }
254 }
255
256 return PackageManager.PERMISSION_DENIED;
257 }
258
Todd Kennedy3c714492017-10-27 09:12:50 -0700259 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
260 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700261 final int callingUserId = UserHandle.getUserId(callingUid);
262 final boolean isCallerInstantApp =
263 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
264 final boolean isUidInstantApp =
265 mPackageManagerInt.getInstantAppPackageName(uid) != null;
266 final int userId = UserHandle.getUserId(uid);
267 if (!mUserManagerInt.exists(userId)) {
268 return PackageManager.PERMISSION_DENIED;
269 }
270
Todd Kennedy3c714492017-10-27 09:12:50 -0700271 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700272 if (pkg.mSharedUserId != null) {
273 if (isCallerInstantApp) {
274 return PackageManager.PERMISSION_DENIED;
275 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700276 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
277 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700278 }
279 final PermissionsState permissionsState =
280 ((PackageSetting) pkg.mExtras).getPermissionsState();
281 if (permissionsState.hasPermission(permName, userId)) {
282 if (isUidInstantApp) {
283 if (mSettings.isPermissionInstant(permName)) {
284 return PackageManager.PERMISSION_GRANTED;
285 }
286 } else {
287 return PackageManager.PERMISSION_GRANTED;
288 }
289 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700290 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700291 return PackageManager.PERMISSION_GRANTED;
292 }
293 } else {
294 ArraySet<String> perms = mSystemPermissions.get(uid);
295 if (perms != null) {
296 if (perms.contains(permName)) {
297 return PackageManager.PERMISSION_GRANTED;
298 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700299 if (FULLER_PERMISSION_MAP.containsKey(permName)
300 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700301 return PackageManager.PERMISSION_GRANTED;
302 }
303 }
304 }
305 return PackageManager.PERMISSION_DENIED;
306 }
307
Hongwei Wangf391b552018-04-06 13:52:46 -0700308 /**
309 * Returns {@code true} if the permission can be implied from another granted permission.
310 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
311 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
312 * it access to any implied permissions.
313 */
314 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
315 String permName, int userId) {
316 return FULLER_PERMISSION_MAP.containsKey(permName)
317 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
318 }
319
Todd Kennedy460f28c2017-10-06 13:46:22 -0700320 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
321 int callingUid) {
322 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
323 return null;
324 }
325 synchronized (mLock) {
326 return PackageParser.generatePermissionGroupInfo(
327 mSettings.mPermissionGroups.get(groupName), flags);
328 }
329 }
330
331 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
332 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
333 return null;
334 }
335 synchronized (mLock) {
336 final int N = mSettings.mPermissionGroups.size();
337 final ArrayList<PermissionGroupInfo> out
338 = new ArrayList<PermissionGroupInfo>(N);
339 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
340 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
341 }
342 return out;
343 }
344 }
345
346 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700347 int callingUid) {
348 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
349 return null;
350 }
351 // reader
352 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700353 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700354 if (bp == null) {
355 return null;
356 }
357 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
358 bp.getProtectionLevel(), packageName, callingUid);
359 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
360 }
361 }
362
363 private List<PermissionInfo> getPermissionInfoByGroup(
364 String groupName, int flags, int callingUid) {
365 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
366 return null;
367 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700368 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700369 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
370 return null;
371 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700372 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700373 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700374 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
375 if (pi != null) {
376 out.add(pi);
377 }
378 }
379 return out;
380 }
381 }
382
383 private int adjustPermissionProtectionFlagsLocked(
384 int protectionLevel, String packageName, int uid) {
385 // Signature permission flags area always reported
386 final int protectionLevelMasked = protectionLevel
387 & (PermissionInfo.PROTECTION_NORMAL
388 | PermissionInfo.PROTECTION_DANGEROUS
389 | PermissionInfo.PROTECTION_SIGNATURE);
390 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
391 return protectionLevel;
392 }
393 // System sees all flags.
394 final int appId = UserHandle.getAppId(uid);
395 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
396 || appId == Process.SHELL_UID) {
397 return protectionLevel;
398 }
399 // Normalize package name to handle renamed packages and static libs
400 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
401 if (pkg == null) {
402 return protectionLevel;
403 }
404 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
405 return protectionLevelMasked;
406 }
407 // Apps that target O see flags for all protection levels.
408 final PackageSetting ps = (PackageSetting) pkg.mExtras;
409 if (ps == null) {
410 return protectionLevel;
411 }
412 if (ps.getAppId() != appId) {
413 return protectionLevel;
414 }
415 return protectionLevel;
416 }
417
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700418 /**
419 * We might auto-grant permissions if any permission of the group is already granted. Hence if
420 * the group of a granted permission changes we need to revoke it to avoid having permissions of
421 * the new group auto-granted.
422 *
423 * @param newPackage The new package that was installed
424 * @param oldPackage The old package that was updated
425 * @param allPackageNames All package names
426 * @param permissionCallback Callback for permission changed
427 */
428 private void revokeRuntimePermissionsIfGroupChanged(
429 @NonNull PackageParser.Package newPackage,
430 @NonNull PackageParser.Package oldPackage,
431 @NonNull ArrayList<String> allPackageNames,
432 @NonNull PermissionCallback permissionCallback) {
433 final int numOldPackagePermissions = oldPackage.permissions.size();
434 final ArrayMap<String, String> oldPermissionNameToGroupName
435 = new ArrayMap<>(numOldPackagePermissions);
436
437 for (int i = 0; i < numOldPackagePermissions; i++) {
438 final PackageParser.Permission permission = oldPackage.permissions.get(i);
439
440 if (permission.group != null) {
441 oldPermissionNameToGroupName.put(permission.info.name,
442 permission.group.info.name);
443 }
444 }
445
446 final int numNewPackagePermissions = newPackage.permissions.size();
447 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
448 newPermissionNum++) {
449 final PackageParser.Permission newPermission =
450 newPackage.permissions.get(newPermissionNum);
451 final int newProtection = newPermission.info.getProtection();
452
453 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
454 final String permissionName = newPermission.info.name;
455 final String newPermissionGroupName =
456 newPermission.group == null ? null : newPermission.group.info.name;
457 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
458 permissionName);
459
460 if (newPermissionGroupName != null
461 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
462 final int[] userIds = mUserManagerInt.getUserIds();
463 final int numUserIds = userIds.length;
464 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
465 final int userId = userIds[userIdNum];
466
467 final int numPackages = allPackageNames.size();
468 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
469 final String packageName = allPackageNames.get(packageNum);
470
471 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
472 userId) == PackageManager.PERMISSION_GRANTED) {
473 EventLog.writeEvent(0x534e4554, "72710897",
474 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900475 "Revoking permission " + permissionName +
476 " from package " + packageName +
477 " as the group changed from " + oldPermissionGroupName +
478 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700479
480 try {
Hongming Jine264f6e2018-06-19 12:35:37 -0700481 revokeRuntimePermission(permissionName, packageName,
482 mSettings.getPermission(permissionName), false,
483 Process.SYSTEM_UID, userId, permissionCallback, false);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700484 } catch (IllegalArgumentException e) {
485 Slog.e(TAG, "Could not revoke " + permissionName + " from "
486 + packageName, e);
487 }
488 }
489 }
490 }
491 }
492 }
493 }
494 }
495
Todd Kennedyc8423932017-10-05 08:58:36 -0700496 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
497 final int N = pkg.permissions.size();
498 for (int i=0; i<N; i++) {
499 PackageParser.Permission p = pkg.permissions.get(i);
500
501 // Assume by default that we did not install this permission into the system.
502 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
503
Todd Kennedyc8423932017-10-05 08:58:36 -0700504 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700505 // Now that permission groups have a special meaning, we ignore permission
506 // groups for legacy apps to prevent unexpected behavior. In particular,
507 // permissions for one app being granted to someone just because they happen
508 // to be in a group defined by another app (before this had no implications).
509 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
510 p.group = mSettings.mPermissionGroups.get(p.info.group);
511 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700512 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700513 && p.info.group != null && p.group == null) {
514 Slog.i(TAG, "Permission " + p.info.name + " from package "
515 + p.info.packageName + " in an unknown group " + p.info.group);
516 }
517 }
518
Todd Kennedyc8423932017-10-05 08:58:36 -0700519 if (p.tree) {
520 final BasePermission bp = BasePermission.createOrUpdate(
521 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
522 mSettings.getAllPermissionTreesLocked(), chatty);
523 mSettings.putPermissionTreeLocked(p.info.name, bp);
524 } else {
525 final BasePermission bp = BasePermission.createOrUpdate(
526 mSettings.getPermissionLocked(p.info.name),
527 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
528 mSettings.putPermissionLocked(p.info.name, bp);
529 }
530 }
531 }
532 }
533
Todd Kennedy460f28c2017-10-06 13:46:22 -0700534 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
535 final int N = pkg.permissionGroups.size();
536 StringBuilder r = null;
537 for (int i=0; i<N; i++) {
538 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
539 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
540 final String curPackageName = (cur == null) ? null : cur.info.packageName;
541 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
542 if (cur == null || isPackageUpdate) {
543 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700544 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700545 if (r == null) {
546 r = new StringBuilder(256);
547 } else {
548 r.append(' ');
549 }
550 if (isPackageUpdate) {
551 r.append("UPD:");
552 }
553 r.append(pg.info.name);
554 }
555 } else {
556 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
557 + pg.info.packageName + " ignored: original from "
558 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700559 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700560 if (r == null) {
561 r = new StringBuilder(256);
562 } else {
563 r.append(' ');
564 }
565 r.append("DUP:");
566 r.append(pg.info.name);
567 }
568 }
569 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700570 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700571 Log.d(TAG, " Permission Groups: " + r);
572 }
573
574 }
575
Hongming Jine264f6e2018-06-19 12:35:37 -0700576 private void revokeAllPermissions(
577 @NonNull List<BasePermission> bps,
578 @NonNull List<String> allPackageNames,
579 @Nullable PermissionCallback permissionCallback) {
580 AsyncTask.execute(() -> {
581 final int numRemovedPermissions = bps.size();
582 for (int permissionNum = 0; permissionNum < numRemovedPermissions; permissionNum++) {
583 final int[] userIds = mUserManagerInt.getUserIds();
584 final int numUserIds = userIds.length;
585
586 final int numPackages = allPackageNames.size();
587 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
588 final String packageName = allPackageNames.get(packageNum);
589 final ApplicationInfo applicationInfo = mPackageManagerInt.getApplicationInfo(
590 packageName, 0, Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
591 if (applicationInfo != null
592 && applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
593 continue;
594 }
595 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
596 final int userId = userIds[userIdNum];
597 final String permissionName = bps.get(permissionNum).getName();
598 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
599 userId) == PackageManager.PERMISSION_GRANTED) {
600 try {
601 revokeRuntimePermission(
602 permissionName,
603 packageName,
604 bps.get(permissionNum),
605 false,
606 Process.SYSTEM_UID,
607 userId,
608 permissionCallback,
609 true);
610 } catch (IllegalArgumentException e) {
611 Slog.e(TAG, "Could not revoke " + permissionName + " from "
612 + packageName, e);
613 }
614 }
615 }
616 }
617 }
618 });
619 }
620
621 private void removeAllPermissions(
622 @NonNull PackageParser.Package pkg,
623 @NonNull List<String> allPackageNames,
624 @Nullable PermissionCallback permissionCallback,
625 boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700626 synchronized (mLock) {
627 int N = pkg.permissions.size();
Hongming Jine264f6e2018-06-19 12:35:37 -0700628 List<BasePermission> bps = new ArrayList<BasePermission>(N);
Todd Kennedyc8423932017-10-05 08:58:36 -0700629 StringBuilder r = null;
630 for (int i=0; i<N; i++) {
631 PackageParser.Permission p = pkg.permissions.get(i);
632 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
633 if (bp == null) {
634 bp = mSettings.mPermissionTrees.get(p.info.name);
635 }
636 if (bp != null && bp.isPermission(p)) {
Hongming Jine264f6e2018-06-19 12:35:37 -0700637 if ((p.info.getProtection() & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
638 bps.add(bp);
639 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700640 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700641 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700642 if (r == null) {
643 r = new StringBuilder(256);
644 } else {
645 r.append(' ');
646 }
647 r.append(p.info.name);
648 }
649 }
650 if (p.isAppOp()) {
651 ArraySet<String> appOpPkgs =
652 mSettings.mAppOpPermissionPackages.get(p.info.name);
653 if (appOpPkgs != null) {
654 appOpPkgs.remove(pkg.packageName);
655 }
656 }
657 }
Hongming Jine264f6e2018-06-19 12:35:37 -0700658 revokeAllPermissions(bps, allPackageNames, permissionCallback);
Todd Kennedyc8423932017-10-05 08:58:36 -0700659 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700660 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700661 }
662
663 N = pkg.requestedPermissions.size();
664 r = null;
665 for (int i=0; i<N; i++) {
666 String perm = pkg.requestedPermissions.get(i);
667 if (mSettings.isPermissionAppOp(perm)) {
668 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
669 if (appOpPkgs != null) {
670 appOpPkgs.remove(pkg.packageName);
671 if (appOpPkgs.isEmpty()) {
672 mSettings.mAppOpPermissionPackages.remove(perm);
673 }
674 }
675 }
676 }
677 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700678 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700679 }
680 }
681 }
682
683 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700684 PermissionInfo info, int callingUid, PermissionCallback callback) {
685 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
686 throw new SecurityException("Instant apps can't add permissions");
687 }
688 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
689 throw new SecurityException("Label must be specified in permission");
690 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700691 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700692 final boolean added;
693 final boolean changed;
694 synchronized (mLock) {
695 BasePermission bp = mSettings.getPermissionLocked(info.name);
696 added = bp == null;
697 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
698 if (added) {
699 enforcePermissionCapLocked(info, tree);
700 bp = new BasePermission(info.name, tree.getSourcePackageName(),
701 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700702 } else if (!bp.isDynamic()) {
703 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700704 + info.name);
705 }
706 changed = bp.addToTree(fixedLevel, info, tree);
707 if (added) {
708 mSettings.putPermissionLocked(info.name, bp);
709 }
710 }
711 if (changed && callback != null) {
712 callback.onPermissionChanged();
713 }
714 return added;
715 }
716
Todd Kennedyc8423932017-10-05 08:58:36 -0700717 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700718 String permName, int callingUid, PermissionCallback callback) {
719 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
720 throw new SecurityException("Instant applications don't have access to this method");
721 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700722 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700723 synchronized (mLock) {
724 final BasePermission bp = mSettings.getPermissionLocked(permName);
725 if (bp == null) {
726 return;
727 }
728 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600729 // TODO: switch this back to SecurityException
730 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700731 + permName);
732 }
733 mSettings.removePermissionLocked(permName);
734 if (callback != null) {
735 callback.onPermissionRemoved();
736 }
737 }
738 }
739
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700740 private void grantPermissions(PackageParser.Package pkg, boolean replace,
741 String packageOfInterest, PermissionCallback callback) {
742 // IMPORTANT: There are two types of permissions: install and runtime.
743 // Install time permissions are granted when the app is installed to
744 // all device users and users added in the future. Runtime permissions
745 // are granted at runtime explicitly to specific users. Normal and signature
746 // protected permissions are install time permissions. Dangerous permissions
747 // are install permissions if the app's target SDK is Lollipop MR1 or older,
748 // otherwise they are runtime permissions. This function does not manage
749 // runtime permissions except for the case an app targeting Lollipop MR1
750 // being upgraded to target a newer SDK, in which case dangerous permissions
751 // are transformed from install time to runtime ones.
752
753 final PackageSetting ps = (PackageSetting) pkg.mExtras;
754 if (ps == null) {
755 return;
756 }
757 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
758
759 final PermissionsState permissionsState = ps.getPermissionsState();
760 PermissionsState origPermissions = permissionsState;
761
762 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
763
764 boolean runtimePermissionsRevoked = false;
765 int[] updatedUserIds = EMPTY_INT_ARRAY;
766
767 boolean changedInstallPermission = false;
768
769 if (replace) {
770 ps.setInstallPermissionsFixed(false);
771 if (!ps.isSharedUser()) {
772 origPermissions = new PermissionsState(permissionsState);
773 permissionsState.reset();
774 } else {
775 // We need to know only about runtime permission changes since the
776 // calling code always writes the install permissions state but
777 // the runtime ones are written only if changed. The only cases of
778 // changed runtime permissions here are promotion of an install to
779 // runtime and revocation of a runtime from a shared user.
780 synchronized (mLock) {
781 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
782 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
783 if (!ArrayUtils.isEmpty(updatedUserIds)) {
784 runtimePermissionsRevoked = true;
785 }
786 }
787 }
788 }
789
790 permissionsState.setGlobalGids(mGlobalGids);
791
792 synchronized (mLock) {
793 final int N = pkg.requestedPermissions.size();
794 for (int i = 0; i < N; i++) {
795 final String permName = pkg.requestedPermissions.get(i);
796 final BasePermission bp = mSettings.getPermissionLocked(permName);
797 final boolean appSupportsRuntimePermissions =
798 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
799
800 if (DEBUG_INSTALL) {
801 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
802 }
803
804 if (bp == null || bp.getSourcePackageSetting() == null) {
805 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
806 if (DEBUG_PERMISSIONS) {
807 Slog.i(TAG, "Unknown permission " + permName
808 + " in package " + pkg.packageName);
809 }
810 }
811 continue;
812 }
813
814 // Limit ephemeral apps to ephemeral allowed permissions.
815 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
816 if (DEBUG_PERMISSIONS) {
817 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
818 + " for package " + pkg.packageName);
819 }
820 continue;
821 }
822
823 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
824 if (DEBUG_PERMISSIONS) {
825 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
826 + " for package " + pkg.packageName);
827 }
828 continue;
829 }
830
831 final String perm = bp.getName();
832 boolean allowedSig = false;
833 int grant = GRANT_DENIED;
834
835 // Keep track of app op permissions.
836 if (bp.isAppOp()) {
837 mSettings.addAppOpPackage(perm, pkg.packageName);
838 }
839
840 if (bp.isNormal()) {
841 // For all apps normal permissions are install time ones.
842 grant = GRANT_INSTALL;
843 } else if (bp.isRuntime()) {
844 // If a permission review is required for legacy apps we represent
845 // their permissions as always granted runtime ones since we need
846 // to keep the review required permission flag per user while an
847 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700848 if (origPermissions.hasInstallPermission(bp.getName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700849 // For legacy apps that became modern, install becomes runtime.
850 grant = GRANT_UPGRADE;
851 } else if (isLegacySystemApp) {
852 // For legacy system apps, install becomes runtime.
853 // We cannot check hasInstallPermission() for system apps since those
854 // permissions were granted implicitly and not persisted pre-M.
855 grant = GRANT_UPGRADE;
856 } else {
857 // For modern apps keep runtime permissions unchanged.
858 grant = GRANT_RUNTIME;
859 }
860 } else if (bp.isSignature()) {
861 // For all apps signature permissions are install time ones.
862 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
863 if (allowedSig) {
864 grant = GRANT_INSTALL;
865 }
866 }
867
868 if (DEBUG_PERMISSIONS) {
869 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
870 }
871
872 if (grant != GRANT_DENIED) {
873 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
874 // If this is an existing, non-system package, then
875 // we can't add any new permissions to it.
876 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
877 // Except... if this is a permission that was added
878 // to the platform (note: need to only do this when
879 // updating the platform).
880 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
881 grant = GRANT_DENIED;
882 }
883 }
884 }
885
886 switch (grant) {
887 case GRANT_INSTALL: {
888 // Revoke this as runtime permission to handle the case of
889 // a runtime permission being downgraded to an install one.
890 // Also in permission review mode we keep dangerous permissions
891 // for legacy apps
892 for (int userId : UserManagerService.getInstance().getUserIds()) {
893 if (origPermissions.getRuntimePermissionState(
894 perm, userId) != null) {
895 // Revoke the runtime permission and clear the flags.
896 origPermissions.revokeRuntimePermission(bp, userId);
897 origPermissions.updatePermissionFlags(bp, userId,
898 PackageManager.MASK_PERMISSION_FLAGS, 0);
899 // If we revoked a permission permission, we have to write.
900 updatedUserIds = ArrayUtils.appendInt(
901 updatedUserIds, userId);
902 }
903 }
904 // Grant an install permission.
905 if (permissionsState.grantInstallPermission(bp) !=
906 PermissionsState.PERMISSION_OPERATION_FAILURE) {
907 changedInstallPermission = true;
908 }
909 } break;
910
911 case GRANT_RUNTIME: {
912 // Grant previously granted runtime permissions.
913 for (int userId : UserManagerService.getInstance().getUserIds()) {
914 final PermissionState permissionState = origPermissions
915 .getRuntimePermissionState(perm, userId);
916 int flags = permissionState != null
917 ? permissionState.getFlags() : 0;
918 if (origPermissions.hasRuntimePermission(perm, userId)) {
919 // Don't propagate the permission in a permission review
920 // mode if the former was revoked, i.e. marked to not
921 // propagate on upgrade. Note that in a permission review
922 // mode install permissions are represented as constantly
923 // granted runtime ones since we need to keep a per user
924 // state associated with the permission. Also the revoke
925 // on upgrade flag is no longer applicable and is reset.
926 final boolean revokeOnUpgrade = (flags & PackageManager
927 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
928 if (revokeOnUpgrade) {
929 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
930 // Since we changed the flags, we have to write.
931 updatedUserIds = ArrayUtils.appendInt(
932 updatedUserIds, userId);
933 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700934 if (!revokeOnUpgrade) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700935 if (permissionsState.grantRuntimePermission(bp, userId) ==
936 PermissionsState.PERMISSION_OPERATION_FAILURE) {
937 // If we cannot put the permission as it was,
938 // we have to write.
939 updatedUserIds = ArrayUtils.appendInt(
940 updatedUserIds, userId);
941 }
942 }
943
944 // If the app supports runtime permissions no need for a review.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700945 if (appSupportsRuntimePermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700946 && (flags & PackageManager
947 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
948 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
949 // Since we changed the flags, we have to write.
950 updatedUserIds = ArrayUtils.appendInt(
951 updatedUserIds, userId);
952 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700953 } else if (!appSupportsRuntimePermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700954 // For legacy apps that need a permission review, every new
955 // runtime permission is granted but it is pending a review.
956 // We also need to review only platform defined runtime
957 // permissions as these are the only ones the platform knows
958 // how to disable the API to simulate revocation as legacy
959 // apps don't expect to run with revoked permissions.
960 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
961 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
962 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
963 // We changed the flags, hence have to write.
964 updatedUserIds = ArrayUtils.appendInt(
965 updatedUserIds, userId);
966 }
967 }
968 if (permissionsState.grantRuntimePermission(bp, userId)
969 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
970 // We changed the permission, hence have to write.
971 updatedUserIds = ArrayUtils.appendInt(
972 updatedUserIds, userId);
973 }
974 }
975 // Propagate the permission flags.
976 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
977 }
978 } break;
979
980 case GRANT_UPGRADE: {
981 // Grant runtime permissions for a previously held install permission.
982 final PermissionState permissionState = origPermissions
983 .getInstallPermissionState(perm);
984 final int flags =
985 (permissionState != null) ? permissionState.getFlags() : 0;
986
987 if (origPermissions.revokeInstallPermission(bp)
988 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
989 // We will be transferring the permission flags, so clear them.
990 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
991 PackageManager.MASK_PERMISSION_FLAGS, 0);
992 changedInstallPermission = true;
993 }
994
995 // If the permission is not to be promoted to runtime we ignore it and
996 // also its other flags as they are not applicable to install permissions.
997 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
998 for (int userId : currentUserIds) {
999 if (permissionsState.grantRuntimePermission(bp, userId) !=
1000 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1001 // Transfer the permission flags.
1002 permissionsState.updatePermissionFlags(bp, userId,
1003 flags, flags);
1004 // If we granted the permission, we have to write.
1005 updatedUserIds = ArrayUtils.appendInt(
1006 updatedUserIds, userId);
1007 }
1008 }
1009 }
1010 } break;
1011
1012 default: {
1013 if (packageOfInterest == null
1014 || packageOfInterest.equals(pkg.packageName)) {
1015 if (DEBUG_PERMISSIONS) {
1016 Slog.i(TAG, "Not granting permission " + perm
1017 + " to package " + pkg.packageName
1018 + " because it was previously installed without");
1019 }
1020 }
1021 } break;
1022 }
1023 } else {
1024 if (permissionsState.revokeInstallPermission(bp) !=
1025 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1026 // Also drop the permission flags.
1027 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1028 PackageManager.MASK_PERMISSION_FLAGS, 0);
1029 changedInstallPermission = true;
1030 Slog.i(TAG, "Un-granting permission " + perm
1031 + " from package " + pkg.packageName
1032 + " (protectionLevel=" + bp.getProtectionLevel()
1033 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1034 + ")");
1035 } else if (bp.isAppOp()) {
1036 // Don't print warning for app op permissions, since it is fine for them
1037 // not to be granted, there is a UI for the user to decide.
1038 if (DEBUG_PERMISSIONS
1039 && (packageOfInterest == null
1040 || packageOfInterest.equals(pkg.packageName))) {
1041 Slog.i(TAG, "Not granting permission " + perm
1042 + " to package " + pkg.packageName
1043 + " (protectionLevel=" + bp.getProtectionLevel()
1044 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1045 + ")");
1046 }
1047 }
1048 }
1049 }
1050
1051 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1052 !ps.isSystem() || ps.isUpdatedSystem()) {
1053 // This is the first that we have heard about this package, so the
1054 // permissions we have now selected are fixed until explicitly
1055 // changed.
1056 ps.setInstallPermissionsFixed(true);
1057 }
1058 }
1059
1060 // Persist the runtime permissions state for users with changes. If permissions
1061 // were revoked because no app in the shared user declares them we have to
1062 // write synchronously to avoid losing runtime permissions state.
1063 if (callback != null) {
1064 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1065 }
1066 }
1067
1068 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1069 boolean allowed = false;
1070 final int NP = PackageParser.NEW_PERMISSIONS.length;
1071 for (int ip=0; ip<NP; ip++) {
1072 final PackageParser.NewPermissionInfo npi
1073 = PackageParser.NEW_PERMISSIONS[ip];
1074 if (npi.name.equals(perm)
1075 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1076 allowed = true;
1077 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1078 + pkg.packageName);
1079 break;
1080 }
1081 }
1082 return allowed;
1083 }
1084
1085 /**
1086 * Determines whether a package is whitelisted for a particular privapp permission.
1087 *
1088 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1089 *
1090 * <p>This handles parent/child apps.
1091 */
1092 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001093 ArraySet<String> wlPermissions = null;
1094 if (pkg.isVendor()) {
1095 wlPermissions =
1096 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1097 } else if (pkg.isProduct()) {
1098 wlPermissions =
1099 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001100 } else if (pkg.isProductServices()) {
1101 wlPermissions =
1102 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1103 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001104 } else {
1105 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1106 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001107 // Let's check if this package is whitelisted...
1108 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1109 // If it's not, we'll also tail-recurse to the parent.
1110 return whitelisted ||
1111 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1112 }
1113
1114 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1115 BasePermission bp, PermissionsState origPermissions) {
1116 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001117 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1118 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001119 boolean privappPermissionsDisable =
1120 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1121 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1122 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1123 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1124 && !platformPackage && platformPermission) {
1125 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001126 // Only report violations for apps on system image
1127 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1128 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001129 ArraySet<String> deniedPermissions = null;
1130 if (pkg.isVendor()) {
1131 deniedPermissions = SystemConfig.getInstance()
1132 .getVendorPrivAppDenyPermissions(pkg.packageName);
1133 } else if (pkg.isProduct()) {
1134 deniedPermissions = SystemConfig.getInstance()
1135 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001136 } else if (pkg.isProductServices()) {
1137 deniedPermissions = SystemConfig.getInstance()
1138 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001139 } else {
1140 deniedPermissions = SystemConfig.getInstance()
1141 .getPrivAppDenyPermissions(pkg.packageName);
1142 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001143 final boolean permissionViolation =
1144 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001145 if (permissionViolation) {
1146 Slog.w(TAG, "Privileged permission " + perm + " for package "
1147 + pkg.packageName + " - not in privapp-permissions whitelist");
1148
1149 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1150 if (mPrivappPermissionsViolations == null) {
1151 mPrivappPermissionsViolations = new ArraySet<>();
1152 }
1153 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001154 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001155 } else {
1156 return false;
1157 }
1158 }
1159 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1160 return false;
1161 }
1162 }
1163 }
1164 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1165 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1166 final PackageParser.Package systemPackage =
1167 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001168
1169 // check if the package is allow to use this signature permission. A package is allowed to
1170 // use a signature permission if:
1171 // - it has the same set of signing certificates as the source package
1172 // - or its signing certificate was rotated from the source package's certificate
1173 // - or its signing certificate is a previous signing certificate of the defining
1174 // package, and the defining package still trusts the old certificate for permissions
1175 // - or it shares the above relationships with the system package
1176 boolean allowed =
1177 pkg.mSigningDetails.hasAncestorOrSelf(
1178 bp.getSourcePackageSetting().getSigningDetails())
1179 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1180 pkg.mSigningDetails,
1181 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1182 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1183 || systemPackage.mSigningDetails.checkCapability(
1184 pkg.mSigningDetails,
1185 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001186 if (!allowed && (privilegedPermission || oemPermission)) {
1187 if (pkg.isSystem()) {
1188 // For updated system applications, a privileged/oem permission
1189 // is granted only if it had been defined by the original application.
1190 if (pkg.isUpdatedSystemApp()) {
1191 final PackageParser.Package disabledPkg =
1192 mPackageManagerInt.getDisabledPackage(pkg.packageName);
1193 final PackageSetting disabledPs =
1194 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1195 if (disabledPs != null
1196 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1197 // If the original was granted this permission, we take
1198 // that grant decision as read and propagate it to the
1199 // update.
1200 if ((privilegedPermission && disabledPs.isPrivileged())
1201 || (oemPermission && disabledPs.isOem()
1202 && canGrantOemPermission(disabledPs, perm))) {
1203 allowed = true;
1204 }
1205 } else {
1206 // The system apk may have been updated with an older
1207 // version of the one on the data partition, but which
1208 // granted a new system permission that it didn't have
1209 // before. In this case we do want to allow the app to
1210 // now get the new permission if the ancestral apk is
1211 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001212 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001213 && isPackageRequestingPermission(disabledPkg, perm)
1214 && ((privilegedPermission && disabledPs.isPrivileged())
1215 || (oemPermission && disabledPs.isOem()
1216 && canGrantOemPermission(disabledPs, perm)))) {
1217 allowed = true;
1218 }
1219 // Also if a privileged parent package on the system image or any of
1220 // its children requested a privileged/oem permission, the updated child
1221 // packages can also get the permission.
1222 if (pkg.parentPackage != null) {
1223 final PackageParser.Package disabledParentPkg = mPackageManagerInt
1224 .getDisabledPackage(pkg.parentPackage.packageName);
1225 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1226 ? (PackageSetting) disabledParentPkg.mExtras : null;
1227 if (disabledParentPkg != null
1228 && ((privilegedPermission && disabledParentPs.isPrivileged())
1229 || (oemPermission && disabledParentPs.isOem()))) {
1230 if (isPackageRequestingPermission(disabledParentPkg, perm)
1231 && canGrantOemPermission(disabledParentPs, perm)) {
1232 allowed = true;
1233 } else if (disabledParentPkg.childPackages != null) {
1234 for (PackageParser.Package disabledChildPkg
1235 : disabledParentPkg.childPackages) {
1236 final PackageSetting disabledChildPs =
1237 (disabledChildPkg != null)
1238 ? (PackageSetting) disabledChildPkg.mExtras
1239 : null;
1240 if (isPackageRequestingPermission(disabledChildPkg, perm)
1241 && canGrantOemPermission(
1242 disabledChildPs, perm)) {
1243 allowed = true;
1244 break;
1245 }
1246 }
1247 }
1248 }
1249 }
1250 }
1251 } else {
1252 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1253 allowed = (privilegedPermission && pkg.isPrivileged())
1254 || (oemPermission && pkg.isOem()
1255 && canGrantOemPermission(ps, perm));
1256 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001257 // In any case, don't grant a privileged permission to privileged vendor apps, if
1258 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1259 // flag.
1260 if (allowed && privilegedPermission &&
1261 !vendorPrivilegedPermission && pkg.isVendor()) {
1262 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1263 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1264 allowed = false;
1265 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001266 }
1267 }
1268 if (!allowed) {
1269 if (!allowed
1270 && bp.isPre23()
1271 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1272 // If this was a previously normal/dangerous permission that got moved
1273 // to a system permission as part of the runtime permission redesign, then
1274 // we still want to blindly grant it to old apps.
1275 allowed = true;
1276 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001277 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1278 // need a separate flag anymore. Hence we need to check which
1279 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001280 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001281 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1282 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1283 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1284 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1285 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001286 // If this permission is to be granted to the system installer and
1287 // this app is an installer, then it gets the permission.
1288 allowed = true;
1289 }
1290 if (!allowed && bp.isVerifier()
1291 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1292 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1293 // If this permission is to be granted to the system verifier and
1294 // this app is a verifier, then it gets the permission.
1295 allowed = true;
1296 }
1297 if (!allowed && bp.isPreInstalled()
1298 && pkg.isSystem()) {
1299 // Any pre-installed system app is allowed to get this permission.
1300 allowed = true;
1301 }
1302 if (!allowed && bp.isDevelopment()) {
1303 // For development permissions, a development permission
1304 // is granted only if it was already granted.
1305 allowed = origPermissions.hasInstallPermission(perm);
1306 }
1307 if (!allowed && bp.isSetup()
1308 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1309 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1310 // If this permission is to be granted to the system setup wizard and
1311 // this app is a setup wizard, then it gets the permission.
1312 allowed = true;
1313 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001314 if (!allowed && bp.isSystemTextClassifier()
1315 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1316 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1317 UserHandle.USER_SYSTEM))) {
1318 // Special permissions for the system default text classifier.
1319 allowed = true;
1320 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001321 }
1322 return allowed;
1323 }
1324
1325 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1326 if (!ps.isOem()) {
1327 return false;
1328 }
1329 // all oem permissions must explicitly be granted or denied
1330 final Boolean granted =
1331 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1332 if (granted == null) {
1333 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1334 + ps.name + " must be explicitly declared granted or not");
1335 }
1336 return Boolean.TRUE == granted;
1337 }
1338
1339 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001340 // Permission review applies only to apps not supporting the new permission model.
1341 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1342 return false;
1343 }
1344
1345 // Legacy apps have the permission and get user consent on launch.
1346 if (pkg == null || pkg.mExtras == null) {
1347 return false;
1348 }
1349 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1350 final PermissionsState permissionsState = ps.getPermissionsState();
1351 return permissionsState.isPermissionReviewRequired(userId);
1352 }
1353
1354 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1355 final int permCount = pkg.requestedPermissions.size();
1356 for (int j = 0; j < permCount; j++) {
1357 String requestedPermission = pkg.requestedPermissions.get(j);
1358 if (permission.equals(requestedPermission)) {
1359 return true;
1360 }
1361 }
1362 return false;
1363 }
1364
Andreas Gampea36dc622018-02-05 17:19:22 -08001365 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001366 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1367 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1368 if (pkg.parentPackage == null) {
1369 return;
1370 }
1371 if (pkg.requestedPermissions == null) {
1372 return;
1373 }
1374 final PackageParser.Package disabledPkg =
1375 mPackageManagerInt.getDisabledPackage(pkg.parentPackage.packageName);
1376 if (disabledPkg == null || disabledPkg.mExtras == null) {
1377 return;
1378 }
1379 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1380 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1381 return;
1382 }
1383 final int permCount = pkg.requestedPermissions.size();
1384 for (int i = 0; i < permCount; i++) {
1385 String permission = pkg.requestedPermissions.get(i);
1386 BasePermission bp = mSettings.getPermissionLocked(permission);
1387 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1388 continue;
1389 }
1390 for (int userId : mUserManagerInt.getUserIds()) {
1391 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1392 grantRuntimePermission(
1393 permission, pkg.packageName, false, callingUid, userId, callback);
1394 }
1395 }
1396 }
1397 }
1398
1399 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1400 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1401 for (int userId : userIds) {
1402 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1403 callback);
1404 }
1405 }
1406
1407 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1408 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1409 PackageSetting ps = (PackageSetting) pkg.mExtras;
1410 if (ps == null) {
1411 return;
1412 }
1413
1414 PermissionsState permissionsState = ps.getPermissionsState();
1415
1416 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1417 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1418
1419 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1420 >= Build.VERSION_CODES.M;
1421
1422 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1423
1424 for (String permission : pkg.requestedPermissions) {
1425 final BasePermission bp;
1426 synchronized (mLock) {
1427 bp = mSettings.getPermissionLocked(permission);
1428 }
1429 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1430 && (!instantApp || bp.isInstant())
1431 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1432 && (grantedPermissions == null
1433 || ArrayUtils.contains(grantedPermissions, permission))) {
1434 final int flags = permissionsState.getPermissionFlags(permission, userId);
1435 if (supportsRuntimePermissions) {
1436 // Installer cannot change immutable permissions.
1437 if ((flags & immutableFlags) == 0) {
1438 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1439 userId, callback);
1440 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001441 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001442 // In permission review mode we clear the review flag when we
1443 // are asked to install the app with all permissions granted.
1444 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1445 updatePermissionFlags(permission, pkg.packageName,
1446 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1447 userId, callback);
1448 }
1449 }
1450 }
1451 }
1452 }
1453
1454 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1455 int callingUid, final int userId, PermissionCallback callback) {
1456 if (!mUserManagerInt.exists(userId)) {
1457 Log.e(TAG, "No such user:" + userId);
1458 return;
1459 }
1460
1461 mContext.enforceCallingOrSelfPermission(
1462 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1463 "grantRuntimePermission");
1464
1465 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001466 true, // requireFullPermission
1467 true, // checkShell
1468 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001469 "grantRuntimePermission");
1470
1471 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1472 if (pkg == null || pkg.mExtras == null) {
1473 throw new IllegalArgumentException("Unknown package: " + packageName);
1474 }
1475 final BasePermission bp;
1476 synchronized(mLock) {
1477 bp = mSettings.getPermissionLocked(permName);
1478 }
1479 if (bp == null) {
1480 throw new IllegalArgumentException("Unknown permission: " + permName);
1481 }
1482 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1483 throw new IllegalArgumentException("Unknown package: " + packageName);
1484 }
1485
1486 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1487
1488 // If a permission review is required for legacy apps we represent
1489 // their permissions as always granted runtime ones since we need
1490 // to keep the review required permission flag per user while an
1491 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001492 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001493 && bp.isRuntime()) {
1494 return;
1495 }
1496
1497 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1498
1499 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1500 final PermissionsState permissionsState = ps.getPermissionsState();
1501
1502 final int flags = permissionsState.getPermissionFlags(permName, userId);
1503 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1504 throw new SecurityException("Cannot grant system fixed permission "
1505 + permName + " for package " + packageName);
1506 }
1507 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1508 throw new SecurityException("Cannot grant policy fixed permission "
1509 + permName + " for package " + packageName);
1510 }
1511
1512 if (bp.isDevelopment()) {
1513 // Development permissions must be handled specially, since they are not
1514 // normal runtime permissions. For now they apply to all users.
1515 if (permissionsState.grantInstallPermission(bp) !=
1516 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1517 if (callback != null) {
1518 callback.onInstallPermissionGranted();
1519 }
1520 }
1521 return;
1522 }
1523
1524 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1525 throw new SecurityException("Cannot grant non-ephemeral permission"
1526 + permName + " for package " + packageName);
1527 }
1528
1529 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1530 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1531 return;
1532 }
1533
1534 final int result = permissionsState.grantRuntimePermission(bp, userId);
1535 switch (result) {
1536 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1537 return;
1538 }
1539
1540 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1541 if (callback != null) {
1542 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1543 }
1544 }
1545 break;
1546 }
1547
1548 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001549 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001550 }
1551
1552 if (callback != null) {
1553 callback.onPermissionGranted(uid, userId);
1554 }
1555
1556 // Only need to do this if user is initialized. Otherwise it's a new user
1557 // and there are no processes running as the user yet and there's no need
1558 // to make an expensive call to remount processes for the changed permissions.
1559 if (READ_EXTERNAL_STORAGE.equals(permName)
1560 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1561 final long token = Binder.clearCallingIdentity();
1562 try {
1563 if (mUserManagerInt.isUserInitialized(userId)) {
1564 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1565 StorageManagerInternal.class);
1566 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1567 }
1568 } finally {
1569 Binder.restoreCallingIdentity(token);
1570 }
1571 }
1572
1573 }
Hongming Jine264f6e2018-06-19 12:35:37 -07001574
1575 private void revokeRuntimePermission(String permName, String packageName, BasePermission bp,
1576 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback,
1577 boolean permissionRemoved) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001578 if (!mUserManagerInt.exists(userId)) {
1579 Log.e(TAG, "No such user:" + userId);
1580 return;
1581 }
1582
1583 mContext.enforceCallingOrSelfPermission(
1584 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1585 "revokeRuntimePermission");
1586
1587 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001588 true, // requireFullPermission
1589 true, // checkShell
1590 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001591 "revokeRuntimePermission");
1592
1593 final int appId;
1594
1595 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1596 if (pkg == null || pkg.mExtras == null) {
1597 throw new IllegalArgumentException("Unknown package: " + packageName);
1598 }
1599 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1600 throw new IllegalArgumentException("Unknown package: " + packageName);
1601 }
Hongming Jine264f6e2018-06-19 12:35:37 -07001602
Todd Kennedy0eb97382017-10-03 16:57:22 -07001603 if (bp == null) {
1604 throw new IllegalArgumentException("Unknown permission: " + permName);
1605 }
1606
1607 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1608
1609 // If a permission review is required for legacy apps we represent
1610 // their permissions as always granted runtime ones since we need
1611 // to keep the review required permission flag per user while an
1612 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001613 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001614 && bp.isRuntime()) {
1615 return;
1616 }
1617
1618 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1619 final PermissionsState permissionsState = ps.getPermissionsState();
1620
1621 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07001622 // Only the system may revoke SYSTEM_FIXED permissions.
1623 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1624 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1625 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07001626 + permName + " for package " + packageName);
1627 }
1628 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1629 throw new SecurityException("Cannot revoke policy fixed permission "
1630 + permName + " for package " + packageName);
1631 }
1632
1633 if (bp.isDevelopment()) {
1634 // Development permissions must be handled specially, since they are not
1635 // normal runtime permissions. For now they apply to all users.
1636 if (permissionsState.revokeInstallPermission(bp) !=
1637 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1638 if (callback != null) {
1639 callback.onInstallPermissionRevoked();
1640 }
1641 }
1642 return;
1643 }
1644
1645 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1646 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1647 return;
1648 }
1649
1650 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001651 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001652 }
1653
1654 if (callback != null) {
1655 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1656 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1657 }
1658 }
1659
Andreas Gampea36dc622018-02-05 17:19:22 -08001660 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001661 private int[] revokeUnusedSharedUserPermissionsLocked(
1662 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001663 // Collect all used permissions in the UID
1664 final ArraySet<String> usedPermissions = new ArraySet<>();
1665 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1666 if (pkgList == null || pkgList.size() == 0) {
1667 return EmptyArray.INT;
1668 }
1669 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07001670 if (pkg.requestedPermissions == null) {
1671 continue;
1672 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07001673 final int requestedPermCount = pkg.requestedPermissions.size();
1674 for (int j = 0; j < requestedPermCount; j++) {
1675 String permission = pkg.requestedPermissions.get(j);
1676 BasePermission bp = mSettings.getPermissionLocked(permission);
1677 if (bp != null) {
1678 usedPermissions.add(permission);
1679 }
1680 }
1681 }
1682
1683 PermissionsState permissionsState = suSetting.getPermissionsState();
1684 // Prune install permissions
1685 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1686 final int installPermCount = installPermStates.size();
1687 for (int i = installPermCount - 1; i >= 0; i--) {
1688 PermissionState permissionState = installPermStates.get(i);
1689 if (!usedPermissions.contains(permissionState.getName())) {
1690 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1691 if (bp != null) {
1692 permissionsState.revokeInstallPermission(bp);
1693 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1694 PackageManager.MASK_PERMISSION_FLAGS, 0);
1695 }
1696 }
1697 }
1698
1699 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1700
1701 // Prune runtime permissions
1702 for (int userId : allUserIds) {
1703 List<PermissionState> runtimePermStates = permissionsState
1704 .getRuntimePermissionStates(userId);
1705 final int runtimePermCount = runtimePermStates.size();
1706 for (int i = runtimePermCount - 1; i >= 0; i--) {
1707 PermissionState permissionState = runtimePermStates.get(i);
1708 if (!usedPermissions.contains(permissionState.getName())) {
1709 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1710 if (bp != null) {
1711 permissionsState.revokeRuntimePermission(bp, userId);
1712 permissionsState.updatePermissionFlags(bp, userId,
1713 PackageManager.MASK_PERMISSION_FLAGS, 0);
1714 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
1715 runtimePermissionChangedUserIds, userId);
1716 }
1717 }
1718 }
1719 }
1720
1721 return runtimePermissionChangedUserIds;
1722 }
1723
Todd Kennedyc8423932017-10-05 08:58:36 -07001724 private String[] getAppOpPermissionPackages(String permName) {
1725 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1726 return null;
1727 }
1728 synchronized (mLock) {
1729 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
1730 if (pkgs == null) {
1731 return null;
1732 }
1733 return pkgs.toArray(new String[pkgs.size()]);
1734 }
1735 }
1736
1737 private int getPermissionFlags(
1738 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001739 if (!mUserManagerInt.exists(userId)) {
1740 return 0;
1741 }
1742
1743 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
1744
1745 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001746 true, // requireFullPermission
1747 false, // checkShell
1748 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001749 "getPermissionFlags");
1750
1751 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1752 if (pkg == null || pkg.mExtras == null) {
1753 return 0;
1754 }
1755 synchronized (mLock) {
1756 if (mSettings.getPermissionLocked(permName) == null) {
1757 return 0;
1758 }
1759 }
1760 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1761 return 0;
1762 }
1763 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1764 PermissionsState permissionsState = ps.getPermissionsState();
1765 return permissionsState.getPermissionFlags(permName, userId);
1766 }
1767
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001768 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
1769 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
1770 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
1771
1772 private void updatePermissions(String packageName, PackageParser.Package pkg,
1773 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
1774 PermissionCallback callback) {
1775 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
1776 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
1777 updatePermissions(
1778 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
1779 if (pkg != null && pkg.childPackages != null) {
1780 for (PackageParser.Package childPkg : pkg.childPackages) {
1781 updatePermissions(childPkg.packageName, childPkg,
1782 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
1783 }
1784 }
1785 }
1786
1787 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
1788 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
1789 final int flags = UPDATE_PERMISSIONS_ALL |
1790 (sdkUpdated
1791 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
1792 : 0);
1793 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
1794 }
1795
1796 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
1797 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
1798 PermissionCallback callback) {
1799 // TODO: Most of the methods exposing BasePermission internals [source package name,
1800 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
1801 // have package settings, we should make note of it elsewhere [map between
1802 // source package name and BasePermission] and cycle through that here. Then we
1803 // define a single method on BasePermission that takes a PackageSetting, changing
1804 // package name and a package.
1805 // NOTE: With this approach, we also don't need to tree trees differently than
1806 // normal permissions. Today, we need two separate loops because these BasePermission
1807 // objects are stored separately.
1808 // Make sure there are no dangling permission trees.
1809 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
1810
1811 // Make sure all dynamic permissions have been assigned to a package,
1812 // and make sure there are no dangling permissions.
1813 flags = updatePermissions(changingPkgName, changingPkg, flags);
1814
1815 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
1816 // Now update the permissions for all packages, in particular
1817 // replace the granted permissions of the system packages.
1818 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
1819 for (PackageParser.Package pkg : allPackages) {
1820 if (pkg != changingPkg) {
1821 // Only replace for packages on requested volume
1822 final String volumeUuid = getVolumeUuidForPackage(pkg);
1823 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
1824 && Objects.equals(replaceVolumeUuid, volumeUuid);
1825 grantPermissions(pkg, replace, changingPkgName, callback);
1826 }
1827 }
1828 }
1829
1830 if (changingPkg != null) {
1831 // Only replace for packages on requested volume
1832 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
1833 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
1834 && Objects.equals(replaceVolumeUuid, volumeUuid);
1835 grantPermissions(changingPkg, replace, changingPkgName, callback);
1836 }
1837 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1838 }
1839
1840 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001841 Set<BasePermission> needsUpdate = null;
1842 synchronized (mLock) {
1843 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
1844 while (it.hasNext()) {
1845 final BasePermission bp = it.next();
1846 if (bp.isDynamic()) {
1847 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
1848 }
1849 if (bp.getSourcePackageSetting() != null) {
1850 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001851 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001852 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1853 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001854 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001855 it.remove();
1856 }
1857 continue;
1858 }
1859 if (needsUpdate == null) {
1860 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
1861 }
1862 needsUpdate.add(bp);
1863 }
1864 }
1865 if (needsUpdate != null) {
1866 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001867 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001868 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1869 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001870 if (sourcePkg != null && sourcePkg.mExtras != null) {
1871 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001872 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001873 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001874 }
1875 continue;
1876 }
1877 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
1878 + " from package " + bp.getSourcePackageName());
1879 mSettings.removePermissionLocked(bp.getName());
1880 }
1881 }
1882 }
1883 return flags;
1884 }
1885
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001886 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07001887 int flags) {
1888 Set<BasePermission> needsUpdate = null;
1889 synchronized (mLock) {
1890 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
1891 while (it.hasNext()) {
1892 final BasePermission bp = it.next();
1893 if (bp.getSourcePackageSetting() != null) {
1894 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001895 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001896 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1897 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001898 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001899 it.remove();
1900 }
1901 continue;
1902 }
1903 if (needsUpdate == null) {
1904 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
1905 }
1906 needsUpdate.add(bp);
1907 }
1908 }
1909 if (needsUpdate != null) {
1910 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001911 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001912 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1913 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001914 if (sourcePkg != null && sourcePkg.mExtras != null) {
1915 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001916 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001917 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001918 }
1919 continue;
1920 }
1921 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
1922 + " from package " + bp.getSourcePackageName());
1923 mSettings.removePermissionLocked(bp.getName());
1924 }
1925 }
1926 }
1927 return flags;
1928 }
1929
Todd Kennedy0eb97382017-10-03 16:57:22 -07001930 private void updatePermissionFlags(String permName, String packageName, int flagMask,
1931 int flagValues, int callingUid, int userId, PermissionCallback callback) {
1932 if (!mUserManagerInt.exists(userId)) {
1933 return;
1934 }
1935
1936 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
1937
1938 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001939 true, // requireFullPermission
1940 true, // checkShell
1941 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001942 "updatePermissionFlags");
1943
1944 // Only the system can change these flags and nothing else.
1945 if (callingUid != Process.SYSTEM_UID) {
1946 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1947 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1948 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1949 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1950 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
1951 }
1952
1953 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1954 if (pkg == null || pkg.mExtras == null) {
1955 throw new IllegalArgumentException("Unknown package: " + packageName);
1956 }
1957 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1958 throw new IllegalArgumentException("Unknown package: " + packageName);
1959 }
1960
1961 final BasePermission bp;
1962 synchronized (mLock) {
1963 bp = mSettings.getPermissionLocked(permName);
1964 }
1965 if (bp == null) {
1966 throw new IllegalArgumentException("Unknown permission: " + permName);
1967 }
1968
1969 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1970 final PermissionsState permissionsState = ps.getPermissionsState();
1971 final boolean hadState =
1972 permissionsState.getRuntimePermissionState(permName, userId) != null;
1973 final boolean permissionUpdated =
1974 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
1975 if (permissionUpdated && callback != null) {
1976 // Install and runtime permissions are stored in different places,
1977 // so figure out what permission changed and persist the change.
1978 if (permissionsState.getInstallPermissionState(permName) != null) {
1979 callback.onInstallPermissionUpdated();
1980 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
1981 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001982 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001983 }
1984 }
1985 }
1986
1987 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
1988 int userId, Collection<Package> packages, PermissionCallback callback) {
1989 if (!mUserManagerInt.exists(userId)) {
1990 return false;
1991 }
1992
1993 enforceGrantRevokeRuntimePermissionPermissions(
1994 "updatePermissionFlagsForAllApps");
1995 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001996 true, // requireFullPermission
1997 true, // checkShell
1998 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001999 "updatePermissionFlagsForAllApps");
2000
2001 // Only the system can change system fixed flags.
2002 if (callingUid != Process.SYSTEM_UID) {
2003 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2004 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2005 }
2006
2007 boolean changed = false;
2008 for (PackageParser.Package pkg : packages) {
2009 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2010 if (ps == null) {
2011 continue;
2012 }
2013 PermissionsState permissionsState = ps.getPermissionsState();
2014 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2015 userId, flagMask, flagValues);
2016 }
2017 return changed;
2018 }
2019
2020 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2021 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2022 != PackageManager.PERMISSION_GRANTED
2023 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2024 != PackageManager.PERMISSION_GRANTED) {
2025 throw new SecurityException(message + " requires "
2026 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2027 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2028 }
2029 }
2030
2031 /**
2032 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2033 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2034 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2035 * @param message the message to log on security exception
2036 */
2037 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002038 boolean requireFullPermission, boolean checkShell,
2039 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002040 if (userId < 0) {
2041 throw new IllegalArgumentException("Invalid userId " + userId);
2042 }
2043 if (checkShell) {
2044 PackageManagerServiceUtils.enforceShellRestriction(
2045 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2046 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002047 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002048 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002049 if (requireFullPermission) {
2050 mContext.enforceCallingOrSelfPermission(
2051 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2052 } else {
2053 try {
2054 mContext.enforceCallingOrSelfPermission(
2055 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2056 } catch (SecurityException se) {
2057 mContext.enforceCallingOrSelfPermission(
2058 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2059 }
2060 }
2061 }
2062 }
2063
Andreas Gampea71bee82018-07-20 12:55:36 -07002064 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002065 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2066 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002067 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002068 size += tree.calculateFootprint(perm);
2069 }
2070 return size;
2071 }
2072
Andreas Gampea71bee82018-07-20 12:55:36 -07002073 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002074 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2075 // We calculate the max size of permissions defined by this uid and throw
2076 // if that plus the size of 'info' would exceed our stated maximum.
2077 if (tree.getUid() != Process.SYSTEM_UID) {
2078 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2079 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2080 throw new SecurityException("Permission tree size cap exceeded");
2081 }
2082 }
2083 }
2084
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002085 private void systemReady() {
2086 mSystemReady = true;
2087 if (mPrivappPermissionsViolations != null) {
2088 throw new IllegalStateException("Signature|privileged permissions not in "
2089 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2090 }
2091 }
2092
2093 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2094 if (pkg == null) {
2095 return StorageManager.UUID_PRIVATE_INTERNAL;
2096 }
2097 if (pkg.isExternal()) {
2098 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2099 return StorageManager.UUID_PRIMARY_PHYSICAL;
2100 } else {
2101 return pkg.volumeUuid;
2102 }
2103 } else {
2104 return StorageManager.UUID_PRIVATE_INTERNAL;
2105 }
2106 }
2107
Todd Kennedyc8423932017-10-05 08:58:36 -07002108 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2109 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2110 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2111 return true;
2112 }
2113 }
2114 return false;
2115 }
2116
Todd Kennedy0eb97382017-10-03 16:57:22 -07002117 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002118 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002119 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002120 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002121 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002122 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002123 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002124 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2125 final LogMaker log = new LogMaker(action);
2126 log.setPackageName(packageName);
2127 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002128
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002129 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002130 }
2131
2132 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2133 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002134 public void systemReady() {
2135 PermissionManagerService.this.systemReady();
2136 }
2137 @Override
2138 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2139 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2140 }
2141 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002142 public void revokeRuntimePermissionsIfGroupChanged(
2143 @NonNull PackageParser.Package newPackage,
2144 @NonNull PackageParser.Package oldPackage,
2145 @NonNull ArrayList<String> allPackageNames,
2146 @NonNull PermissionCallback permissionCallback) {
2147 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2148 oldPackage, allPackageNames, permissionCallback);
2149 }
2150 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002151 public void addAllPermissions(Package pkg, boolean chatty) {
2152 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002153 }
2154 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002155 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2156 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2157 }
2158 @Override
Hongming Jine264f6e2018-06-19 12:35:37 -07002159 public void removeAllPermissions(Package pkg, List<String> allPackageNames,
2160 PermissionCallback permissionCallback, boolean chatty) {
2161 PermissionManagerService.this.removeAllPermissions(
2162 pkg, allPackageNames, permissionCallback, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002163 }
2164 @Override
2165 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002166 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002167 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2168 }
2169 @Override
2170 public void removeDynamicPermission(String permName, int callingUid,
2171 PermissionCallback callback) {
2172 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002173 }
2174 @Override
2175 public void grantRuntimePermission(String permName, String packageName,
2176 boolean overridePolicy, int callingUid, int userId,
2177 PermissionCallback callback) {
2178 PermissionManagerService.this.grantRuntimePermission(
2179 permName, packageName, overridePolicy, callingUid, userId, callback);
2180 }
2181 @Override
2182 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2183 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2184 PermissionManagerService.this.grantRequestedRuntimePermissions(
2185 pkg, userIds, grantedPermissions, callingUid, callback);
2186 }
2187 @Override
2188 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2189 int callingUid, PermissionCallback callback) {
2190 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2191 pkg, callingUid, callback);
2192 }
2193 @Override
2194 public void revokeRuntimePermission(String permName, String packageName,
2195 boolean overridePolicy, int callingUid, int userId,
2196 PermissionCallback callback) {
2197 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jine264f6e2018-06-19 12:35:37 -07002198 mSettings.getPermission(permName), overridePolicy, callingUid, userId,
2199 callback, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002200 }
2201 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002202 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2203 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2204 PermissionManagerService.this.updatePermissions(
2205 packageName, pkg, replaceGrant, allPackages, callback);
2206 }
2207 @Override
2208 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2209 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2210 PermissionManagerService.this.updateAllPermissions(
2211 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002212 }
2213 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002214 public String[] getAppOpPermissionPackages(String permName) {
2215 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2216 }
2217 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002218 public int getPermissionFlags(String permName, String packageName, int callingUid,
2219 int userId) {
2220 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2221 callingUid, userId);
2222 }
2223 @Override
2224 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2225 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2226 PermissionManagerService.this.updatePermissionFlags(
2227 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2228 }
2229 @Override
2230 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2231 int userId, Collection<Package> packages, PermissionCallback callback) {
2232 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2233 flagMask, flagValues, callingUid, userId, packages, callback);
2234 }
2235 @Override
2236 public void enforceCrossUserPermission(int callingUid, int userId,
2237 boolean requireFullPermission, boolean checkShell, String message) {
2238 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002239 requireFullPermission, checkShell, false, message);
2240 }
2241 @Override
2242 public void enforceCrossUserPermission(int callingUid, int userId,
2243 boolean requireFullPermission, boolean checkShell,
2244 boolean requirePermissionWhenSameUser, String message) {
2245 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2246 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002247 }
2248 @Override
2249 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2250 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2251 }
2252 @Override
2253 public int checkPermission(String permName, String packageName, int callingUid,
2254 int userId) {
2255 return PermissionManagerService.this.checkPermission(
2256 permName, packageName, callingUid, userId);
2257 }
2258 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002259 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2260 int callingUid) {
2261 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002262 }
2263 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002264 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2265 int callingUid) {
2266 return PermissionManagerService.this.getPermissionGroupInfo(
2267 groupName, flags, callingUid);
2268 }
2269 @Override
2270 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2271 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2272 }
2273 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002274 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2275 int callingUid) {
2276 return PermissionManagerService.this.getPermissionInfo(
2277 permName, packageName, flags, callingUid);
2278 }
2279 @Override
2280 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2281 int callingUid) {
2282 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2283 }
2284 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002285 public PermissionSettings getPermissionSettings() {
2286 return mSettings;
2287 }
2288 @Override
2289 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2290 return mDefaultPermissionGrantPolicy;
2291 }
2292 @Override
2293 public BasePermission getPermissionTEMP(String permName) {
2294 synchronized (PermissionManagerService.this.mLock) {
2295 return mSettings.getPermissionLocked(permName);
2296 }
2297 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002298 }
2299}