blob: af05a7987bea0054fd077471042fffac1dda4e77 [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;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070021import static android.app.AppOpsManager.MODE_ALLOWED;
22import static android.app.AppOpsManager.MODE_DEFAULT;
23import static android.app.AppOpsManager.MODE_ERRORED;
24import static android.app.AppOpsManager.MODE_FOREGROUND;
25import static android.app.AppOpsManager.MODE_IGNORED;
26import static android.app.AppOpsManager.OP_NONE;
27import static android.app.AppOpsManager.permissionToOp;
28import static android.app.AppOpsManager.permissionToOpCode;
29import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070033import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Hongwei Wangf391b552018-04-06 13:52:46 -070037import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070038import static android.os.UserHandle.getAppId;
39import static android.os.UserHandle.getUid;
Hongwei Wangf391b552018-04-06 13:52:46 -070040
Todd Kennedyc29b11a2017-10-23 15:55:59 -070041import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
42import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
43import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
44import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
45import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Todd Kennedy0eb97382017-10-03 16:57:22 -070046
47import android.Manifest;
48import android.annotation.NonNull;
49import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070050import android.annotation.UserIdInt;
51import android.app.AppOpsManager;
52import android.app.AppOpsManagerInternal;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.content.Context;
54import android.content.pm.PackageManager;
55import android.content.pm.PackageManagerInternal;
56import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070057import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070058import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070059import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070060import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070061import android.os.Binder;
62import android.os.Build;
63import android.os.Handler;
64import android.os.HandlerThread;
65import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070066import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070067import android.os.UserHandle;
68import android.os.UserManager;
69import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070070import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070071import android.os.storage.StorageManagerInternal;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070072import android.permission.PermissionManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070073import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070074import android.util.ArrayMap;
75import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070076import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070077import android.util.Log;
78import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070079import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070080
Todd Kennedyc29b11a2017-10-23 15:55:59 -070081import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070082import com.android.internal.logging.MetricsLogger;
83import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070084import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070085import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070086import com.android.server.LocalServices;
87import com.android.server.ServiceThread;
88import com.android.server.SystemConfig;
89import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070090import com.android.server.pm.PackageManagerServiceUtils;
91import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070092import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070093import com.android.server.pm.UserManagerService;
Hongwei Wangf391b552018-04-06 13:52:46 -070094import com.android.server.pm.permission.DefaultPermissionGrantPolicy
95 .DefaultPermissionGrantedCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
97import com.android.server.pm.permission.PermissionsState.PermissionState;
98
99import libcore.util.EmptyArray;
100
101import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700102import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700103import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700104import java.util.Iterator;
105import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700106import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700107import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700108import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700109
110/**
111 * Manages all permissions and handles permissions related tasks.
112 */
113public class PermissionManagerService {
114 private static final String TAG = "PackageManager";
115
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700116 /** Permission grant: not grant the permission. */
117 private static final int GRANT_DENIED = 1;
118 /** Permission grant: grant the permission as an install permission. */
119 private static final int GRANT_INSTALL = 2;
120 /** Permission grant: grant the permission as a runtime one. */
121 private static final int GRANT_RUNTIME = 3;
122 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
123 private static final int GRANT_UPGRADE = 4;
124
125 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
126 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
127 /** Empty array to avoid allocations */
128 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700129
Hongwei Wangf391b552018-04-06 13:52:46 -0700130 /** If the permission of the value is granted, so is the key */
131 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
132
133 static {
134 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
135 Manifest.permission.ACCESS_FINE_LOCATION);
136 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
137 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
138 }
139
Todd Kennedy0eb97382017-10-03 16:57:22 -0700140 /** Lock to protect internal data access */
141 private final Object mLock;
142
143 /** Internal connection to the package manager */
144 private final PackageManagerInternal mPackageManagerInt;
145
146 /** Internal connection to the user manager */
147 private final UserManagerInternal mUserManagerInt;
148
149 /** Default permission policy to provide proper behaviour out-of-the-box */
150 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
151
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700152 /**
153 * Built-in permissions. Read from system configuration files. Mapping is from
154 * UID to permission name.
155 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700156 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700157
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700158 /** Built-in group IDs given to all packages. Read from system configuration files. */
159 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700160
161 private final HandlerThread mHandlerThread;
162 private final Handler mHandler;
163 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700164 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700165
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700166 /** Internal storage for permissions and related settings */
167 @GuardedBy("mLock")
168 private final PermissionSettings mSettings;
169
170 @GuardedBy("mLock")
171 private ArraySet<String> mPrivappPermissionsViolations;
172
173 @GuardedBy("mLock")
174 private boolean mSystemReady;
175
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700176 /**
177 * For each foreground/background permission the mapping:
178 * Background permission -> foreground permissions
179 */
180 @GuardedBy("mLock")
181 private ArrayMap<String, List<String>> mBackgroundPermissions;
182
Todd Kennedy0eb97382017-10-03 16:57:22 -0700183 PermissionManagerService(Context context,
184 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
185 @NonNull Object externalLock) {
186 mContext = context;
187 mLock = externalLock;
188 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
189 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700190 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700191
192 mHandlerThread = new ServiceThread(TAG,
193 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
194 mHandlerThread.start();
195 mHandler = new Handler(mHandlerThread.getLooper());
196 Watchdog.getInstance().addThread(mHandler);
197
198 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
199 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700200 SystemConfig systemConfig = SystemConfig.getInstance();
201 mSystemPermissions = systemConfig.getSystemPermissions();
202 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700203
204 // propagate permission configuration
205 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
206 SystemConfig.getInstance().getPermissions();
207 synchronized (mLock) {
208 for (int i=0; i<permConfig.size(); i++) {
209 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
210 BasePermission bp = mSettings.getPermissionLocked(perm.name);
211 if (bp == null) {
212 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
213 mSettings.putPermissionLocked(perm.name, bp);
214 }
215 if (perm.gids != null) {
216 bp.setGids(perm.gids, perm.perUser);
217 }
218 }
219 }
220
221 LocalServices.addService(
222 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
223 }
224
225 /**
226 * Creates and returns an initialized, internal service for use by other components.
227 * <p>
228 * The object returned is identical to the one returned by the LocalServices class using:
229 * {@code LocalServices.getService(PermissionManagerInternal.class);}
230 * <p>
231 * NOTE: The external lock is temporary and should be removed. This needs to be a
232 * lock created by the permission manager itself.
233 */
234 public static PermissionManagerInternal create(Context context,
235 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
236 @NonNull Object externalLock) {
237 final PermissionManagerInternal permMgrInt =
238 LocalServices.getService(PermissionManagerInternal.class);
239 if (permMgrInt != null) {
240 return permMgrInt;
241 }
242 new PermissionManagerService(context, defaultGrantCallback, externalLock);
243 return LocalServices.getService(PermissionManagerInternal.class);
244 }
245
246 @Nullable BasePermission getPermission(String permName) {
247 synchronized (mLock) {
248 return mSettings.getPermissionLocked(permName);
249 }
250 }
251
252 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
253 if (!mUserManagerInt.exists(userId)) {
254 return PackageManager.PERMISSION_DENIED;
255 }
256
Patrick Baumann97b9b532018-04-11 14:51:30 +0000257 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
258 if (pkg != null && pkg.mExtras != null) {
259 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700260 return PackageManager.PERMISSION_DENIED;
261 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000262 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700263 final boolean instantApp = ps.getInstantApp(userId);
264 final PermissionsState permissionsState = ps.getPermissionsState();
265 if (permissionsState.hasPermission(permName, userId)) {
266 if (instantApp) {
267 synchronized (mLock) {
268 BasePermission bp = mSettings.getPermissionLocked(permName);
269 if (bp != null && bp.isInstant()) {
270 return PackageManager.PERMISSION_GRANTED;
271 }
272 }
273 } else {
274 return PackageManager.PERMISSION_GRANTED;
275 }
276 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700277 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700278 return PackageManager.PERMISSION_GRANTED;
279 }
280 }
281
282 return PackageManager.PERMISSION_DENIED;
283 }
284
Todd Kennedy3c714492017-10-27 09:12:50 -0700285 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
286 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700287 final int callingUserId = UserHandle.getUserId(callingUid);
288 final boolean isCallerInstantApp =
289 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
290 final boolean isUidInstantApp =
291 mPackageManagerInt.getInstantAppPackageName(uid) != null;
292 final int userId = UserHandle.getUserId(uid);
293 if (!mUserManagerInt.exists(userId)) {
294 return PackageManager.PERMISSION_DENIED;
295 }
296
Todd Kennedy3c714492017-10-27 09:12:50 -0700297 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700298 if (pkg.mSharedUserId != null) {
299 if (isCallerInstantApp) {
300 return PackageManager.PERMISSION_DENIED;
301 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700302 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
303 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700304 }
305 final PermissionsState permissionsState =
306 ((PackageSetting) pkg.mExtras).getPermissionsState();
307 if (permissionsState.hasPermission(permName, userId)) {
308 if (isUidInstantApp) {
309 if (mSettings.isPermissionInstant(permName)) {
310 return PackageManager.PERMISSION_GRANTED;
311 }
312 } else {
313 return PackageManager.PERMISSION_GRANTED;
314 }
315 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700316 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700317 return PackageManager.PERMISSION_GRANTED;
318 }
319 } else {
320 ArraySet<String> perms = mSystemPermissions.get(uid);
321 if (perms != null) {
322 if (perms.contains(permName)) {
323 return PackageManager.PERMISSION_GRANTED;
324 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700325 if (FULLER_PERMISSION_MAP.containsKey(permName)
326 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700327 return PackageManager.PERMISSION_GRANTED;
328 }
329 }
330 }
331 return PackageManager.PERMISSION_DENIED;
332 }
333
Hongwei Wangf391b552018-04-06 13:52:46 -0700334 /**
335 * Returns {@code true} if the permission can be implied from another granted permission.
336 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
337 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
338 * it access to any implied permissions.
339 */
340 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
341 String permName, int userId) {
342 return FULLER_PERMISSION_MAP.containsKey(permName)
343 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
344 }
345
Todd Kennedy460f28c2017-10-06 13:46:22 -0700346 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
347 int callingUid) {
348 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
349 return null;
350 }
351 synchronized (mLock) {
352 return PackageParser.generatePermissionGroupInfo(
353 mSettings.mPermissionGroups.get(groupName), flags);
354 }
355 }
356
357 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
358 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
359 return null;
360 }
361 synchronized (mLock) {
362 final int N = mSettings.mPermissionGroups.size();
363 final ArrayList<PermissionGroupInfo> out
364 = new ArrayList<PermissionGroupInfo>(N);
365 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
366 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
367 }
368 return out;
369 }
370 }
371
372 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700373 int callingUid) {
374 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
375 return null;
376 }
377 // reader
378 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700379 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700380 if (bp == null) {
381 return null;
382 }
383 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
384 bp.getProtectionLevel(), packageName, callingUid);
385 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
386 }
387 }
388
389 private List<PermissionInfo> getPermissionInfoByGroup(
390 String groupName, int flags, int callingUid) {
391 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
392 return null;
393 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700394 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700395 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
396 return null;
397 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700398 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700399 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700400 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
401 if (pi != null) {
402 out.add(pi);
403 }
404 }
405 return out;
406 }
407 }
408
409 private int adjustPermissionProtectionFlagsLocked(
410 int protectionLevel, String packageName, int uid) {
411 // Signature permission flags area always reported
412 final int protectionLevelMasked = protectionLevel
413 & (PermissionInfo.PROTECTION_NORMAL
414 | PermissionInfo.PROTECTION_DANGEROUS
415 | PermissionInfo.PROTECTION_SIGNATURE);
416 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
417 return protectionLevel;
418 }
419 // System sees all flags.
420 final int appId = UserHandle.getAppId(uid);
421 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
422 || appId == Process.SHELL_UID) {
423 return protectionLevel;
424 }
425 // Normalize package name to handle renamed packages and static libs
426 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
427 if (pkg == null) {
428 return protectionLevel;
429 }
430 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
431 return protectionLevelMasked;
432 }
433 // Apps that target O see flags for all protection levels.
434 final PackageSetting ps = (PackageSetting) pkg.mExtras;
435 if (ps == null) {
436 return protectionLevel;
437 }
438 if (ps.getAppId() != appId) {
439 return protectionLevel;
440 }
441 return protectionLevel;
442 }
443
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700444 /**
445 * We might auto-grant permissions if any permission of the group is already granted. Hence if
446 * the group of a granted permission changes we need to revoke it to avoid having permissions of
447 * the new group auto-granted.
448 *
449 * @param newPackage The new package that was installed
450 * @param oldPackage The old package that was updated
451 * @param allPackageNames All package names
452 * @param permissionCallback Callback for permission changed
453 */
454 private void revokeRuntimePermissionsIfGroupChanged(
455 @NonNull PackageParser.Package newPackage,
456 @NonNull PackageParser.Package oldPackage,
457 @NonNull ArrayList<String> allPackageNames,
458 @NonNull PermissionCallback permissionCallback) {
459 final int numOldPackagePermissions = oldPackage.permissions.size();
460 final ArrayMap<String, String> oldPermissionNameToGroupName
461 = new ArrayMap<>(numOldPackagePermissions);
462
463 for (int i = 0; i < numOldPackagePermissions; i++) {
464 final PackageParser.Permission permission = oldPackage.permissions.get(i);
465
466 if (permission.group != null) {
467 oldPermissionNameToGroupName.put(permission.info.name,
468 permission.group.info.name);
469 }
470 }
471
472 final int numNewPackagePermissions = newPackage.permissions.size();
473 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
474 newPermissionNum++) {
475 final PackageParser.Permission newPermission =
476 newPackage.permissions.get(newPermissionNum);
477 final int newProtection = newPermission.info.getProtection();
478
479 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
480 final String permissionName = newPermission.info.name;
481 final String newPermissionGroupName =
482 newPermission.group == null ? null : newPermission.group.info.name;
483 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
484 permissionName);
485
486 if (newPermissionGroupName != null
487 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
488 final int[] userIds = mUserManagerInt.getUserIds();
489 final int numUserIds = userIds.length;
490 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
491 final int userId = userIds[userIdNum];
492
493 final int numPackages = allPackageNames.size();
494 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
495 final String packageName = allPackageNames.get(packageNum);
496
497 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
498 userId) == PackageManager.PERMISSION_GRANTED) {
499 EventLog.writeEvent(0x534e4554, "72710897",
500 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900501 "Revoking permission " + permissionName +
502 " from package " + packageName +
503 " as the group changed from " + oldPermissionGroupName +
504 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700505
506 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000507 revokeRuntimePermission(permissionName, packageName, false,
508 Process.SYSTEM_UID, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700509 } catch (IllegalArgumentException e) {
510 Slog.e(TAG, "Could not revoke " + permissionName + " from "
511 + packageName, e);
512 }
513 }
514 }
515 }
516 }
517 }
518 }
519 }
520
Todd Kennedyc8423932017-10-05 08:58:36 -0700521 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
522 final int N = pkg.permissions.size();
523 for (int i=0; i<N; i++) {
524 PackageParser.Permission p = pkg.permissions.get(i);
525
526 // Assume by default that we did not install this permission into the system.
527 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
528
Todd Kennedyc8423932017-10-05 08:58:36 -0700529 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700530 // Now that permission groups have a special meaning, we ignore permission
531 // groups for legacy apps to prevent unexpected behavior. In particular,
532 // permissions for one app being granted to someone just because they happen
533 // to be in a group defined by another app (before this had no implications).
534 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
535 p.group = mSettings.mPermissionGroups.get(p.info.group);
536 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700537 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700538 && p.info.group != null && p.group == null) {
539 Slog.i(TAG, "Permission " + p.info.name + " from package "
540 + p.info.packageName + " in an unknown group " + p.info.group);
541 }
542 }
543
Todd Kennedyc8423932017-10-05 08:58:36 -0700544 if (p.tree) {
545 final BasePermission bp = BasePermission.createOrUpdate(
546 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
547 mSettings.getAllPermissionTreesLocked(), chatty);
548 mSettings.putPermissionTreeLocked(p.info.name, bp);
549 } else {
550 final BasePermission bp = BasePermission.createOrUpdate(
551 mSettings.getPermissionLocked(p.info.name),
552 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
553 mSettings.putPermissionLocked(p.info.name, bp);
554 }
555 }
556 }
557 }
558
Todd Kennedy460f28c2017-10-06 13:46:22 -0700559 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
560 final int N = pkg.permissionGroups.size();
561 StringBuilder r = null;
562 for (int i=0; i<N; i++) {
563 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
564 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
565 final String curPackageName = (cur == null) ? null : cur.info.packageName;
566 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
567 if (cur == null || isPackageUpdate) {
568 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700569 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700570 if (r == null) {
571 r = new StringBuilder(256);
572 } else {
573 r.append(' ');
574 }
575 if (isPackageUpdate) {
576 r.append("UPD:");
577 }
578 r.append(pg.info.name);
579 }
580 } else {
581 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
582 + pg.info.packageName + " ignored: original from "
583 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700584 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700585 if (r == null) {
586 r = new StringBuilder(256);
587 } else {
588 r.append(' ');
589 }
590 r.append("DUP:");
591 r.append(pg.info.name);
592 }
593 }
594 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700595 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700596 Log.d(TAG, " Permission Groups: " + r);
597 }
598
599 }
600
Hongming Jinae750fb2018-09-27 23:00:20 +0000601 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700602 synchronized (mLock) {
603 int N = pkg.permissions.size();
604 StringBuilder r = null;
605 for (int i=0; i<N; i++) {
606 PackageParser.Permission p = pkg.permissions.get(i);
607 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
608 if (bp == null) {
609 bp = mSettings.mPermissionTrees.get(p.info.name);
610 }
611 if (bp != null && bp.isPermission(p)) {
612 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700613 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700614 if (r == null) {
615 r = new StringBuilder(256);
616 } else {
617 r.append(' ');
618 }
619 r.append(p.info.name);
620 }
621 }
622 if (p.isAppOp()) {
623 ArraySet<String> appOpPkgs =
624 mSettings.mAppOpPermissionPackages.get(p.info.name);
625 if (appOpPkgs != null) {
626 appOpPkgs.remove(pkg.packageName);
627 }
628 }
629 }
630 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700631 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700632 }
633
634 N = pkg.requestedPermissions.size();
635 r = null;
636 for (int i=0; i<N; i++) {
637 String perm = pkg.requestedPermissions.get(i);
638 if (mSettings.isPermissionAppOp(perm)) {
639 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
640 if (appOpPkgs != null) {
641 appOpPkgs.remove(pkg.packageName);
642 if (appOpPkgs.isEmpty()) {
643 mSettings.mAppOpPermissionPackages.remove(perm);
644 }
645 }
646 }
647 }
648 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700649 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700650 }
651 }
652 }
653
654 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700655 PermissionInfo info, int callingUid, PermissionCallback callback) {
656 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
657 throw new SecurityException("Instant apps can't add permissions");
658 }
659 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
660 throw new SecurityException("Label must be specified in permission");
661 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700662 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700663 final boolean added;
664 final boolean changed;
665 synchronized (mLock) {
666 BasePermission bp = mSettings.getPermissionLocked(info.name);
667 added = bp == null;
668 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
669 if (added) {
670 enforcePermissionCapLocked(info, tree);
671 bp = new BasePermission(info.name, tree.getSourcePackageName(),
672 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700673 } else if (!bp.isDynamic()) {
674 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700675 + info.name);
676 }
677 changed = bp.addToTree(fixedLevel, info, tree);
678 if (added) {
679 mSettings.putPermissionLocked(info.name, bp);
680 }
681 }
682 if (changed && callback != null) {
683 callback.onPermissionChanged();
684 }
685 return added;
686 }
687
Todd Kennedyc8423932017-10-05 08:58:36 -0700688 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700689 String permName, int callingUid, PermissionCallback callback) {
690 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
691 throw new SecurityException("Instant applications don't have access to this method");
692 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700693 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700694 synchronized (mLock) {
695 final BasePermission bp = mSettings.getPermissionLocked(permName);
696 if (bp == null) {
697 return;
698 }
699 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600700 // TODO: switch this back to SecurityException
701 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700702 + permName);
703 }
704 mSettings.removePermissionLocked(permName);
705 if (callback != null) {
706 callback.onPermissionRemoved();
707 }
708 }
709 }
710
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700711 /**
712 * Restore the permission state for a package.
713 *
714 * <ul>
715 * <li>During boot the state gets restored from the disk</li>
716 * <li>During app update the state gets restored from the last version of the app</li>
717 * </ul>
718 *
719 * <p>This restores the permission state for all users.
720 *
721 * @param pkg the package the permissions belong to
722 * @param replace if the package is getting replaced (this might change the requested
723 * permissions of this package)
724 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
725 * @param callback Result call back
726 */
727 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
728 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700729 // IMPORTANT: There are two types of permissions: install and runtime.
730 // Install time permissions are granted when the app is installed to
731 // all device users and users added in the future. Runtime permissions
732 // are granted at runtime explicitly to specific users. Normal and signature
733 // protected permissions are install time permissions. Dangerous permissions
734 // are install permissions if the app's target SDK is Lollipop MR1 or older,
735 // otherwise they are runtime permissions. This function does not manage
736 // runtime permissions except for the case an app targeting Lollipop MR1
737 // being upgraded to target a newer SDK, in which case dangerous permissions
738 // are transformed from install time to runtime ones.
739
740 final PackageSetting ps = (PackageSetting) pkg.mExtras;
741 if (ps == null) {
742 return;
743 }
744 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
745
746 final PermissionsState permissionsState = ps.getPermissionsState();
747 PermissionsState origPermissions = permissionsState;
748
749 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
750
751 boolean runtimePermissionsRevoked = false;
752 int[] updatedUserIds = EMPTY_INT_ARRAY;
753
754 boolean changedInstallPermission = false;
755
756 if (replace) {
757 ps.setInstallPermissionsFixed(false);
758 if (!ps.isSharedUser()) {
759 origPermissions = new PermissionsState(permissionsState);
760 permissionsState.reset();
761 } else {
762 // We need to know only about runtime permission changes since the
763 // calling code always writes the install permissions state but
764 // the runtime ones are written only if changed. The only cases of
765 // changed runtime permissions here are promotion of an install to
766 // runtime and revocation of a runtime from a shared user.
767 synchronized (mLock) {
768 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
769 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
770 if (!ArrayUtils.isEmpty(updatedUserIds)) {
771 runtimePermissionsRevoked = true;
772 }
773 }
774 }
775 }
776
777 permissionsState.setGlobalGids(mGlobalGids);
778
779 synchronized (mLock) {
780 final int N = pkg.requestedPermissions.size();
781 for (int i = 0; i < N; i++) {
782 final String permName = pkg.requestedPermissions.get(i);
783 final BasePermission bp = mSettings.getPermissionLocked(permName);
784 final boolean appSupportsRuntimePermissions =
785 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
786
787 if (DEBUG_INSTALL) {
788 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
789 }
790
791 if (bp == null || bp.getSourcePackageSetting() == null) {
792 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
793 if (DEBUG_PERMISSIONS) {
794 Slog.i(TAG, "Unknown permission " + permName
795 + " in package " + pkg.packageName);
796 }
797 }
798 continue;
799 }
800
801 // Limit ephemeral apps to ephemeral allowed permissions.
802 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
803 if (DEBUG_PERMISSIONS) {
804 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
805 + " for package " + pkg.packageName);
806 }
807 continue;
808 }
809
810 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
811 if (DEBUG_PERMISSIONS) {
812 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
813 + " for package " + pkg.packageName);
814 }
815 continue;
816 }
817
818 final String perm = bp.getName();
819 boolean allowedSig = false;
820 int grant = GRANT_DENIED;
821
822 // Keep track of app op permissions.
823 if (bp.isAppOp()) {
824 mSettings.addAppOpPackage(perm, pkg.packageName);
825 }
826
827 if (bp.isNormal()) {
828 // For all apps normal permissions are install time ones.
829 grant = GRANT_INSTALL;
830 } else if (bp.isRuntime()) {
831 // If a permission review is required for legacy apps we represent
832 // their permissions as always granted runtime ones since we need
833 // to keep the review required permission flag per user while an
834 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700835 if (origPermissions.hasInstallPermission(bp.getName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700836 // For legacy apps that became modern, install becomes runtime.
837 grant = GRANT_UPGRADE;
838 } else if (isLegacySystemApp) {
839 // For legacy system apps, install becomes runtime.
840 // We cannot check hasInstallPermission() for system apps since those
841 // permissions were granted implicitly and not persisted pre-M.
842 grant = GRANT_UPGRADE;
843 } else {
844 // For modern apps keep runtime permissions unchanged.
845 grant = GRANT_RUNTIME;
846 }
847 } else if (bp.isSignature()) {
848 // For all apps signature permissions are install time ones.
849 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
850 if (allowedSig) {
851 grant = GRANT_INSTALL;
852 }
853 }
854
855 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700856 Slog.i(TAG, "Considering granting permission " + perm + " to package "
857 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700858 }
859
860 if (grant != GRANT_DENIED) {
861 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
862 // If this is an existing, non-system package, then
863 // we can't add any new permissions to it.
864 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
865 // Except... if this is a permission that was added
866 // to the platform (note: need to only do this when
867 // updating the platform).
868 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
869 grant = GRANT_DENIED;
870 }
871 }
872 }
873
874 switch (grant) {
875 case GRANT_INSTALL: {
876 // Revoke this as runtime permission to handle the case of
877 // a runtime permission being downgraded to an install one.
878 // Also in permission review mode we keep dangerous permissions
879 // for legacy apps
880 for (int userId : UserManagerService.getInstance().getUserIds()) {
881 if (origPermissions.getRuntimePermissionState(
882 perm, userId) != null) {
883 // Revoke the runtime permission and clear the flags.
884 origPermissions.revokeRuntimePermission(bp, userId);
885 origPermissions.updatePermissionFlags(bp, userId,
886 PackageManager.MASK_PERMISSION_FLAGS, 0);
887 // If we revoked a permission permission, we have to write.
888 updatedUserIds = ArrayUtils.appendInt(
889 updatedUserIds, userId);
890 }
891 }
892 // Grant an install permission.
893 if (permissionsState.grantInstallPermission(bp) !=
894 PermissionsState.PERMISSION_OPERATION_FAILURE) {
895 changedInstallPermission = true;
896 }
897 } break;
898
899 case GRANT_RUNTIME: {
900 // Grant previously granted runtime permissions.
901 for (int userId : UserManagerService.getInstance().getUserIds()) {
902 final PermissionState permissionState = origPermissions
903 .getRuntimePermissionState(perm, userId);
904 int flags = permissionState != null
905 ? permissionState.getFlags() : 0;
906 if (origPermissions.hasRuntimePermission(perm, userId)) {
907 // Don't propagate the permission in a permission review
908 // mode if the former was revoked, i.e. marked to not
909 // propagate on upgrade. Note that in a permission review
910 // mode install permissions are represented as constantly
911 // granted runtime ones since we need to keep a per user
912 // state associated with the permission. Also the revoke
913 // on upgrade flag is no longer applicable and is reset.
914 final boolean revokeOnUpgrade = (flags & PackageManager
915 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
916 if (revokeOnUpgrade) {
917 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
918 // Since we changed the flags, we have to write.
919 updatedUserIds = ArrayUtils.appendInt(
920 updatedUserIds, userId);
921 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700922 if (!revokeOnUpgrade) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700923 if (permissionsState.grantRuntimePermission(bp, userId) ==
924 PermissionsState.PERMISSION_OPERATION_FAILURE) {
925 // If we cannot put the permission as it was,
926 // we have to write.
927 updatedUserIds = ArrayUtils.appendInt(
928 updatedUserIds, userId);
929 }
930 }
931
932 // If the app supports runtime permissions no need for a review.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700933 if (appSupportsRuntimePermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700934 && (flags & PackageManager
935 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
936 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
937 // Since we changed the flags, we have to write.
938 updatedUserIds = ArrayUtils.appendInt(
939 updatedUserIds, userId);
940 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700941 } else if (!appSupportsRuntimePermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700942 // For legacy apps that need a permission review, every new
943 // runtime permission is granted but it is pending a review.
944 // We also need to review only platform defined runtime
945 // permissions as these are the only ones the platform knows
946 // how to disable the API to simulate revocation as legacy
947 // apps don't expect to run with revoked permissions.
948 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
949 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
950 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
951 // We changed the flags, hence have to write.
952 updatedUserIds = ArrayUtils.appendInt(
953 updatedUserIds, userId);
954 }
955 }
956 if (permissionsState.grantRuntimePermission(bp, userId)
957 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
958 // We changed the permission, hence have to write.
959 updatedUserIds = ArrayUtils.appendInt(
960 updatedUserIds, userId);
961 }
962 }
963 // Propagate the permission flags.
964 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
965 }
966 } break;
967
968 case GRANT_UPGRADE: {
969 // Grant runtime permissions for a previously held install permission.
970 final PermissionState permissionState = origPermissions
971 .getInstallPermissionState(perm);
972 final int flags =
973 (permissionState != null) ? permissionState.getFlags() : 0;
974
975 if (origPermissions.revokeInstallPermission(bp)
976 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
977 // We will be transferring the permission flags, so clear them.
978 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
979 PackageManager.MASK_PERMISSION_FLAGS, 0);
980 changedInstallPermission = true;
981 }
982
983 // If the permission is not to be promoted to runtime we ignore it and
984 // also its other flags as they are not applicable to install permissions.
985 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
986 for (int userId : currentUserIds) {
987 if (permissionsState.grantRuntimePermission(bp, userId) !=
988 PermissionsState.PERMISSION_OPERATION_FAILURE) {
989 // Transfer the permission flags.
990 permissionsState.updatePermissionFlags(bp, userId,
991 flags, flags);
992 // If we granted the permission, we have to write.
993 updatedUserIds = ArrayUtils.appendInt(
994 updatedUserIds, userId);
995 }
996 }
997 }
998 } break;
999
1000 default: {
1001 if (packageOfInterest == null
1002 || packageOfInterest.equals(pkg.packageName)) {
1003 if (DEBUG_PERMISSIONS) {
1004 Slog.i(TAG, "Not granting permission " + perm
1005 + " to package " + pkg.packageName
1006 + " because it was previously installed without");
1007 }
1008 }
1009 } break;
1010 }
1011 } else {
1012 if (permissionsState.revokeInstallPermission(bp) !=
1013 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1014 // Also drop the permission flags.
1015 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1016 PackageManager.MASK_PERMISSION_FLAGS, 0);
1017 changedInstallPermission = true;
1018 Slog.i(TAG, "Un-granting permission " + perm
1019 + " from package " + pkg.packageName
1020 + " (protectionLevel=" + bp.getProtectionLevel()
1021 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1022 + ")");
1023 } else if (bp.isAppOp()) {
1024 // Don't print warning for app op permissions, since it is fine for them
1025 // not to be granted, there is a UI for the user to decide.
1026 if (DEBUG_PERMISSIONS
1027 && (packageOfInterest == null
1028 || packageOfInterest.equals(pkg.packageName))) {
1029 Slog.i(TAG, "Not granting permission " + perm
1030 + " to package " + pkg.packageName
1031 + " (protectionLevel=" + bp.getProtectionLevel()
1032 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1033 + ")");
1034 }
1035 }
1036 }
1037 }
1038
1039 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1040 !ps.isSystem() || ps.isUpdatedSystem()) {
1041 // This is the first that we have heard about this package, so the
1042 // permissions we have now selected are fixed until explicitly
1043 // changed.
1044 ps.setInstallPermissionsFixed(true);
1045 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001046
1047 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1048 updatedUserIds);
1049 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1050 permissionsState, pkg, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001051 }
1052
1053 // Persist the runtime permissions state for users with changes. If permissions
1054 // were revoked because no app in the shared user declares them we have to
1055 // write synchronously to avoid losing runtime permissions state.
1056 if (callback != null) {
1057 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1058 }
1059 }
1060
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001061 /**
1062 * Set app op for a app-op related to a permission.
1063 *
1064 * @param permission The permission the app-op belongs to
1065 * @param pkg The package the permission belongs to
1066 * @param userId The user to be changed
1067 * @param mode The new mode to set
1068 */
1069 private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
1070 @UserIdInt int userId, int mode) {
1071 AppOpsManagerInternal appOpsInternal = LocalServices.getService(
1072 AppOpsManagerInternal.class);
1073
1074 appOpsInternal.setMode(permissionToOpCode(permission),
1075 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkg.packageName, mode,
1076 (pkg.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0);
1077 }
1078
1079 /**
1080 * Revoke permissions that are not implicit anymore and that have
1081 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1082 *
1083 * @param ps The state of the permissions of the package
1084 * @param pkg The package that is currently looked at
1085 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1086 * for a user is changed.
1087 *
1088 * @return The updated value of the {@code updatedUserIds} parameter
1089 */
1090 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1091 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1092 @NonNull int[] updatedUserIds) {
1093 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1094
1095 String pkgName = pkg.packageName;
1096
1097 int[] users = UserManagerService.getInstance().getUserIds();
1098 int numUsers = users.length;
1099 for (int i = 0; i < numUsers; i++) {
1100 int userId = users[i];
1101
1102 for (String permission : ps.getPermissions(userId)) {
1103 if (!pkg.implicitPermissions.contains(permission)) {
1104 if (!ps.hasInstallPermission(permission)) {
1105 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1106
1107 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1108 BasePermission bp = mSettings.getPermissionLocked(permission);
1109
1110 ps.updatePermissionFlags(bp, userId,
1111 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
1112 | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_USER_SET,
1113 0);
1114 updatedUserIds = ArrayUtils.appendInt(updatedUserIds,
1115 userId);
1116
1117 if ((flags & (FLAG_PERMISSION_GRANTED_BY_DEFAULT
1118 | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED))
1119 == 0) {
1120 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1121 if (permissionToOpCode(permission) != OP_NONE) {
1122 setAppOpMode(permission, pkg, userId, MODE_IGNORED);
1123
1124 if (DEBUG_PERMISSIONS) {
1125 Slog.i(TAG, "Revoking app-op "
1126 + permissionToOp(permission) + " for " + pkgName
1127 + " as it is now requested");
1128 }
1129 }
1130 } else {
1131 int revokeOpSuccess = ps.revokeRuntimePermission(bp, userId);
1132 if (revokeOpSuccess
1133 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
1134
1135 if (DEBUG_PERMISSIONS) {
1136 Slog.i(TAG, "Revoking runtime permission " + permission
1137 + " for " + pkgName
1138 + " as it is now requested");
1139 }
1140 }
1141 }
1142
1143 List<String> fgPerms = mBackgroundPermissions.get(permission);
1144 if (fgPerms != null) {
1145 int numFgPerms = fgPerms.size();
1146 for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
1147 String fgPerm = fgPerms.get(fgPermNum);
1148
1149 int mode = appOpsManager.unsafeCheckOpRaw(
1150 permissionToOp(fgPerm),
1151 getUid(userId, getAppId(pkg.applicationInfo.uid)),
1152 pkgName);
1153
1154 if (mode == MODE_ALLOWED) {
1155 setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
1156 }
1157 }
1158 }
1159 }
1160 }
1161 }
1162 }
1163 }
1164 }
1165
1166 return updatedUserIds;
1167 }
1168
1169 /**
1170 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1171 *
1172 * <p>A single new permission can be split off from several source permissions. In this case
1173 * the most leniant state is inherited.
1174 *
1175 * <p>Warning: This does not handle foreground / background permissions
1176 *
1177 * @param sourcePerms The permissions to inherit from
1178 * @param newPerm The permission to inherit to
1179 * @param ps The permission state of the package
1180 * @param pkg The package requesting the permissions
1181 * @param userId The user the permission belongs to
1182 */
1183 private void inheritPermissionStateToNewImplicitPermissionLocked(
1184 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1185 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1186 @UserIdInt int userId) {
1187 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1188 String pkgName = pkg.packageName;
1189
1190 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1191 if (permissionToOp(newPerm) != null) {
1192 int mostLenientSourceMode = MODE_ERRORED;
1193
1194 // Find most lenient source permission state.
1195 int numSourcePerms = sourcePerms.size();
1196 for (int i = 0; i < numSourcePerms; i++) {
1197 String sourcePerm = sourcePerms.valueAt(i);
1198
1199 if (ps.hasRuntimePermission(sourcePerm, userId)) {
1200 String sourceOp = permissionToOp(sourcePerm);
1201
1202 if (sourceOp != null) {
1203 int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
1204 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
1205
1206 if (mode == MODE_FOREGROUND) {
1207 throw new IllegalArgumentException("split permission" + sourcePerm
1208 + " has app-op state " + AppOpsManager.MODE_NAMES[mode]);
1209 }
1210
1211 // Leniency order: allowed > ignored > default
1212 if (mode == MODE_ALLOWED) {
1213 mostLenientSourceMode = MODE_ALLOWED;
1214 break;
1215 } else if (mode == MODE_IGNORED) {
1216 mostLenientSourceMode = MODE_IGNORED;
1217 } else if (mode == MODE_DEFAULT
1218 && mostLenientSourceMode != MODE_IGNORED) {
1219 mostLenientSourceMode = MODE_DEFAULT;
1220 }
1221 }
1222 }
1223 }
1224
1225 if (mostLenientSourceMode != MODE_ERRORED) {
1226 if (DEBUG_PERMISSIONS) {
1227 Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
1228 + " from " + sourcePerms + " for " + pkgName);
1229 }
1230
1231 setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
1232 }
1233 }
1234 } else {
1235 boolean isGranted = false;
1236
1237 int numSourcePerm = sourcePerms.size();
1238 for (int i = 0; i < numSourcePerm; i++) {
1239 String sourcePerm = sourcePerms.valueAt(i);
1240 if (ps.hasRuntimePermission(sourcePerm, userId)
1241 && ps.getRuntimePermissionState(sourcePerm, userId).isGranted()) {
1242 isGranted = true;
1243 break;
1244 }
1245 }
1246
1247 if (isGranted) {
1248 if (DEBUG_PERMISSIONS) {
1249 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1250 + " for " + pkgName);
1251 }
1252
1253 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1254 }
1255 }
1256 }
1257
1258 /**
1259 * Set the state of a implicit permission that is seen for the first time.
1260 *
1261 * @param origPs The permission state of the package before the split
1262 * @param ps The new permission state
1263 * @param pkg The package the permission belongs to
1264 * @param updatedUserIds List of users for which the permission state has already been changed
1265 *
1266 * @return List of users for which the permission state has been changed
1267 */
1268 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1269 @NonNull PermissionsState origPs,
1270 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1271 @NonNull int[] updatedUserIds) {
1272 String pkgName = pkg.packageName;
1273 ArraySet<String> newImplicitPermissions = new ArraySet<>();
1274
1275 int numRequestedPerms = pkg.requestedPermissions.size();
1276 for (int i = 0; i < numRequestedPerms; i++) {
1277 BasePermission bp = mSettings.getPermissionLocked(pkg.requestedPermissions.get(i));
1278 if (bp != null) {
1279 String perm = bp.getName();
1280
1281 if (!origPs.hasRequestedPermission(perm) && pkg.implicitPermissions.contains(
1282 perm)) {
1283 newImplicitPermissions.add(perm);
1284
1285 if (DEBUG_PERMISSIONS) {
1286 Slog.i(TAG, perm + " is newly added for " + pkgName);
1287 }
1288 }
1289 }
1290 }
1291
1292 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1293
1294 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1295 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1296 PermissionManager.SplitPermissionInfo spi =
1297 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1298
1299 List<String> newPerms = spi.getNewPermissions();
1300 int numNewPerms = newPerms.size();
1301 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1302 String newPerm = newPerms.get(newPermNum);
1303
1304 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1305 if (splitPerms == null) {
1306 splitPerms = new ArraySet<>();
1307 newToSplitPerms.put(newPerm, splitPerms);
1308 }
1309
1310 splitPerms.add(spi.getSplitPermission());
1311 }
1312 }
1313
1314 int numNewImplicitPerms = newImplicitPermissions.size();
1315 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1316 newImplicitPermNum++) {
1317 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1318 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1319
1320 if (sourcePerms != null) {
1321 if (!ps.hasInstallPermission(newPerm)) {
1322 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1323
1324 int[] users = UserManagerService.getInstance().getUserIds();
1325 int numUsers = users.length;
1326 for (int userNum = 0; userNum < numUsers; userNum++) {
1327 int userId = users[userNum];
1328
1329 ps.updatePermissionFlags(bp, userId,
1330 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1331 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1332 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1333
1334 if (!origPs.hasRequestedPermission(sourcePerms)) {
1335 // Both permissions are new, do nothing
1336 if (DEBUG_PERMISSIONS) {
1337 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1338 + " for " + pkgName + " as split permission is also new");
1339 }
1340
1341 break;
1342 } else {
1343 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1344 newPerm, ps, pkg, userId);
1345 }
1346 }
1347 }
1348 }
1349 }
1350
1351 return updatedUserIds;
1352 }
1353
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001354 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1355 boolean allowed = false;
1356 final int NP = PackageParser.NEW_PERMISSIONS.length;
1357 for (int ip=0; ip<NP; ip++) {
1358 final PackageParser.NewPermissionInfo npi
1359 = PackageParser.NEW_PERMISSIONS[ip];
1360 if (npi.name.equals(perm)
1361 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1362 allowed = true;
1363 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1364 + pkg.packageName);
1365 break;
1366 }
1367 }
1368 return allowed;
1369 }
1370
1371 /**
1372 * Determines whether a package is whitelisted for a particular privapp permission.
1373 *
1374 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1375 *
1376 * <p>This handles parent/child apps.
1377 */
1378 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001379 ArraySet<String> wlPermissions = null;
1380 if (pkg.isVendor()) {
1381 wlPermissions =
1382 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1383 } else if (pkg.isProduct()) {
1384 wlPermissions =
1385 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001386 } else if (pkg.isProductServices()) {
1387 wlPermissions =
1388 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1389 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001390 } else {
1391 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1392 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001393 // Let's check if this package is whitelisted...
1394 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1395 // If it's not, we'll also tail-recurse to the parent.
1396 return whitelisted ||
1397 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1398 }
1399
1400 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1401 BasePermission bp, PermissionsState origPermissions) {
1402 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001403 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1404 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001405 boolean privappPermissionsDisable =
1406 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1407 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1408 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1409 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1410 && !platformPackage && platformPermission) {
1411 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001412 // Only report violations for apps on system image
1413 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1414 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001415 ArraySet<String> deniedPermissions = null;
1416 if (pkg.isVendor()) {
1417 deniedPermissions = SystemConfig.getInstance()
1418 .getVendorPrivAppDenyPermissions(pkg.packageName);
1419 } else if (pkg.isProduct()) {
1420 deniedPermissions = SystemConfig.getInstance()
1421 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001422 } else if (pkg.isProductServices()) {
1423 deniedPermissions = SystemConfig.getInstance()
1424 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001425 } else {
1426 deniedPermissions = SystemConfig.getInstance()
1427 .getPrivAppDenyPermissions(pkg.packageName);
1428 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001429 final boolean permissionViolation =
1430 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001431 if (permissionViolation) {
1432 Slog.w(TAG, "Privileged permission " + perm + " for package "
1433 + pkg.packageName + " - not in privapp-permissions whitelist");
1434
1435 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1436 if (mPrivappPermissionsViolations == null) {
1437 mPrivappPermissionsViolations = new ArraySet<>();
1438 }
1439 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001440 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001441 } else {
1442 return false;
1443 }
1444 }
1445 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1446 return false;
1447 }
1448 }
1449 }
1450 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1451 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1452 final PackageParser.Package systemPackage =
1453 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001454
1455 // check if the package is allow to use this signature permission. A package is allowed to
1456 // use a signature permission if:
1457 // - it has the same set of signing certificates as the source package
1458 // - or its signing certificate was rotated from the source package's certificate
1459 // - or its signing certificate is a previous signing certificate of the defining
1460 // package, and the defining package still trusts the old certificate for permissions
1461 // - or it shares the above relationships with the system package
1462 boolean allowed =
1463 pkg.mSigningDetails.hasAncestorOrSelf(
1464 bp.getSourcePackageSetting().getSigningDetails())
1465 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1466 pkg.mSigningDetails,
1467 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1468 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1469 || systemPackage.mSigningDetails.checkCapability(
1470 pkg.mSigningDetails,
1471 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001472 if (!allowed && (privilegedPermission || oemPermission)) {
1473 if (pkg.isSystem()) {
1474 // For updated system applications, a privileged/oem permission
1475 // is granted only if it had been defined by the original application.
1476 if (pkg.isUpdatedSystemApp()) {
1477 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001478 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001479 final PackageSetting disabledPs =
1480 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1481 if (disabledPs != null
1482 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1483 // If the original was granted this permission, we take
1484 // that grant decision as read and propagate it to the
1485 // update.
1486 if ((privilegedPermission && disabledPs.isPrivileged())
1487 || (oemPermission && disabledPs.isOem()
1488 && canGrantOemPermission(disabledPs, perm))) {
1489 allowed = true;
1490 }
1491 } else {
1492 // The system apk may have been updated with an older
1493 // version of the one on the data partition, but which
1494 // granted a new system permission that it didn't have
1495 // before. In this case we do want to allow the app to
1496 // now get the new permission if the ancestral apk is
1497 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001498 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001499 && isPackageRequestingPermission(disabledPkg, perm)
1500 && ((privilegedPermission && disabledPs.isPrivileged())
1501 || (oemPermission && disabledPs.isOem()
1502 && canGrantOemPermission(disabledPs, perm)))) {
1503 allowed = true;
1504 }
1505 // Also if a privileged parent package on the system image or any of
1506 // its children requested a privileged/oem permission, the updated child
1507 // packages can also get the permission.
1508 if (pkg.parentPackage != null) {
1509 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001510 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001511 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1512 ? (PackageSetting) disabledParentPkg.mExtras : null;
1513 if (disabledParentPkg != null
1514 && ((privilegedPermission && disabledParentPs.isPrivileged())
1515 || (oemPermission && disabledParentPs.isOem()))) {
1516 if (isPackageRequestingPermission(disabledParentPkg, perm)
1517 && canGrantOemPermission(disabledParentPs, perm)) {
1518 allowed = true;
1519 } else if (disabledParentPkg.childPackages != null) {
1520 for (PackageParser.Package disabledChildPkg
1521 : disabledParentPkg.childPackages) {
1522 final PackageSetting disabledChildPs =
1523 (disabledChildPkg != null)
1524 ? (PackageSetting) disabledChildPkg.mExtras
1525 : null;
1526 if (isPackageRequestingPermission(disabledChildPkg, perm)
1527 && canGrantOemPermission(
1528 disabledChildPs, perm)) {
1529 allowed = true;
1530 break;
1531 }
1532 }
1533 }
1534 }
1535 }
1536 }
1537 } else {
1538 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1539 allowed = (privilegedPermission && pkg.isPrivileged())
1540 || (oemPermission && pkg.isOem()
1541 && canGrantOemPermission(ps, perm));
1542 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001543 // In any case, don't grant a privileged permission to privileged vendor apps, if
1544 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1545 // flag.
1546 if (allowed && privilegedPermission &&
1547 !vendorPrivilegedPermission && pkg.isVendor()) {
1548 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1549 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1550 allowed = false;
1551 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001552 }
1553 }
1554 if (!allowed) {
1555 if (!allowed
1556 && bp.isPre23()
1557 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1558 // If this was a previously normal/dangerous permission that got moved
1559 // to a system permission as part of the runtime permission redesign, then
1560 // we still want to blindly grant it to old apps.
1561 allowed = true;
1562 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001563 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1564 // need a separate flag anymore. Hence we need to check which
1565 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001566 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001567 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1568 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1569 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1570 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1571 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001572 // If this permission is to be granted to the system installer and
1573 // this app is an installer, then it gets the permission.
1574 allowed = true;
1575 }
1576 if (!allowed && bp.isVerifier()
1577 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1578 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1579 // If this permission is to be granted to the system verifier and
1580 // this app is a verifier, then it gets the permission.
1581 allowed = true;
1582 }
1583 if (!allowed && bp.isPreInstalled()
1584 && pkg.isSystem()) {
1585 // Any pre-installed system app is allowed to get this permission.
1586 allowed = true;
1587 }
1588 if (!allowed && bp.isDevelopment()) {
1589 // For development permissions, a development permission
1590 // is granted only if it was already granted.
1591 allowed = origPermissions.hasInstallPermission(perm);
1592 }
1593 if (!allowed && bp.isSetup()
1594 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1595 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1596 // If this permission is to be granted to the system setup wizard and
1597 // this app is a setup wizard, then it gets the permission.
1598 allowed = true;
1599 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001600 if (!allowed && bp.isSystemTextClassifier()
1601 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1602 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1603 UserHandle.USER_SYSTEM))) {
1604 // Special permissions for the system default text classifier.
1605 allowed = true;
1606 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001607 }
1608 return allowed;
1609 }
1610
1611 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1612 if (!ps.isOem()) {
1613 return false;
1614 }
1615 // all oem permissions must explicitly be granted or denied
1616 final Boolean granted =
1617 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1618 if (granted == null) {
1619 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1620 + ps.name + " must be explicitly declared granted or not");
1621 }
1622 return Boolean.TRUE == granted;
1623 }
1624
1625 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001626 // Permission review applies only to apps not supporting the new permission model.
1627 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1628 return false;
1629 }
1630
1631 // Legacy apps have the permission and get user consent on launch.
1632 if (pkg == null || pkg.mExtras == null) {
1633 return false;
1634 }
1635 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1636 final PermissionsState permissionsState = ps.getPermissionsState();
1637 return permissionsState.isPermissionReviewRequired(userId);
1638 }
1639
1640 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1641 final int permCount = pkg.requestedPermissions.size();
1642 for (int j = 0; j < permCount; j++) {
1643 String requestedPermission = pkg.requestedPermissions.get(j);
1644 if (permission.equals(requestedPermission)) {
1645 return true;
1646 }
1647 }
1648 return false;
1649 }
1650
Andreas Gampea36dc622018-02-05 17:19:22 -08001651 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001652 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1653 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1654 if (pkg.parentPackage == null) {
1655 return;
1656 }
1657 if (pkg.requestedPermissions == null) {
1658 return;
1659 }
1660 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001661 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001662 if (disabledPkg == null || disabledPkg.mExtras == null) {
1663 return;
1664 }
1665 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1666 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1667 return;
1668 }
1669 final int permCount = pkg.requestedPermissions.size();
1670 for (int i = 0; i < permCount; i++) {
1671 String permission = pkg.requestedPermissions.get(i);
1672 BasePermission bp = mSettings.getPermissionLocked(permission);
1673 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1674 continue;
1675 }
1676 for (int userId : mUserManagerInt.getUserIds()) {
1677 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1678 grantRuntimePermission(
1679 permission, pkg.packageName, false, callingUid, userId, callback);
1680 }
1681 }
1682 }
1683 }
1684
1685 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1686 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1687 for (int userId : userIds) {
1688 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1689 callback);
1690 }
1691 }
1692
1693 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1694 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1695 PackageSetting ps = (PackageSetting) pkg.mExtras;
1696 if (ps == null) {
1697 return;
1698 }
1699
1700 PermissionsState permissionsState = ps.getPermissionsState();
1701
1702 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1703 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1704
1705 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1706 >= Build.VERSION_CODES.M;
1707
1708 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1709
1710 for (String permission : pkg.requestedPermissions) {
1711 final BasePermission bp;
1712 synchronized (mLock) {
1713 bp = mSettings.getPermissionLocked(permission);
1714 }
1715 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1716 && (!instantApp || bp.isInstant())
1717 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1718 && (grantedPermissions == null
1719 || ArrayUtils.contains(grantedPermissions, permission))) {
1720 final int flags = permissionsState.getPermissionFlags(permission, userId);
1721 if (supportsRuntimePermissions) {
1722 // Installer cannot change immutable permissions.
1723 if ((flags & immutableFlags) == 0) {
1724 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1725 userId, callback);
1726 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001727 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001728 // In permission review mode we clear the review flag when we
1729 // are asked to install the app with all permissions granted.
1730 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1731 updatePermissionFlags(permission, pkg.packageName,
1732 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1733 userId, callback);
1734 }
1735 }
1736 }
1737 }
1738 }
1739
1740 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1741 int callingUid, final int userId, PermissionCallback callback) {
1742 if (!mUserManagerInt.exists(userId)) {
1743 Log.e(TAG, "No such user:" + userId);
1744 return;
1745 }
1746
1747 mContext.enforceCallingOrSelfPermission(
1748 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1749 "grantRuntimePermission");
1750
1751 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001752 true, // requireFullPermission
1753 true, // checkShell
1754 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001755 "grantRuntimePermission");
1756
1757 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1758 if (pkg == null || pkg.mExtras == null) {
1759 throw new IllegalArgumentException("Unknown package: " + packageName);
1760 }
1761 final BasePermission bp;
1762 synchronized(mLock) {
1763 bp = mSettings.getPermissionLocked(permName);
1764 }
1765 if (bp == null) {
1766 throw new IllegalArgumentException("Unknown permission: " + permName);
1767 }
1768 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1769 throw new IllegalArgumentException("Unknown package: " + packageName);
1770 }
1771
1772 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1773
1774 // If a permission review is required for legacy apps we represent
1775 // their permissions as always granted runtime ones since we need
1776 // to keep the review required permission flag per user while an
1777 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001778 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001779 && bp.isRuntime()) {
1780 return;
1781 }
1782
1783 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1784
1785 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1786 final PermissionsState permissionsState = ps.getPermissionsState();
1787
1788 final int flags = permissionsState.getPermissionFlags(permName, userId);
1789 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1790 throw new SecurityException("Cannot grant system fixed permission "
1791 + permName + " for package " + packageName);
1792 }
1793 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1794 throw new SecurityException("Cannot grant policy fixed permission "
1795 + permName + " for package " + packageName);
1796 }
1797
1798 if (bp.isDevelopment()) {
1799 // Development permissions must be handled specially, since they are not
1800 // normal runtime permissions. For now they apply to all users.
1801 if (permissionsState.grantInstallPermission(bp) !=
1802 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1803 if (callback != null) {
1804 callback.onInstallPermissionGranted();
1805 }
1806 }
1807 return;
1808 }
1809
1810 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1811 throw new SecurityException("Cannot grant non-ephemeral permission"
1812 + permName + " for package " + packageName);
1813 }
1814
1815 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1816 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1817 return;
1818 }
1819
1820 final int result = permissionsState.grantRuntimePermission(bp, userId);
1821 switch (result) {
1822 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1823 return;
1824 }
1825
1826 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1827 if (callback != null) {
1828 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1829 }
1830 }
1831 break;
1832 }
1833
1834 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001835 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001836 }
1837
1838 if (callback != null) {
1839 callback.onPermissionGranted(uid, userId);
1840 }
1841
1842 // Only need to do this if user is initialized. Otherwise it's a new user
1843 // and there are no processes running as the user yet and there's no need
1844 // to make an expensive call to remount processes for the changed permissions.
1845 if (READ_EXTERNAL_STORAGE.equals(permName)
1846 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1847 final long token = Binder.clearCallingIdentity();
1848 try {
1849 if (mUserManagerInt.isUserInitialized(userId)) {
1850 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1851 StorageManagerInternal.class);
1852 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1853 }
1854 } finally {
1855 Binder.restoreCallingIdentity(token);
1856 }
1857 }
1858
1859 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001860
1861 private void revokeRuntimePermission(String permName, String packageName,
1862 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001863 if (!mUserManagerInt.exists(userId)) {
1864 Log.e(TAG, "No such user:" + userId);
1865 return;
1866 }
1867
1868 mContext.enforceCallingOrSelfPermission(
1869 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1870 "revokeRuntimePermission");
1871
1872 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001873 true, // requireFullPermission
1874 true, // checkShell
1875 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001876 "revokeRuntimePermission");
1877
1878 final int appId;
1879
1880 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1881 if (pkg == null || pkg.mExtras == null) {
1882 throw new IllegalArgumentException("Unknown package: " + packageName);
1883 }
1884 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1885 throw new IllegalArgumentException("Unknown package: " + packageName);
1886 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001887 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001888 if (bp == null) {
1889 throw new IllegalArgumentException("Unknown permission: " + permName);
1890 }
1891
1892 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1893
1894 // If a permission review is required for legacy apps we represent
1895 // their permissions as always granted runtime ones since we need
1896 // to keep the review required permission flag per user while an
1897 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001898 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001899 && bp.isRuntime()) {
1900 return;
1901 }
1902
1903 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1904 final PermissionsState permissionsState = ps.getPermissionsState();
1905
1906 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07001907 // Only the system may revoke SYSTEM_FIXED permissions.
1908 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1909 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1910 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07001911 + permName + " for package " + packageName);
1912 }
1913 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1914 throw new SecurityException("Cannot revoke policy fixed permission "
1915 + permName + " for package " + packageName);
1916 }
1917
1918 if (bp.isDevelopment()) {
1919 // Development permissions must be handled specially, since they are not
1920 // normal runtime permissions. For now they apply to all users.
1921 if (permissionsState.revokeInstallPermission(bp) !=
1922 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1923 if (callback != null) {
1924 callback.onInstallPermissionRevoked();
1925 }
1926 }
1927 return;
1928 }
1929
1930 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1931 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1932 return;
1933 }
1934
1935 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001936 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001937 }
1938
1939 if (callback != null) {
1940 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1941 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1942 }
1943 }
1944
Andreas Gampea36dc622018-02-05 17:19:22 -08001945 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001946 private int[] revokeUnusedSharedUserPermissionsLocked(
1947 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001948 // Collect all used permissions in the UID
1949 final ArraySet<String> usedPermissions = new ArraySet<>();
1950 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1951 if (pkgList == null || pkgList.size() == 0) {
1952 return EmptyArray.INT;
1953 }
1954 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07001955 if (pkg.requestedPermissions == null) {
1956 continue;
1957 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07001958 final int requestedPermCount = pkg.requestedPermissions.size();
1959 for (int j = 0; j < requestedPermCount; j++) {
1960 String permission = pkg.requestedPermissions.get(j);
1961 BasePermission bp = mSettings.getPermissionLocked(permission);
1962 if (bp != null) {
1963 usedPermissions.add(permission);
1964 }
1965 }
1966 }
1967
1968 PermissionsState permissionsState = suSetting.getPermissionsState();
1969 // Prune install permissions
1970 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1971 final int installPermCount = installPermStates.size();
1972 for (int i = installPermCount - 1; i >= 0; i--) {
1973 PermissionState permissionState = installPermStates.get(i);
1974 if (!usedPermissions.contains(permissionState.getName())) {
1975 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1976 if (bp != null) {
1977 permissionsState.revokeInstallPermission(bp);
1978 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1979 PackageManager.MASK_PERMISSION_FLAGS, 0);
1980 }
1981 }
1982 }
1983
1984 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1985
1986 // Prune runtime permissions
1987 for (int userId : allUserIds) {
1988 List<PermissionState> runtimePermStates = permissionsState
1989 .getRuntimePermissionStates(userId);
1990 final int runtimePermCount = runtimePermStates.size();
1991 for (int i = runtimePermCount - 1; i >= 0; i--) {
1992 PermissionState permissionState = runtimePermStates.get(i);
1993 if (!usedPermissions.contains(permissionState.getName())) {
1994 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1995 if (bp != null) {
1996 permissionsState.revokeRuntimePermission(bp, userId);
1997 permissionsState.updatePermissionFlags(bp, userId,
1998 PackageManager.MASK_PERMISSION_FLAGS, 0);
1999 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2000 runtimePermissionChangedUserIds, userId);
2001 }
2002 }
2003 }
2004 }
2005
2006 return runtimePermissionChangedUserIds;
2007 }
2008
Todd Kennedyc8423932017-10-05 08:58:36 -07002009 private String[] getAppOpPermissionPackages(String permName) {
2010 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2011 return null;
2012 }
2013 synchronized (mLock) {
2014 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2015 if (pkgs == null) {
2016 return null;
2017 }
2018 return pkgs.toArray(new String[pkgs.size()]);
2019 }
2020 }
2021
2022 private int getPermissionFlags(
2023 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002024 if (!mUserManagerInt.exists(userId)) {
2025 return 0;
2026 }
2027
2028 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
2029
2030 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002031 true, // requireFullPermission
2032 false, // checkShell
2033 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002034 "getPermissionFlags");
2035
2036 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2037 if (pkg == null || pkg.mExtras == null) {
2038 return 0;
2039 }
2040 synchronized (mLock) {
2041 if (mSettings.getPermissionLocked(permName) == null) {
2042 return 0;
2043 }
2044 }
2045 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2046 return 0;
2047 }
2048 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2049 PermissionsState permissionsState = ps.getPermissionsState();
2050 return permissionsState.getPermissionFlags(permName, userId);
2051 }
2052
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002053 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2054 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2055 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2056
2057 private void updatePermissions(String packageName, PackageParser.Package pkg,
2058 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2059 PermissionCallback callback) {
2060 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2061 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2062 updatePermissions(
2063 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2064 if (pkg != null && pkg.childPackages != null) {
2065 for (PackageParser.Package childPkg : pkg.childPackages) {
2066 updatePermissions(childPkg.packageName, childPkg,
2067 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2068 }
2069 }
2070 }
2071
2072 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2073 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2074 final int flags = UPDATE_PERMISSIONS_ALL |
2075 (sdkUpdated
2076 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2077 : 0);
2078 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2079 }
2080
2081 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2082 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2083 PermissionCallback callback) {
2084 // TODO: Most of the methods exposing BasePermission internals [source package name,
2085 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2086 // have package settings, we should make note of it elsewhere [map between
2087 // source package name and BasePermission] and cycle through that here. Then we
2088 // define a single method on BasePermission that takes a PackageSetting, changing
2089 // package name and a package.
2090 // NOTE: With this approach, we also don't need to tree trees differently than
2091 // normal permissions. Today, we need two separate loops because these BasePermission
2092 // objects are stored separately.
2093 // Make sure there are no dangling permission trees.
2094 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2095
2096 // Make sure all dynamic permissions have been assigned to a package,
2097 // and make sure there are no dangling permissions.
2098 flags = updatePermissions(changingPkgName, changingPkg, flags);
2099
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002100 synchronized (mLock) {
2101 if (mBackgroundPermissions == null) {
2102 // Cache background -> foreground permission mapping.
2103 // Only system declares background permissions, hence mapping does never change.
2104 mBackgroundPermissions = new ArrayMap<>();
2105 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
2106 if (bp.perm.info != null && bp.perm.info.backgroundPermission != null) {
2107 String fgPerm = bp.name;
2108 String bgPerm = bp.perm.info.backgroundPermission;
2109
2110 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2111 if (fgPerms == null) {
2112 fgPerms = new ArrayList<>();
2113 mBackgroundPermissions.put(bgPerm, fgPerms);
2114 }
2115
2116 fgPerms.add(fgPerm);
2117 }
2118 }
2119 }
2120 }
2121
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002122 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002123 // Now update the permissions for all packages, in particular
2124 // replace the granted permissions of the system packages.
2125 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2126 for (PackageParser.Package pkg : allPackages) {
2127 if (pkg != changingPkg) {
2128 // Only replace for packages on requested volume
2129 final String volumeUuid = getVolumeUuidForPackage(pkg);
2130 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2131 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002132 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002133 }
2134 }
2135 }
2136
2137 if (changingPkg != null) {
2138 // Only replace for packages on requested volume
2139 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2140 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2141 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002142 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002143 }
2144 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2145 }
2146
2147 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002148 Set<BasePermission> needsUpdate = null;
2149 synchronized (mLock) {
2150 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2151 while (it.hasNext()) {
2152 final BasePermission bp = it.next();
2153 if (bp.isDynamic()) {
2154 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2155 }
2156 if (bp.getSourcePackageSetting() != null) {
2157 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002158 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002159 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2160 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002161 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002162 it.remove();
2163 }
2164 continue;
2165 }
2166 if (needsUpdate == null) {
2167 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2168 }
2169 needsUpdate.add(bp);
2170 }
2171 }
2172 if (needsUpdate != null) {
2173 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002174 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002175 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2176 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002177 if (sourcePkg != null && sourcePkg.mExtras != null) {
2178 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002179 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002180 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002181 }
2182 continue;
2183 }
2184 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2185 + " from package " + bp.getSourcePackageName());
2186 mSettings.removePermissionLocked(bp.getName());
2187 }
2188 }
2189 }
2190 return flags;
2191 }
2192
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002193 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002194 int flags) {
2195 Set<BasePermission> needsUpdate = null;
2196 synchronized (mLock) {
2197 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2198 while (it.hasNext()) {
2199 final BasePermission bp = it.next();
2200 if (bp.getSourcePackageSetting() != null) {
2201 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002202 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002203 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2204 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002205 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002206 it.remove();
2207 }
2208 continue;
2209 }
2210 if (needsUpdate == null) {
2211 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2212 }
2213 needsUpdate.add(bp);
2214 }
2215 }
2216 if (needsUpdate != null) {
2217 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002218 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002219 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2220 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002221 if (sourcePkg != null && sourcePkg.mExtras != null) {
2222 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002223 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002224 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002225 }
2226 continue;
2227 }
2228 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2229 + " from package " + bp.getSourcePackageName());
2230 mSettings.removePermissionLocked(bp.getName());
2231 }
2232 }
2233 }
2234 return flags;
2235 }
2236
Todd Kennedy0eb97382017-10-03 16:57:22 -07002237 private void updatePermissionFlags(String permName, String packageName, int flagMask,
2238 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2239 if (!mUserManagerInt.exists(userId)) {
2240 return;
2241 }
2242
2243 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2244
2245 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002246 true, // requireFullPermission
2247 true, // checkShell
2248 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002249 "updatePermissionFlags");
2250
2251 // Only the system can change these flags and nothing else.
2252 if (callingUid != Process.SYSTEM_UID) {
2253 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2254 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2255 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2256 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2257 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2258 }
2259
2260 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2261 if (pkg == null || pkg.mExtras == null) {
2262 throw new IllegalArgumentException("Unknown package: " + packageName);
2263 }
2264 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2265 throw new IllegalArgumentException("Unknown package: " + packageName);
2266 }
2267
2268 final BasePermission bp;
2269 synchronized (mLock) {
2270 bp = mSettings.getPermissionLocked(permName);
2271 }
2272 if (bp == null) {
2273 throw new IllegalArgumentException("Unknown permission: " + permName);
2274 }
2275
2276 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2277 final PermissionsState permissionsState = ps.getPermissionsState();
2278 final boolean hadState =
2279 permissionsState.getRuntimePermissionState(permName, userId) != null;
2280 final boolean permissionUpdated =
2281 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2282 if (permissionUpdated && callback != null) {
2283 // Install and runtime permissions are stored in different places,
2284 // so figure out what permission changed and persist the change.
2285 if (permissionsState.getInstallPermissionState(permName) != null) {
2286 callback.onInstallPermissionUpdated();
2287 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2288 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002289 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002290 }
2291 }
2292 }
2293
2294 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2295 int userId, Collection<Package> packages, PermissionCallback callback) {
2296 if (!mUserManagerInt.exists(userId)) {
2297 return false;
2298 }
2299
2300 enforceGrantRevokeRuntimePermissionPermissions(
2301 "updatePermissionFlagsForAllApps");
2302 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002303 true, // requireFullPermission
2304 true, // checkShell
2305 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002306 "updatePermissionFlagsForAllApps");
2307
2308 // Only the system can change system fixed flags.
2309 if (callingUid != Process.SYSTEM_UID) {
2310 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2311 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2312 }
2313
2314 boolean changed = false;
2315 for (PackageParser.Package pkg : packages) {
2316 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2317 if (ps == null) {
2318 continue;
2319 }
2320 PermissionsState permissionsState = ps.getPermissionsState();
2321 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2322 userId, flagMask, flagValues);
2323 }
2324 return changed;
2325 }
2326
2327 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2328 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2329 != PackageManager.PERMISSION_GRANTED
2330 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2331 != PackageManager.PERMISSION_GRANTED) {
2332 throw new SecurityException(message + " requires "
2333 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2334 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2335 }
2336 }
2337
2338 /**
2339 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2340 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2341 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2342 * @param message the message to log on security exception
2343 */
2344 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002345 boolean requireFullPermission, boolean checkShell,
2346 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002347 if (userId < 0) {
2348 throw new IllegalArgumentException("Invalid userId " + userId);
2349 }
2350 if (checkShell) {
2351 PackageManagerServiceUtils.enforceShellRestriction(
2352 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2353 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002354 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002355 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002356 if (requireFullPermission) {
2357 mContext.enforceCallingOrSelfPermission(
2358 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2359 } else {
2360 try {
2361 mContext.enforceCallingOrSelfPermission(
2362 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2363 } catch (SecurityException se) {
2364 mContext.enforceCallingOrSelfPermission(
2365 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2366 }
2367 }
2368 }
2369 }
2370
Andreas Gampea71bee82018-07-20 12:55:36 -07002371 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002372 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2373 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002374 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002375 size += tree.calculateFootprint(perm);
2376 }
2377 return size;
2378 }
2379
Andreas Gampea71bee82018-07-20 12:55:36 -07002380 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002381 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2382 // We calculate the max size of permissions defined by this uid and throw
2383 // if that plus the size of 'info' would exceed our stated maximum.
2384 if (tree.getUid() != Process.SYSTEM_UID) {
2385 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2386 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2387 throw new SecurityException("Permission tree size cap exceeded");
2388 }
2389 }
2390 }
2391
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002392 private void systemReady() {
2393 mSystemReady = true;
2394 if (mPrivappPermissionsViolations != null) {
2395 throw new IllegalStateException("Signature|privileged permissions not in "
2396 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2397 }
2398 }
2399
2400 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2401 if (pkg == null) {
2402 return StorageManager.UUID_PRIVATE_INTERNAL;
2403 }
2404 if (pkg.isExternal()) {
2405 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2406 return StorageManager.UUID_PRIMARY_PHYSICAL;
2407 } else {
2408 return pkg.volumeUuid;
2409 }
2410 } else {
2411 return StorageManager.UUID_PRIVATE_INTERNAL;
2412 }
2413 }
2414
Todd Kennedyc8423932017-10-05 08:58:36 -07002415 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2416 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2417 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2418 return true;
2419 }
2420 }
2421 return false;
2422 }
2423
Todd Kennedy0eb97382017-10-03 16:57:22 -07002424 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002425 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002426 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002427 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002428 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002429 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002430 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002431 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2432 final LogMaker log = new LogMaker(action);
2433 log.setPackageName(packageName);
2434 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002435
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002436 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002437 }
2438
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002439 /**
2440 * Get the mapping of background permissions to their foreground permissions.
2441 *
2442 * <p>Only initialized in the system server.
2443 *
2444 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2445 */
2446 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2447 return mBackgroundPermissions;
2448 }
2449
Todd Kennedy0eb97382017-10-03 16:57:22 -07002450 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2451 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002452 public void systemReady() {
2453 PermissionManagerService.this.systemReady();
2454 }
2455 @Override
2456 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2457 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2458 }
2459 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002460 public void revokeRuntimePermissionsIfGroupChanged(
2461 @NonNull PackageParser.Package newPackage,
2462 @NonNull PackageParser.Package oldPackage,
2463 @NonNull ArrayList<String> allPackageNames,
2464 @NonNull PermissionCallback permissionCallback) {
2465 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2466 oldPackage, allPackageNames, permissionCallback);
2467 }
2468 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002469 public void addAllPermissions(Package pkg, boolean chatty) {
2470 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002471 }
2472 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002473 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2474 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2475 }
2476 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00002477 public void removeAllPermissions(Package pkg, boolean chatty) {
2478 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002479 }
2480 @Override
2481 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002482 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002483 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2484 }
2485 @Override
2486 public void removeDynamicPermission(String permName, int callingUid,
2487 PermissionCallback callback) {
2488 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002489 }
2490 @Override
2491 public void grantRuntimePermission(String permName, String packageName,
2492 boolean overridePolicy, int callingUid, int userId,
2493 PermissionCallback callback) {
2494 PermissionManagerService.this.grantRuntimePermission(
2495 permName, packageName, overridePolicy, callingUid, userId, callback);
2496 }
2497 @Override
2498 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2499 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2500 PermissionManagerService.this.grantRequestedRuntimePermissions(
2501 pkg, userIds, grantedPermissions, callingUid, callback);
2502 }
2503 @Override
2504 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2505 int callingUid, PermissionCallback callback) {
2506 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2507 pkg, callingUid, callback);
2508 }
2509 @Override
2510 public void revokeRuntimePermission(String permName, String packageName,
2511 boolean overridePolicy, int callingUid, int userId,
2512 PermissionCallback callback) {
2513 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jinae750fb2018-09-27 23:00:20 +00002514 overridePolicy, callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002515 }
2516 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002517 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2518 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2519 PermissionManagerService.this.updatePermissions(
2520 packageName, pkg, replaceGrant, allPackages, callback);
2521 }
2522 @Override
2523 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2524 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2525 PermissionManagerService.this.updateAllPermissions(
2526 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002527 }
2528 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002529 public String[] getAppOpPermissionPackages(String permName) {
2530 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2531 }
2532 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002533 public int getPermissionFlags(String permName, String packageName, int callingUid,
2534 int userId) {
2535 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2536 callingUid, userId);
2537 }
2538 @Override
2539 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2540 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2541 PermissionManagerService.this.updatePermissionFlags(
2542 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2543 }
2544 @Override
2545 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2546 int userId, Collection<Package> packages, PermissionCallback callback) {
2547 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2548 flagMask, flagValues, callingUid, userId, packages, callback);
2549 }
2550 @Override
2551 public void enforceCrossUserPermission(int callingUid, int userId,
2552 boolean requireFullPermission, boolean checkShell, String message) {
2553 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002554 requireFullPermission, checkShell, false, message);
2555 }
2556 @Override
2557 public void enforceCrossUserPermission(int callingUid, int userId,
2558 boolean requireFullPermission, boolean checkShell,
2559 boolean requirePermissionWhenSameUser, String message) {
2560 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2561 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002562 }
2563 @Override
2564 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2565 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2566 }
2567 @Override
2568 public int checkPermission(String permName, String packageName, int callingUid,
2569 int userId) {
2570 return PermissionManagerService.this.checkPermission(
2571 permName, packageName, callingUid, userId);
2572 }
2573 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002574 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2575 int callingUid) {
2576 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002577 }
2578 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002579 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2580 int callingUid) {
2581 return PermissionManagerService.this.getPermissionGroupInfo(
2582 groupName, flags, callingUid);
2583 }
2584 @Override
2585 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2586 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2587 }
2588 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002589 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2590 int callingUid) {
2591 return PermissionManagerService.this.getPermissionInfo(
2592 permName, packageName, flags, callingUid);
2593 }
2594 @Override
2595 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2596 int callingUid) {
2597 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2598 }
2599 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002600 public PermissionSettings getPermissionSettings() {
2601 return mSettings;
2602 }
2603 @Override
2604 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2605 return mDefaultPermissionGrantPolicy;
2606 }
2607 @Override
2608 public BasePermission getPermissionTEMP(String permName) {
2609 synchronized (PermissionManagerService.this.mLock) {
2610 return mSettings.getPermissionLocked(permName);
2611 }
2612 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002613 }
2614}