blob: 03da962b6ac614a6e484986f60a054302806b2ee [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
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -070019import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
Todd Kennedy0eb97382017-10-03 16:57:22 -070020import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070022import static android.app.AppOpsManager.MODE_ALLOWED;
23import static android.app.AppOpsManager.MODE_DEFAULT;
24import static android.app.AppOpsManager.MODE_ERRORED;
25import static android.app.AppOpsManager.MODE_FOREGROUND;
26import static android.app.AppOpsManager.MODE_IGNORED;
27import static android.app.AppOpsManager.OP_NONE;
28import static android.app.AppOpsManager.permissionToOp;
29import static android.app.AppOpsManager.permissionToOpCode;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070030import 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. Moltmann48456672019-01-20 13:14:03 -080033import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070034import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -080038import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS;
Hongwei Wangf391b552018-04-06 13:52:46 -070039import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070040import static android.os.UserHandle.getAppId;
41import static android.os.UserHandle.getUid;
Hongwei Wangf391b552018-04-06 13:52:46 -070042
Todd Kennedyc29b11a2017-10-23 15:55:59 -070043import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
44import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
45import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
46import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
47import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080048import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
49
50import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070051
52import android.Manifest;
53import android.annotation.NonNull;
54import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070055import android.annotation.UserIdInt;
56import android.app.AppOpsManager;
57import android.app.AppOpsManagerInternal;
Todd Kennedy0eb97382017-10-03 16:57:22 -070058import android.content.Context;
59import android.content.pm.PackageManager;
60import android.content.pm.PackageManagerInternal;
61import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070062import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070063import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070064import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070065import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070066import android.os.Binder;
67import android.os.Build;
68import android.os.Handler;
69import android.os.HandlerThread;
70import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070071import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070072import android.os.UserHandle;
73import android.os.UserManager;
74import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070075import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070076import android.os.storage.StorageManagerInternal;
Philip P. Moltmann48456672019-01-20 13:14:03 -080077import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070078import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080079import android.permission.PermissionManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070080import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070081import android.util.ArrayMap;
82import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070083import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070084import android.util.Log;
85import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070086import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -080087import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070088
Todd Kennedyc29b11a2017-10-23 15:55:59 -070089import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070090import com.android.internal.logging.MetricsLogger;
91import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070092import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070093import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070094import com.android.server.LocalServices;
95import com.android.server.ServiceThread;
96import com.android.server.SystemConfig;
97import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070098import com.android.server.pm.PackageManagerServiceUtils;
99import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700100import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700101import com.android.server.pm.UserManagerService;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800102import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
103import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700104import com.android.server.pm.permission.PermissionsState.PermissionState;
105
106import libcore.util.EmptyArray;
107
108import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700109import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700110import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700111import java.util.Iterator;
112import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700113import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700114import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700115import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800116import java.util.concurrent.CompletableFuture;
117import java.util.concurrent.ExecutionException;
118import java.util.concurrent.TimeUnit;
119import java.util.concurrent.TimeoutException;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700120
121/**
122 * Manages all permissions and handles permissions related tasks.
123 */
124public class PermissionManagerService {
125 private static final String TAG = "PackageManager";
126
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700127 /** Permission grant: not grant the permission. */
128 private static final int GRANT_DENIED = 1;
129 /** Permission grant: grant the permission as an install permission. */
130 private static final int GRANT_INSTALL = 2;
131 /** Permission grant: grant the permission as a runtime one. */
132 private static final int GRANT_RUNTIME = 3;
133 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
134 private static final int GRANT_UPGRADE = 4;
135
Philip P. Moltmann48456672019-01-20 13:14:03 -0800136 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
137
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700138 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
139 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
140 /** Empty array to avoid allocations */
141 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700142
Hongwei Wangf391b552018-04-06 13:52:46 -0700143 /** If the permission of the value is granted, so is the key */
144 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
145
146 static {
147 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
148 Manifest.permission.ACCESS_FINE_LOCATION);
149 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
150 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
151 }
152
Todd Kennedy0eb97382017-10-03 16:57:22 -0700153 /** Lock to protect internal data access */
154 private final Object mLock;
155
156 /** Internal connection to the package manager */
157 private final PackageManagerInternal mPackageManagerInt;
158
159 /** Internal connection to the user manager */
160 private final UserManagerInternal mUserManagerInt;
161
Philip P. Moltmann48456672019-01-20 13:14:03 -0800162 /** Permission controller: User space permission management */
163 private PermissionControllerManager mPermissionControllerManager;
164
Todd Kennedy0eb97382017-10-03 16:57:22 -0700165 /** Default permission policy to provide proper behaviour out-of-the-box */
166 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
167
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700168 /**
169 * Built-in permissions. Read from system configuration files. Mapping is from
170 * UID to permission name.
171 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700172 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700173
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700174 /** Built-in group IDs given to all packages. Read from system configuration files. */
175 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700176
177 private final HandlerThread mHandlerThread;
178 private final Handler mHandler;
179 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700180 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700181
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700182 /** Internal storage for permissions and related settings */
183 @GuardedBy("mLock")
184 private final PermissionSettings mSettings;
185
186 @GuardedBy("mLock")
187 private ArraySet<String> mPrivappPermissionsViolations;
188
189 @GuardedBy("mLock")
190 private boolean mSystemReady;
191
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700192 /**
193 * For each foreground/background permission the mapping:
194 * Background permission -> foreground permissions
195 */
196 @GuardedBy("mLock")
197 private ArrayMap<String, List<String>> mBackgroundPermissions;
198
Philip P. Moltmann48456672019-01-20 13:14:03 -0800199 /**
200 * A permission backup might contain apps that are not installed. In this case we delay the
201 * restoration until the app is installed.
202 *
203 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
204 * there is <u>no more</u> delayed backup left.
205 */
206 @GuardedBy("mLock")
207 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
208
Todd Kennedy0eb97382017-10-03 16:57:22 -0700209 PermissionManagerService(Context context,
210 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
211 @NonNull Object externalLock) {
212 mContext = context;
213 mLock = externalLock;
214 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
215 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700216 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700217
218 mHandlerThread = new ServiceThread(TAG,
219 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
220 mHandlerThread.start();
221 mHandler = new Handler(mHandlerThread.getLooper());
222 Watchdog.getInstance().addThread(mHandler);
223
224 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
225 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700226 SystemConfig systemConfig = SystemConfig.getInstance();
227 mSystemPermissions = systemConfig.getSystemPermissions();
228 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700229
230 // propagate permission configuration
231 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
232 SystemConfig.getInstance().getPermissions();
233 synchronized (mLock) {
234 for (int i=0; i<permConfig.size(); i++) {
235 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
236 BasePermission bp = mSettings.getPermissionLocked(perm.name);
237 if (bp == null) {
238 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
239 mSettings.putPermissionLocked(perm.name, bp);
240 }
241 if (perm.gids != null) {
242 bp.setGids(perm.gids, perm.perUser);
243 }
244 }
245 }
246
Philip P. Moltmann48456672019-01-20 13:14:03 -0800247 PermissionManagerServiceInternalImpl localService =
248 new PermissionManagerServiceInternalImpl();
249 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
250 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700251 }
252
253 /**
254 * Creates and returns an initialized, internal service for use by other components.
255 * <p>
256 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800257 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700258 * <p>
259 * NOTE: The external lock is temporary and should be removed. This needs to be a
260 * lock created by the permission manager itself.
261 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800262 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700263 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
264 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800265 final PermissionManagerServiceInternal permMgrInt =
266 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700267 if (permMgrInt != null) {
268 return permMgrInt;
269 }
270 new PermissionManagerService(context, defaultGrantCallback, externalLock);
Philip P. Moltmann48456672019-01-20 13:14:03 -0800271 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700272 }
273
274 @Nullable BasePermission getPermission(String permName) {
275 synchronized (mLock) {
276 return mSettings.getPermissionLocked(permName);
277 }
278 }
279
280 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
281 if (!mUserManagerInt.exists(userId)) {
282 return PackageManager.PERMISSION_DENIED;
283 }
284
Patrick Baumann97b9b532018-04-11 14:51:30 +0000285 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
286 if (pkg != null && pkg.mExtras != null) {
287 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700288 return PackageManager.PERMISSION_DENIED;
289 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000290 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700291 final boolean instantApp = ps.getInstantApp(userId);
292 final PermissionsState permissionsState = ps.getPermissionsState();
293 if (permissionsState.hasPermission(permName, userId)) {
294 if (instantApp) {
295 synchronized (mLock) {
296 BasePermission bp = mSettings.getPermissionLocked(permName);
297 if (bp != null && bp.isInstant()) {
298 return PackageManager.PERMISSION_GRANTED;
299 }
300 }
301 } else {
302 return PackageManager.PERMISSION_GRANTED;
303 }
304 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700305 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700306 return PackageManager.PERMISSION_GRANTED;
307 }
308 }
309
310 return PackageManager.PERMISSION_DENIED;
311 }
312
Todd Kennedy3c714492017-10-27 09:12:50 -0700313 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
314 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700315 final int callingUserId = UserHandle.getUserId(callingUid);
316 final boolean isCallerInstantApp =
317 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
318 final boolean isUidInstantApp =
319 mPackageManagerInt.getInstantAppPackageName(uid) != null;
320 final int userId = UserHandle.getUserId(uid);
321 if (!mUserManagerInt.exists(userId)) {
322 return PackageManager.PERMISSION_DENIED;
323 }
324
Todd Kennedy3c714492017-10-27 09:12:50 -0700325 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700326 if (pkg.mSharedUserId != null) {
327 if (isCallerInstantApp) {
328 return PackageManager.PERMISSION_DENIED;
329 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700330 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
331 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700332 }
333 final PermissionsState permissionsState =
334 ((PackageSetting) pkg.mExtras).getPermissionsState();
335 if (permissionsState.hasPermission(permName, userId)) {
336 if (isUidInstantApp) {
337 if (mSettings.isPermissionInstant(permName)) {
338 return PackageManager.PERMISSION_GRANTED;
339 }
340 } else {
341 return PackageManager.PERMISSION_GRANTED;
342 }
343 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700344 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700345 return PackageManager.PERMISSION_GRANTED;
346 }
347 } else {
348 ArraySet<String> perms = mSystemPermissions.get(uid);
349 if (perms != null) {
350 if (perms.contains(permName)) {
351 return PackageManager.PERMISSION_GRANTED;
352 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700353 if (FULLER_PERMISSION_MAP.containsKey(permName)
354 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700355 return PackageManager.PERMISSION_GRANTED;
356 }
357 }
358 }
359 return PackageManager.PERMISSION_DENIED;
360 }
361
Hongwei Wangf391b552018-04-06 13:52:46 -0700362 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -0800363 * Get the state of the runtime permissions as xml file.
364 *
365 * <p>Can not be called on main thread.
366 *
367 * @param user The user the data should be extracted for
368 *
369 * @return The state as a xml file
370 */
371 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
372 CompletableFuture<byte[]> backup = new CompletableFuture<>();
373 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
374 backup::complete);
375
376 try {
377 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
378 } catch (InterruptedException | ExecutionException | TimeoutException e) {
379 Slog.e(TAG, "Cannot create permission backup for " + user, e);
380 return null;
381 }
382 }
383
384 /**
385 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
386 *
387 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
388 * applied via {@link #restoreDelayedRuntimePermissions}.
389 *
390 * @param backup The state as an xml file
391 * @param user The user the data should be restored for
392 */
393 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
394 synchronized (mLock) {
395 mHasNoDelayedPermBackup.delete(user.getIdentifier());
396 mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
397 }
398 }
399
400 /**
401 * Try to apply permission backup that was previously not applied.
402 *
403 * <p>Can not be called on main thread.
404 *
405 * @param packageName The package that is newly installed
406 * @param user The user the package is installed for
407 *
408 * @see #restoreRuntimePermissions
409 */
410 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
411 @NonNull UserHandle user) {
412 synchronized (mLock) {
413 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
414 return;
415 }
416
417 mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
418 mContext.getMainExecutor(), (hasMoreBackup) -> {
419 if (hasMoreBackup) {
420 return;
421 }
422
423 synchronized (mLock) {
424 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
425 }
426 });
427 }
428 }
429
430 /**
Hongwei Wangf391b552018-04-06 13:52:46 -0700431 * Returns {@code true} if the permission can be implied from another granted permission.
432 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
433 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
434 * it access to any implied permissions.
435 */
436 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
437 String permName, int userId) {
438 return FULLER_PERMISSION_MAP.containsKey(permName)
439 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
440 }
441
Todd Kennedy460f28c2017-10-06 13:46:22 -0700442 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
443 int callingUid) {
444 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
445 return null;
446 }
447 synchronized (mLock) {
448 return PackageParser.generatePermissionGroupInfo(
449 mSettings.mPermissionGroups.get(groupName), flags);
450 }
451 }
452
453 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
454 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
455 return null;
456 }
457 synchronized (mLock) {
458 final int N = mSettings.mPermissionGroups.size();
459 final ArrayList<PermissionGroupInfo> out
460 = new ArrayList<PermissionGroupInfo>(N);
461 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
462 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
463 }
464 return out;
465 }
466 }
467
468 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700469 int callingUid) {
470 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
471 return null;
472 }
473 // reader
474 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700475 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700476 if (bp == null) {
477 return null;
478 }
479 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
480 bp.getProtectionLevel(), packageName, callingUid);
481 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
482 }
483 }
484
485 private List<PermissionInfo> getPermissionInfoByGroup(
486 String groupName, int flags, int callingUid) {
487 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
488 return null;
489 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700490 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700491 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
492 return null;
493 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700494 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700495 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700496 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
497 if (pi != null) {
498 out.add(pi);
499 }
500 }
501 return out;
502 }
503 }
504
505 private int adjustPermissionProtectionFlagsLocked(
506 int protectionLevel, String packageName, int uid) {
507 // Signature permission flags area always reported
508 final int protectionLevelMasked = protectionLevel
509 & (PermissionInfo.PROTECTION_NORMAL
510 | PermissionInfo.PROTECTION_DANGEROUS
511 | PermissionInfo.PROTECTION_SIGNATURE);
512 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
513 return protectionLevel;
514 }
515 // System sees all flags.
516 final int appId = UserHandle.getAppId(uid);
517 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
518 || appId == Process.SHELL_UID) {
519 return protectionLevel;
520 }
521 // Normalize package name to handle renamed packages and static libs
522 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
523 if (pkg == null) {
524 return protectionLevel;
525 }
526 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
527 return protectionLevelMasked;
528 }
529 // Apps that target O see flags for all protection levels.
530 final PackageSetting ps = (PackageSetting) pkg.mExtras;
531 if (ps == null) {
532 return protectionLevel;
533 }
534 if (ps.getAppId() != appId) {
535 return protectionLevel;
536 }
537 return protectionLevel;
538 }
539
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700540 /**
541 * We might auto-grant permissions if any permission of the group is already granted. Hence if
542 * the group of a granted permission changes we need to revoke it to avoid having permissions of
543 * the new group auto-granted.
544 *
545 * @param newPackage The new package that was installed
546 * @param oldPackage The old package that was updated
547 * @param allPackageNames All package names
548 * @param permissionCallback Callback for permission changed
549 */
550 private void revokeRuntimePermissionsIfGroupChanged(
551 @NonNull PackageParser.Package newPackage,
552 @NonNull PackageParser.Package oldPackage,
553 @NonNull ArrayList<String> allPackageNames,
554 @NonNull PermissionCallback permissionCallback) {
555 final int numOldPackagePermissions = oldPackage.permissions.size();
556 final ArrayMap<String, String> oldPermissionNameToGroupName
557 = new ArrayMap<>(numOldPackagePermissions);
558
559 for (int i = 0; i < numOldPackagePermissions; i++) {
560 final PackageParser.Permission permission = oldPackage.permissions.get(i);
561
562 if (permission.group != null) {
563 oldPermissionNameToGroupName.put(permission.info.name,
564 permission.group.info.name);
565 }
566 }
567
568 final int numNewPackagePermissions = newPackage.permissions.size();
569 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
570 newPermissionNum++) {
571 final PackageParser.Permission newPermission =
572 newPackage.permissions.get(newPermissionNum);
573 final int newProtection = newPermission.info.getProtection();
574
575 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
576 final String permissionName = newPermission.info.name;
577 final String newPermissionGroupName =
578 newPermission.group == null ? null : newPermission.group.info.name;
579 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
580 permissionName);
581
582 if (newPermissionGroupName != null
583 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
584 final int[] userIds = mUserManagerInt.getUserIds();
585 final int numUserIds = userIds.length;
586 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
587 final int userId = userIds[userIdNum];
588
589 final int numPackages = allPackageNames.size();
590 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
591 final String packageName = allPackageNames.get(packageNum);
592
593 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
594 userId) == PackageManager.PERMISSION_GRANTED) {
595 EventLog.writeEvent(0x534e4554, "72710897",
596 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900597 "Revoking permission " + permissionName +
598 " from package " + packageName +
599 " as the group changed from " + oldPermissionGroupName +
600 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700601
602 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000603 revokeRuntimePermission(permissionName, packageName, false,
604 Process.SYSTEM_UID, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700605 } catch (IllegalArgumentException e) {
606 Slog.e(TAG, "Could not revoke " + permissionName + " from "
607 + packageName, e);
608 }
609 }
610 }
611 }
612 }
613 }
614 }
615 }
616
Todd Kennedyc8423932017-10-05 08:58:36 -0700617 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
618 final int N = pkg.permissions.size();
619 for (int i=0; i<N; i++) {
620 PackageParser.Permission p = pkg.permissions.get(i);
621
622 // Assume by default that we did not install this permission into the system.
623 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
624
Todd Kennedyc8423932017-10-05 08:58:36 -0700625 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700626 // Now that permission groups have a special meaning, we ignore permission
627 // groups for legacy apps to prevent unexpected behavior. In particular,
628 // permissions for one app being granted to someone just because they happen
629 // to be in a group defined by another app (before this had no implications).
630 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
631 p.group = mSettings.mPermissionGroups.get(p.info.group);
632 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700633 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700634 && p.info.group != null && p.group == null) {
635 Slog.i(TAG, "Permission " + p.info.name + " from package "
636 + p.info.packageName + " in an unknown group " + p.info.group);
637 }
638 }
639
Todd Kennedyc8423932017-10-05 08:58:36 -0700640 if (p.tree) {
641 final BasePermission bp = BasePermission.createOrUpdate(
642 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
643 mSettings.getAllPermissionTreesLocked(), chatty);
644 mSettings.putPermissionTreeLocked(p.info.name, bp);
645 } else {
646 final BasePermission bp = BasePermission.createOrUpdate(
647 mSettings.getPermissionLocked(p.info.name),
648 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
649 mSettings.putPermissionLocked(p.info.name, bp);
650 }
651 }
652 }
653 }
654
Todd Kennedy460f28c2017-10-06 13:46:22 -0700655 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
656 final int N = pkg.permissionGroups.size();
657 StringBuilder r = null;
658 for (int i=0; i<N; i++) {
659 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
660 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
661 final String curPackageName = (cur == null) ? null : cur.info.packageName;
662 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
663 if (cur == null || isPackageUpdate) {
664 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700665 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700666 if (r == null) {
667 r = new StringBuilder(256);
668 } else {
669 r.append(' ');
670 }
671 if (isPackageUpdate) {
672 r.append("UPD:");
673 }
674 r.append(pg.info.name);
675 }
676 } else {
677 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
678 + pg.info.packageName + " ignored: original from "
679 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700680 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700681 if (r == null) {
682 r = new StringBuilder(256);
683 } else {
684 r.append(' ');
685 }
686 r.append("DUP:");
687 r.append(pg.info.name);
688 }
689 }
690 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700691 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700692 Log.d(TAG, " Permission Groups: " + r);
693 }
694
695 }
696
Hongming Jinae750fb2018-09-27 23:00:20 +0000697 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700698 synchronized (mLock) {
699 int N = pkg.permissions.size();
700 StringBuilder r = null;
701 for (int i=0; i<N; i++) {
702 PackageParser.Permission p = pkg.permissions.get(i);
703 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
704 if (bp == null) {
705 bp = mSettings.mPermissionTrees.get(p.info.name);
706 }
707 if (bp != null && bp.isPermission(p)) {
708 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700709 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700710 if (r == null) {
711 r = new StringBuilder(256);
712 } else {
713 r.append(' ');
714 }
715 r.append(p.info.name);
716 }
717 }
718 if (p.isAppOp()) {
719 ArraySet<String> appOpPkgs =
720 mSettings.mAppOpPermissionPackages.get(p.info.name);
721 if (appOpPkgs != null) {
722 appOpPkgs.remove(pkg.packageName);
723 }
724 }
725 }
726 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700727 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700728 }
729
730 N = pkg.requestedPermissions.size();
731 r = null;
732 for (int i=0; i<N; i++) {
733 String perm = pkg.requestedPermissions.get(i);
734 if (mSettings.isPermissionAppOp(perm)) {
735 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
736 if (appOpPkgs != null) {
737 appOpPkgs.remove(pkg.packageName);
738 if (appOpPkgs.isEmpty()) {
739 mSettings.mAppOpPermissionPackages.remove(perm);
740 }
741 }
742 }
743 }
744 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700745 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700746 }
747 }
748 }
749
750 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700751 PermissionInfo info, int callingUid, PermissionCallback callback) {
752 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
753 throw new SecurityException("Instant apps can't add permissions");
754 }
755 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
756 throw new SecurityException("Label must be specified in permission");
757 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700758 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700759 final boolean added;
760 final boolean changed;
761 synchronized (mLock) {
762 BasePermission bp = mSettings.getPermissionLocked(info.name);
763 added = bp == null;
764 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
765 if (added) {
766 enforcePermissionCapLocked(info, tree);
767 bp = new BasePermission(info.name, tree.getSourcePackageName(),
768 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700769 } else if (!bp.isDynamic()) {
770 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700771 + info.name);
772 }
773 changed = bp.addToTree(fixedLevel, info, tree);
774 if (added) {
775 mSettings.putPermissionLocked(info.name, bp);
776 }
777 }
778 if (changed && callback != null) {
779 callback.onPermissionChanged();
780 }
781 return added;
782 }
783
Todd Kennedyc8423932017-10-05 08:58:36 -0700784 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700785 String permName, int callingUid, PermissionCallback callback) {
786 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
787 throw new SecurityException("Instant applications don't have access to this method");
788 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700789 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700790 synchronized (mLock) {
791 final BasePermission bp = mSettings.getPermissionLocked(permName);
792 if (bp == null) {
793 return;
794 }
795 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600796 // TODO: switch this back to SecurityException
797 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700798 + permName);
799 }
800 mSettings.removePermissionLocked(permName);
801 if (callback != null) {
802 callback.onPermissionRemoved();
803 }
804 }
805 }
806
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700807 /**
808 * Restore the permission state for a package.
809 *
810 * <ul>
811 * <li>During boot the state gets restored from the disk</li>
812 * <li>During app update the state gets restored from the last version of the app</li>
813 * </ul>
814 *
815 * <p>This restores the permission state for all users.
816 *
817 * @param pkg the package the permissions belong to
818 * @param replace if the package is getting replaced (this might change the requested
819 * permissions of this package)
820 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
821 * @param callback Result call back
822 */
823 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
824 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700825 // IMPORTANT: There are two types of permissions: install and runtime.
826 // Install time permissions are granted when the app is installed to
827 // all device users and users added in the future. Runtime permissions
828 // are granted at runtime explicitly to specific users. Normal and signature
829 // protected permissions are install time permissions. Dangerous permissions
830 // are install permissions if the app's target SDK is Lollipop MR1 or older,
831 // otherwise they are runtime permissions. This function does not manage
832 // runtime permissions except for the case an app targeting Lollipop MR1
833 // being upgraded to target a newer SDK, in which case dangerous permissions
834 // are transformed from install time to runtime ones.
835
836 final PackageSetting ps = (PackageSetting) pkg.mExtras;
837 if (ps == null) {
838 return;
839 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700840
841 final PermissionsState permissionsState = ps.getPermissionsState();
842 PermissionsState origPermissions = permissionsState;
843
844 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
845
846 boolean runtimePermissionsRevoked = false;
847 int[] updatedUserIds = EMPTY_INT_ARRAY;
848
849 boolean changedInstallPermission = false;
850
851 if (replace) {
852 ps.setInstallPermissionsFixed(false);
853 if (!ps.isSharedUser()) {
854 origPermissions = new PermissionsState(permissionsState);
855 permissionsState.reset();
856 } else {
857 // We need to know only about runtime permission changes since the
858 // calling code always writes the install permissions state but
859 // the runtime ones are written only if changed. The only cases of
860 // changed runtime permissions here are promotion of an install to
861 // runtime and revocation of a runtime from a shared user.
862 synchronized (mLock) {
863 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
864 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
865 if (!ArrayUtils.isEmpty(updatedUserIds)) {
866 runtimePermissionsRevoked = true;
867 }
868 }
869 }
870 }
871
872 permissionsState.setGlobalGids(mGlobalGids);
873
874 synchronized (mLock) {
875 final int N = pkg.requestedPermissions.size();
876 for (int i = 0; i < N; i++) {
877 final String permName = pkg.requestedPermissions.get(i);
878 final BasePermission bp = mSettings.getPermissionLocked(permName);
879 final boolean appSupportsRuntimePermissions =
880 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
881
882 if (DEBUG_INSTALL) {
883 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
884 }
885
886 if (bp == null || bp.getSourcePackageSetting() == null) {
887 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
888 if (DEBUG_PERMISSIONS) {
889 Slog.i(TAG, "Unknown permission " + permName
890 + " in package " + pkg.packageName);
891 }
892 }
893 continue;
894 }
895
896 // Limit ephemeral apps to ephemeral allowed permissions.
897 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
898 if (DEBUG_PERMISSIONS) {
899 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
900 + " for package " + pkg.packageName);
901 }
902 continue;
903 }
904
905 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
906 if (DEBUG_PERMISSIONS) {
907 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
908 + " for package " + pkg.packageName);
909 }
910 continue;
911 }
912
913 final String perm = bp.getName();
914 boolean allowedSig = false;
915 int grant = GRANT_DENIED;
916
917 // Keep track of app op permissions.
918 if (bp.isAppOp()) {
919 mSettings.addAppOpPackage(perm, pkg.packageName);
920 }
921
922 if (bp.isNormal()) {
923 // For all apps normal permissions are install time ones.
924 grant = GRANT_INSTALL;
925 } else if (bp.isRuntime()) {
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700926 if (origPermissions.hasInstallPermission(bp.getName())) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800927 // Before Q we represented some runtime permissions as install permissions,
928 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700929 grant = GRANT_UPGRADE;
930 } else {
931 // For modern apps keep runtime permissions unchanged.
932 grant = GRANT_RUNTIME;
933 }
934 } else if (bp.isSignature()) {
935 // For all apps signature permissions are install time ones.
936 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
937 if (allowedSig) {
938 grant = GRANT_INSTALL;
939 }
940 }
941
942 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700943 Slog.i(TAG, "Considering granting permission " + perm + " to package "
944 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700945 }
946
947 if (grant != GRANT_DENIED) {
948 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
949 // If this is an existing, non-system package, then
950 // we can't add any new permissions to it.
951 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
952 // Except... if this is a permission that was added
953 // to the platform (note: need to only do this when
954 // updating the platform).
955 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
956 grant = GRANT_DENIED;
957 }
958 }
959 }
960
961 switch (grant) {
962 case GRANT_INSTALL: {
963 // Revoke this as runtime permission to handle the case of
964 // a runtime permission being downgraded to an install one.
965 // Also in permission review mode we keep dangerous permissions
966 // for legacy apps
967 for (int userId : UserManagerService.getInstance().getUserIds()) {
968 if (origPermissions.getRuntimePermissionState(
969 perm, userId) != null) {
970 // Revoke the runtime permission and clear the flags.
971 origPermissions.revokeRuntimePermission(bp, userId);
972 origPermissions.updatePermissionFlags(bp, userId,
973 PackageManager.MASK_PERMISSION_FLAGS, 0);
974 // If we revoked a permission permission, we have to write.
975 updatedUserIds = ArrayUtils.appendInt(
976 updatedUserIds, userId);
977 }
978 }
979 // Grant an install permission.
980 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -0800981 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700982 changedInstallPermission = true;
983 }
984 } break;
985
986 case GRANT_RUNTIME: {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800987 for (int userId : currentUserIds) {
988 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700989 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -0800990 int flags = permState != null ? permState.getFlags() : 0;
991
992 boolean wasChanged = false;
993
994 if (appSupportsRuntimePermissions) {
995 // Remove review flag as it is not necessary anymore
996 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
997 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
998 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700999 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001000
1001 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1002 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1003 wasChanged = true;
1004 } else {
1005 if (permState != null && permState.isGranted()) {
1006 if (permissionsState.grantRuntimePermission(bp, userId)
1007 == PERMISSION_OPERATION_FAILURE) {
1008 wasChanged = true;
1009 }
1010 }
1011 }
1012 } else {
1013 if (permState == null) {
1014 // New permission
1015 if (PLATFORM_PACKAGE_NAME.equals(
1016 bp.getSourcePackageName())) {
1017 if (!bp.isRemoved()) {
1018 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1019 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1020 wasChanged = true;
1021 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001022 }
1023 }
1024
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001025 if (permissionsState.grantRuntimePermission(bp, userId)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001026 != PERMISSION_OPERATION_FAILURE) {
1027 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001028 }
1029 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001030
1031 if (wasChanged) {
1032 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1033 }
1034
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001035 permissionsState.updatePermissionFlags(bp, userId,
1036 MASK_PERMISSION_FLAGS, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001037 }
1038 } break;
1039
1040 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001041 // Upgrade from Pre-Q to Q permission model. Make all permissions
1042 // runtime
1043 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001044 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001045 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001046
Philip P. Moltmann48456672019-01-20 13:14:03 -08001047 // Remove install permission
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001048 if (origPermissions.revokeInstallPermission(bp)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001049 != PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001050 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
1051 PackageManager.MASK_PERMISSION_FLAGS, 0);
1052 changedInstallPermission = true;
1053 }
1054
Philip P. Moltmann48456672019-01-20 13:14:03 -08001055 for (int userId : currentUserIds) {
1056 boolean wasChanged = false;
1057
1058 if (appSupportsRuntimePermissions) {
1059 // Remove review flag as it is not necessary anymore
1060 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1061 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1062 wasChanged = true;
1063 }
1064
1065 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1066 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1067 wasChanged = true;
1068 } else {
1069 if (permissionsState.grantRuntimePermission(bp, userId) !=
1070 PERMISSION_OPERATION_FAILURE) {
1071 wasChanged = true;
1072 }
1073 }
1074 } else {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001075 if (permissionsState.grantRuntimePermission(bp, userId) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001076 PERMISSION_OPERATION_FAILURE) {
1077 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1078 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001079 }
1080 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001081
1082 if (wasChanged) {
1083 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1084 }
1085
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001086 permissionsState.updatePermissionFlags(bp, userId,
1087 MASK_PERMISSION_FLAGS, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001088 }
1089 } break;
1090
1091 default: {
1092 if (packageOfInterest == null
1093 || packageOfInterest.equals(pkg.packageName)) {
1094 if (DEBUG_PERMISSIONS) {
1095 Slog.i(TAG, "Not granting permission " + perm
1096 + " to package " + pkg.packageName
1097 + " because it was previously installed without");
1098 }
1099 }
1100 } break;
1101 }
1102 } else {
1103 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001104 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001105 // Also drop the permission flags.
1106 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1107 PackageManager.MASK_PERMISSION_FLAGS, 0);
1108 changedInstallPermission = true;
1109 Slog.i(TAG, "Un-granting permission " + perm
1110 + " from package " + pkg.packageName
1111 + " (protectionLevel=" + bp.getProtectionLevel()
1112 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1113 + ")");
1114 } else if (bp.isAppOp()) {
1115 // Don't print warning for app op permissions, since it is fine for them
1116 // not to be granted, there is a UI for the user to decide.
1117 if (DEBUG_PERMISSIONS
1118 && (packageOfInterest == null
1119 || packageOfInterest.equals(pkg.packageName))) {
1120 Slog.i(TAG, "Not granting permission " + perm
1121 + " to package " + pkg.packageName
1122 + " (protectionLevel=" + bp.getProtectionLevel()
1123 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1124 + ")");
1125 }
1126 }
1127 }
1128 }
1129
1130 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1131 !ps.isSystem() || ps.isUpdatedSystem()) {
1132 // This is the first that we have heard about this package, so the
1133 // permissions we have now selected are fixed until explicitly
1134 // changed.
1135 ps.setInstallPermissionsFixed(true);
1136 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001137
1138 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1139 updatedUserIds);
1140 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1141 permissionsState, pkg, updatedUserIds);
Philip P. Moltmanndde07852019-01-25 16:42:36 -08001142
1143 setAppOpsLocked(permissionsState, pkg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001144 }
1145
1146 // Persist the runtime permissions state for users with changes. If permissions
1147 // were revoked because no app in the shared user declares them we have to
1148 // write synchronously to avoid losing runtime permissions state.
1149 if (callback != null) {
1150 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1151 }
1152 }
1153
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001154 /**
1155 * Set app op for a app-op related to a permission.
1156 *
1157 * @param permission The permission the app-op belongs to
1158 * @param pkg The package the permission belongs to
1159 * @param userId The user to be changed
1160 * @param mode The new mode to set
1161 */
1162 private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
1163 @UserIdInt int userId, int mode) {
1164 AppOpsManagerInternal appOpsInternal = LocalServices.getService(
1165 AppOpsManagerInternal.class);
1166
Philip P. Moltmann159d98b2018-12-20 08:30:53 -08001167 appOpsInternal.setUidMode(permissionToOpCode(permission),
1168 getUid(userId, getAppId(pkg.applicationInfo.uid)), mode);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001169 }
1170
1171 /**
1172 * Revoke permissions that are not implicit anymore and that have
1173 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1174 *
1175 * @param ps The state of the permissions of the package
1176 * @param pkg The package that is currently looked at
1177 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1178 * for a user is changed.
1179 *
1180 * @return The updated value of the {@code updatedUserIds} parameter
1181 */
1182 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1183 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1184 @NonNull int[] updatedUserIds) {
1185 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1186
1187 String pkgName = pkg.packageName;
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08001188 boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1189 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001190
1191 int[] users = UserManagerService.getInstance().getUserIds();
1192 int numUsers = users.length;
1193 for (int i = 0; i < numUsers; i++) {
1194 int userId = users[i];
1195
1196 for (String permission : ps.getPermissions(userId)) {
1197 if (!pkg.implicitPermissions.contains(permission)) {
1198 if (!ps.hasInstallPermission(permission)) {
1199 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1200
1201 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1202 BasePermission bp = mSettings.getPermissionLocked(permission);
1203
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001204 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001205
1206 if ((flags & (FLAG_PERMISSION_GRANTED_BY_DEFAULT
1207 | FLAG_PERMISSION_POLICY_FIXED | FLAG_PERMISSION_SYSTEM_FIXED))
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001208 == 0 && supportsRuntimePermissions) {
1209 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1210 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1211 if (DEBUG_PERMISSIONS) {
1212 Slog.i(TAG, "Revoking runtime permission "
1213 + permission + " for " + pkgName
1214 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001215 }
1216 }
1217
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001218 flagsToRemove |=
1219 FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_USER_SET;
1220
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001221 List<String> fgPerms = mBackgroundPermissions.get(permission);
1222 if (fgPerms != null) {
1223 int numFgPerms = fgPerms.size();
1224 for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
1225 String fgPerm = fgPerms.get(fgPermNum);
1226
1227 int mode = appOpsManager.unsafeCheckOpRaw(
1228 permissionToOp(fgPerm),
1229 getUid(userId, getAppId(pkg.applicationInfo.uid)),
1230 pkgName);
1231
1232 if (mode == MODE_ALLOWED) {
1233 setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
1234 }
1235 }
1236 }
1237 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001238
1239 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1240 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001241 }
1242 }
1243 }
1244 }
1245 }
1246
1247 return updatedUserIds;
1248 }
1249
1250 /**
1251 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1252 *
1253 * <p>A single new permission can be split off from several source permissions. In this case
1254 * the most leniant state is inherited.
1255 *
1256 * <p>Warning: This does not handle foreground / background permissions
1257 *
1258 * @param sourcePerms The permissions to inherit from
1259 * @param newPerm The permission to inherit to
1260 * @param ps The permission state of the package
1261 * @param pkg The package requesting the permissions
1262 * @param userId The user the permission belongs to
1263 */
1264 private void inheritPermissionStateToNewImplicitPermissionLocked(
1265 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1266 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1267 @UserIdInt int userId) {
1268 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1269 String pkgName = pkg.packageName;
1270
1271 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1272 if (permissionToOp(newPerm) != null) {
1273 int mostLenientSourceMode = MODE_ERRORED;
1274
1275 // Find most lenient source permission state.
1276 int numSourcePerms = sourcePerms.size();
1277 for (int i = 0; i < numSourcePerms; i++) {
1278 String sourcePerm = sourcePerms.valueAt(i);
1279
1280 if (ps.hasRuntimePermission(sourcePerm, userId)) {
1281 String sourceOp = permissionToOp(sourcePerm);
1282
1283 if (sourceOp != null) {
1284 int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
1285 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
1286
1287 if (mode == MODE_FOREGROUND) {
1288 throw new IllegalArgumentException("split permission" + sourcePerm
1289 + " has app-op state " + AppOpsManager.MODE_NAMES[mode]);
1290 }
1291
1292 // Leniency order: allowed > ignored > default
1293 if (mode == MODE_ALLOWED) {
1294 mostLenientSourceMode = MODE_ALLOWED;
1295 break;
1296 } else if (mode == MODE_IGNORED) {
1297 mostLenientSourceMode = MODE_IGNORED;
1298 } else if (mode == MODE_DEFAULT
1299 && mostLenientSourceMode != MODE_IGNORED) {
1300 mostLenientSourceMode = MODE_DEFAULT;
1301 }
1302 }
1303 }
1304 }
1305
1306 if (mostLenientSourceMode != MODE_ERRORED) {
1307 if (DEBUG_PERMISSIONS) {
1308 Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
1309 + " from " + sourcePerms + " for " + pkgName);
1310 }
1311
1312 setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
1313 }
1314 }
1315 } else {
1316 boolean isGranted = false;
1317
1318 int numSourcePerm = sourcePerms.size();
1319 for (int i = 0; i < numSourcePerm; i++) {
1320 String sourcePerm = sourcePerms.valueAt(i);
1321 if (ps.hasRuntimePermission(sourcePerm, userId)
1322 && ps.getRuntimePermissionState(sourcePerm, userId).isGranted()) {
1323 isGranted = true;
1324 break;
Zimuzoc1537dc2018-11-15 21:36:21 +00001325 } else if (ps.hasInstallPermission(sourcePerm)) {
1326 isGranted = true;
1327 break;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001328 }
1329 }
1330
1331 if (isGranted) {
1332 if (DEBUG_PERMISSIONS) {
1333 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1334 + " for " + pkgName);
1335 }
1336
1337 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1338 }
1339 }
1340 }
1341
1342 /**
1343 * Set the state of a implicit permission that is seen for the first time.
1344 *
1345 * @param origPs The permission state of the package before the split
1346 * @param ps The new permission state
1347 * @param pkg The package the permission belongs to
1348 * @param updatedUserIds List of users for which the permission state has already been changed
1349 *
1350 * @return List of users for which the permission state has been changed
1351 */
1352 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1353 @NonNull PermissionsState origPs,
1354 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1355 @NonNull int[] updatedUserIds) {
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001356 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1357
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001358 String pkgName = pkg.packageName;
1359 ArraySet<String> newImplicitPermissions = new ArraySet<>();
1360
1361 int numRequestedPerms = pkg.requestedPermissions.size();
1362 for (int i = 0; i < numRequestedPerms; i++) {
1363 BasePermission bp = mSettings.getPermissionLocked(pkg.requestedPermissions.get(i));
1364 if (bp != null) {
1365 String perm = bp.getName();
1366
1367 if (!origPs.hasRequestedPermission(perm) && pkg.implicitPermissions.contains(
1368 perm)) {
1369 newImplicitPermissions.add(perm);
1370
1371 if (DEBUG_PERMISSIONS) {
1372 Slog.i(TAG, perm + " is newly added for " + pkgName);
1373 }
1374 }
1375 }
1376 }
1377
1378 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1379
1380 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1381 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1382 PermissionManager.SplitPermissionInfo spi =
1383 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1384
1385 List<String> newPerms = spi.getNewPermissions();
1386 int numNewPerms = newPerms.size();
1387 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1388 String newPerm = newPerms.get(newPermNum);
1389
1390 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1391 if (splitPerms == null) {
1392 splitPerms = new ArraySet<>();
1393 newToSplitPerms.put(newPerm, splitPerms);
1394 }
1395
1396 splitPerms.add(spi.getSplitPermission());
1397 }
1398 }
1399
1400 int numNewImplicitPerms = newImplicitPermissions.size();
1401 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1402 newImplicitPermNum++) {
1403 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1404 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1405
1406 if (sourcePerms != null) {
1407 if (!ps.hasInstallPermission(newPerm)) {
1408 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1409
1410 int[] users = UserManagerService.getInstance().getUserIds();
1411 int numUsers = users.length;
1412 for (int userNum = 0; userNum < numUsers; userNum++) {
1413 int userId = users[userNum];
1414
1415 ps.updatePermissionFlags(bp, userId,
1416 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1417 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1418 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1419
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001420 // SPECIAL BEHAVIOR for background location. Foreground only by default.
1421 if (newPerm.equals(ACCESS_BACKGROUND_LOCATION)) {
1422 int numSourcePerms = sourcePerms.size();
1423 for (int sourcePermNum = 0; sourcePermNum < numSourcePerms;
1424 sourcePermNum++) {
1425 String sourcePerm = sourcePerms.valueAt(sourcePermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001426
Philip P. Moltmann125c6ee2018-12-20 10:38:18 -08001427 if (ps.hasRuntimePermission(sourcePerm, userId)
1428 && ps.getRuntimePermissionState(sourcePerm, userId)
1429 .isGranted()
1430 && appOpsManager.unsafeCheckOpNoThrow(
1431 permissionToOp(sourcePerm), getUid(userId,
1432 getAppId(pkg.applicationInfo.uid)), pkgName)
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001433 == MODE_ALLOWED) {
1434 setAppOpMode(sourcePerm, pkg, userId, MODE_FOREGROUND);
1435 }
1436 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001437 } else {
Zimuzoc1537dc2018-11-15 21:36:21 +00001438 boolean inheritsFromInstallPerm = false;
1439 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1440 sourcePermNum++) {
1441 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1442 inheritsFromInstallPerm = true;
1443 break;
1444 }
1445 }
1446
1447 if (!origPs.hasRequestedPermission(sourcePerms)
1448 && !inheritsFromInstallPerm) {
1449 // Both permissions are new so nothing to inherit.
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001450 if (DEBUG_PERMISSIONS) {
1451 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1452 + " for " + pkgName
1453 + " as split permission is also new");
1454 }
1455
1456 break;
1457 } else {
Zimuzoc1537dc2018-11-15 21:36:21 +00001458 // Inherit from new install or existing runtime permissions
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001459 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1460 newPerm, ps, pkg, userId);
1461 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001462 }
1463 }
1464 }
1465 }
1466 }
1467
1468 return updatedUserIds;
1469 }
1470
Philip P. Moltmanndde07852019-01-25 16:42:36 -08001471 /**
1472 * Fix app-op modes for runtime permissions.
1473 *
1474 * @param permsState The state of the permissions of the package
1475 * @param pkg The package information
1476 */
1477 private void setAppOpsLocked(@NonNull PermissionsState permsState,
1478 @NonNull PackageParser.Package pkg) {
1479 for (int userId : UserManagerService.getInstance().getUserIds()) {
1480 int numPerms = pkg.requestedPermissions.size();
1481 for (int i = 0; i < numPerms; i++) {
1482 String permission = pkg.requestedPermissions.get(i);
1483
1484 int op = permissionToOpCode(permission);
1485 if (op == OP_NONE) {
1486 continue;
1487 }
1488
1489 // Runtime permissions are per uid, not per package, hence per package app-op
1490 // modes should never have been set. It is possible to set them via the shell
1491 // though. Revert such settings during boot to get the device back into a good
1492 // state.
1493 LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
1494 op, getUid(userId, getAppId(pkg.applicationInfo.uid)));
1495
1496 // For pre-M apps the runtime permission do not store the state
1497 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1498 continue;
1499 }
1500
1501 PermissionState state = permsState.getRuntimePermissionState(permission, userId);
1502 if (state == null) {
1503 continue;
1504 }
1505
1506 // Adjust app-op mods for foreground/background permissions. If an package used to
1507 // have both fg and bg permission granted and it lost the bg permission during an
1508 // upgrade the app-op mode should get downgraded to foreground.
1509 if (state.isGranted()) {
1510 BasePermission bp = mSettings.getPermission(permission);
1511
1512 if (bp != null && bp.perm != null && bp.perm.info != null
1513 && bp.perm.info.backgroundPermission != null) {
1514 PermissionState bgState = permsState.getRuntimePermissionState(
1515 bp.perm.info.backgroundPermission, userId);
1516
1517 setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
1518 ? MODE_ALLOWED : MODE_FOREGROUND);
1519 }
1520 }
1521 }
1522 }
1523 }
1524
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001525 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1526 boolean allowed = false;
1527 final int NP = PackageParser.NEW_PERMISSIONS.length;
1528 for (int ip=0; ip<NP; ip++) {
1529 final PackageParser.NewPermissionInfo npi
1530 = PackageParser.NEW_PERMISSIONS[ip];
1531 if (npi.name.equals(perm)
1532 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1533 allowed = true;
1534 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1535 + pkg.packageName);
1536 break;
1537 }
1538 }
1539 return allowed;
1540 }
1541
1542 /**
1543 * Determines whether a package is whitelisted for a particular privapp permission.
1544 *
1545 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1546 *
1547 * <p>This handles parent/child apps.
1548 */
1549 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001550 ArraySet<String> wlPermissions = null;
1551 if (pkg.isVendor()) {
1552 wlPermissions =
1553 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1554 } else if (pkg.isProduct()) {
1555 wlPermissions =
1556 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001557 } else if (pkg.isProductServices()) {
1558 wlPermissions =
1559 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1560 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001561 } else {
1562 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1563 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001564 // Let's check if this package is whitelisted...
1565 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1566 // If it's not, we'll also tail-recurse to the parent.
1567 return whitelisted ||
1568 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1569 }
1570
1571 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1572 BasePermission bp, PermissionsState origPermissions) {
1573 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001574 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1575 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001576 boolean privappPermissionsDisable =
1577 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1578 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1579 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1580 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1581 && !platformPackage && platformPermission) {
1582 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001583 // Only report violations for apps on system image
1584 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1585 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001586 ArraySet<String> deniedPermissions = null;
1587 if (pkg.isVendor()) {
1588 deniedPermissions = SystemConfig.getInstance()
1589 .getVendorPrivAppDenyPermissions(pkg.packageName);
1590 } else if (pkg.isProduct()) {
1591 deniedPermissions = SystemConfig.getInstance()
1592 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001593 } else if (pkg.isProductServices()) {
1594 deniedPermissions = SystemConfig.getInstance()
1595 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001596 } else {
1597 deniedPermissions = SystemConfig.getInstance()
1598 .getPrivAppDenyPermissions(pkg.packageName);
1599 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001600 final boolean permissionViolation =
1601 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001602 if (permissionViolation) {
1603 Slog.w(TAG, "Privileged permission " + perm + " for package "
1604 + pkg.packageName + " - not in privapp-permissions whitelist");
1605
1606 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1607 if (mPrivappPermissionsViolations == null) {
1608 mPrivappPermissionsViolations = new ArraySet<>();
1609 }
1610 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001611 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001612 } else {
1613 return false;
1614 }
1615 }
1616 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1617 return false;
1618 }
1619 }
1620 }
1621 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1622 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1623 final PackageParser.Package systemPackage =
1624 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001625
1626 // check if the package is allow to use this signature permission. A package is allowed to
1627 // use a signature permission if:
1628 // - it has the same set of signing certificates as the source package
1629 // - or its signing certificate was rotated from the source package's certificate
1630 // - or its signing certificate is a previous signing certificate of the defining
1631 // package, and the defining package still trusts the old certificate for permissions
1632 // - or it shares the above relationships with the system package
1633 boolean allowed =
1634 pkg.mSigningDetails.hasAncestorOrSelf(
1635 bp.getSourcePackageSetting().getSigningDetails())
1636 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1637 pkg.mSigningDetails,
1638 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1639 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1640 || systemPackage.mSigningDetails.checkCapability(
1641 pkg.mSigningDetails,
1642 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001643 if (!allowed && (privilegedPermission || oemPermission)) {
1644 if (pkg.isSystem()) {
1645 // For updated system applications, a privileged/oem permission
1646 // is granted only if it had been defined by the original application.
1647 if (pkg.isUpdatedSystemApp()) {
1648 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001649 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001650 final PackageSetting disabledPs =
1651 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1652 if (disabledPs != null
1653 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1654 // If the original was granted this permission, we take
1655 // that grant decision as read and propagate it to the
1656 // update.
1657 if ((privilegedPermission && disabledPs.isPrivileged())
1658 || (oemPermission && disabledPs.isOem()
1659 && canGrantOemPermission(disabledPs, perm))) {
1660 allowed = true;
1661 }
1662 } else {
1663 // The system apk may have been updated with an older
1664 // version of the one on the data partition, but which
1665 // granted a new system permission that it didn't have
1666 // before. In this case we do want to allow the app to
1667 // now get the new permission if the ancestral apk is
1668 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001669 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001670 && isPackageRequestingPermission(disabledPkg, perm)
1671 && ((privilegedPermission && disabledPs.isPrivileged())
1672 || (oemPermission && disabledPs.isOem()
1673 && canGrantOemPermission(disabledPs, perm)))) {
1674 allowed = true;
1675 }
1676 // Also if a privileged parent package on the system image or any of
1677 // its children requested a privileged/oem permission, the updated child
1678 // packages can also get the permission.
1679 if (pkg.parentPackage != null) {
1680 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001681 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001682 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1683 ? (PackageSetting) disabledParentPkg.mExtras : null;
1684 if (disabledParentPkg != null
1685 && ((privilegedPermission && disabledParentPs.isPrivileged())
1686 || (oemPermission && disabledParentPs.isOem()))) {
1687 if (isPackageRequestingPermission(disabledParentPkg, perm)
1688 && canGrantOemPermission(disabledParentPs, perm)) {
1689 allowed = true;
1690 } else if (disabledParentPkg.childPackages != null) {
1691 for (PackageParser.Package disabledChildPkg
1692 : disabledParentPkg.childPackages) {
1693 final PackageSetting disabledChildPs =
1694 (disabledChildPkg != null)
1695 ? (PackageSetting) disabledChildPkg.mExtras
1696 : null;
1697 if (isPackageRequestingPermission(disabledChildPkg, perm)
1698 && canGrantOemPermission(
1699 disabledChildPs, perm)) {
1700 allowed = true;
1701 break;
1702 }
1703 }
1704 }
1705 }
1706 }
1707 }
1708 } else {
1709 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1710 allowed = (privilegedPermission && pkg.isPrivileged())
1711 || (oemPermission && pkg.isOem()
1712 && canGrantOemPermission(ps, perm));
1713 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001714 // In any case, don't grant a privileged permission to privileged vendor apps, if
1715 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1716 // flag.
1717 if (allowed && privilegedPermission &&
1718 !vendorPrivilegedPermission && pkg.isVendor()) {
1719 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1720 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1721 allowed = false;
1722 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001723 }
1724 }
1725 if (!allowed) {
1726 if (!allowed
1727 && bp.isPre23()
1728 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1729 // If this was a previously normal/dangerous permission that got moved
1730 // to a system permission as part of the runtime permission redesign, then
1731 // we still want to blindly grant it to old apps.
1732 allowed = true;
1733 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001734 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1735 // need a separate flag anymore. Hence we need to check which
1736 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001737 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001738 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1739 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1740 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1741 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1742 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001743 // If this permission is to be granted to the system installer and
1744 // this app is an installer, then it gets the permission.
1745 allowed = true;
1746 }
1747 if (!allowed && bp.isVerifier()
1748 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1749 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1750 // If this permission is to be granted to the system verifier and
1751 // this app is a verifier, then it gets the permission.
1752 allowed = true;
1753 }
1754 if (!allowed && bp.isPreInstalled()
1755 && pkg.isSystem()) {
1756 // Any pre-installed system app is allowed to get this permission.
1757 allowed = true;
1758 }
1759 if (!allowed && bp.isDevelopment()) {
1760 // For development permissions, a development permission
1761 // is granted only if it was already granted.
1762 allowed = origPermissions.hasInstallPermission(perm);
1763 }
1764 if (!allowed && bp.isSetup()
1765 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1766 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1767 // If this permission is to be granted to the system setup wizard and
1768 // this app is a setup wizard, then it gets the permission.
1769 allowed = true;
1770 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001771 if (!allowed && bp.isSystemTextClassifier()
1772 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1773 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1774 UserHandle.USER_SYSTEM))) {
1775 // Special permissions for the system default text classifier.
1776 allowed = true;
1777 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001778 if (!allowed && bp.isConfigurator()
1779 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1780 PackageManagerInternal.PACKAGE_CONFIGURATOR,
1781 UserHandle.USER_SYSTEM))) {
1782 // Special permissions for the device configurator.
1783 allowed = true;
1784 }
Varun Shah5f303652018-11-16 18:11:19 -08001785 if (!allowed && bp.isWellbeing()
1786 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1787 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
1788 // Special permission granted only to the OEM specified wellbeing app
1789 allowed = true;
1790 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07001791 if (!allowed && bp.isDocumenter()
1792 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1793 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
1794 // If this permission is to be granted to the documenter and
1795 // this app is the documenter, then it gets the permission.
1796 allowed = true;
1797 }
Joe Onorato5a15b552018-12-18 10:40:04 -08001798 if (!allowed && bp.isIncidentReportApprover()
1799 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1800 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
1801 UserHandle.USER_SYSTEM))) {
1802 // If this permission is to be granted to the incident report approver and
1803 // this app is the incident report approver, then it gets the permission.
1804 allowed = true;
1805 }
George Hodulikcd7695d2019-01-29 18:17:05 -08001806 if (!allowed && bp.isAppPredictor()
1807 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1808 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
1809 // Special permissions for the system app predictor.
1810 allowed = true;
1811 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001812 }
1813 return allowed;
1814 }
1815
1816 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1817 if (!ps.isOem()) {
1818 return false;
1819 }
1820 // all oem permissions must explicitly be granted or denied
1821 final Boolean granted =
1822 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1823 if (granted == null) {
1824 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1825 + ps.name + " must be explicitly declared granted or not");
1826 }
1827 return Boolean.TRUE == granted;
1828 }
1829
1830 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001831 // Permission review applies only to apps not supporting the new permission model.
1832 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1833 return false;
1834 }
1835
1836 // Legacy apps have the permission and get user consent on launch.
1837 if (pkg == null || pkg.mExtras == null) {
1838 return false;
1839 }
1840 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1841 final PermissionsState permissionsState = ps.getPermissionsState();
1842 return permissionsState.isPermissionReviewRequired(userId);
1843 }
1844
1845 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1846 final int permCount = pkg.requestedPermissions.size();
1847 for (int j = 0; j < permCount; j++) {
1848 String requestedPermission = pkg.requestedPermissions.get(j);
1849 if (permission.equals(requestedPermission)) {
1850 return true;
1851 }
1852 }
1853 return false;
1854 }
1855
Andreas Gampea36dc622018-02-05 17:19:22 -08001856 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001857 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1858 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1859 if (pkg.parentPackage == null) {
1860 return;
1861 }
1862 if (pkg.requestedPermissions == null) {
1863 return;
1864 }
1865 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001866 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001867 if (disabledPkg == null || disabledPkg.mExtras == null) {
1868 return;
1869 }
1870 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1871 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1872 return;
1873 }
1874 final int permCount = pkg.requestedPermissions.size();
1875 for (int i = 0; i < permCount; i++) {
1876 String permission = pkg.requestedPermissions.get(i);
1877 BasePermission bp = mSettings.getPermissionLocked(permission);
1878 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1879 continue;
1880 }
1881 for (int userId : mUserManagerInt.getUserIds()) {
1882 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1883 grantRuntimePermission(
1884 permission, pkg.packageName, false, callingUid, userId, callback);
1885 }
1886 }
1887 }
1888 }
1889
1890 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1891 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1892 for (int userId : userIds) {
1893 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1894 callback);
1895 }
1896 }
1897
1898 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1899 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1900 PackageSetting ps = (PackageSetting) pkg.mExtras;
1901 if (ps == null) {
1902 return;
1903 }
1904
1905 PermissionsState permissionsState = ps.getPermissionsState();
1906
1907 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1908 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1909
1910 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1911 >= Build.VERSION_CODES.M;
1912
1913 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1914
1915 for (String permission : pkg.requestedPermissions) {
1916 final BasePermission bp;
1917 synchronized (mLock) {
1918 bp = mSettings.getPermissionLocked(permission);
1919 }
1920 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1921 && (!instantApp || bp.isInstant())
1922 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1923 && (grantedPermissions == null
1924 || ArrayUtils.contains(grantedPermissions, permission))) {
1925 final int flags = permissionsState.getPermissionFlags(permission, userId);
1926 if (supportsRuntimePermissions) {
1927 // Installer cannot change immutable permissions.
1928 if ((flags & immutableFlags) == 0) {
1929 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1930 userId, callback);
1931 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001932 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001933 // In permission review mode we clear the review flag when we
1934 // are asked to install the app with all permissions granted.
1935 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1936 updatePermissionFlags(permission, pkg.packageName,
1937 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08001938 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001939 }
1940 }
1941 }
1942 }
1943 }
1944
1945 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1946 int callingUid, final int userId, PermissionCallback callback) {
1947 if (!mUserManagerInt.exists(userId)) {
1948 Log.e(TAG, "No such user:" + userId);
1949 return;
1950 }
1951
1952 mContext.enforceCallingOrSelfPermission(
1953 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1954 "grantRuntimePermission");
1955
1956 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001957 true, // requireFullPermission
1958 true, // checkShell
1959 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001960 "grantRuntimePermission");
1961
1962 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1963 if (pkg == null || pkg.mExtras == null) {
1964 throw new IllegalArgumentException("Unknown package: " + packageName);
1965 }
1966 final BasePermission bp;
1967 synchronized(mLock) {
1968 bp = mSettings.getPermissionLocked(permName);
1969 }
1970 if (bp == null) {
1971 throw new IllegalArgumentException("Unknown permission: " + permName);
1972 }
1973 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1974 throw new IllegalArgumentException("Unknown package: " + packageName);
1975 }
1976
1977 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1978
1979 // If a permission review is required for legacy apps we represent
1980 // their permissions as always granted runtime ones since we need
1981 // to keep the review required permission flag per user while an
1982 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001983 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001984 && bp.isRuntime()) {
1985 return;
1986 }
1987
1988 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1989
1990 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1991 final PermissionsState permissionsState = ps.getPermissionsState();
1992
1993 final int flags = permissionsState.getPermissionFlags(permName, userId);
1994 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1995 throw new SecurityException("Cannot grant system fixed permission "
1996 + permName + " for package " + packageName);
1997 }
1998 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1999 throw new SecurityException("Cannot grant policy fixed permission "
2000 + permName + " for package " + packageName);
2001 }
2002
2003 if (bp.isDevelopment()) {
2004 // Development permissions must be handled specially, since they are not
2005 // normal runtime permissions. For now they apply to all users.
2006 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002007 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002008 if (callback != null) {
2009 callback.onInstallPermissionGranted();
2010 }
2011 }
2012 return;
2013 }
2014
2015 if (ps.getInstantApp(userId) && !bp.isInstant()) {
2016 throw new SecurityException("Cannot grant non-ephemeral permission"
2017 + permName + " for package " + packageName);
2018 }
2019
2020 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2021 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2022 return;
2023 }
2024
2025 final int result = permissionsState.grantRuntimePermission(bp, userId);
2026 switch (result) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002027 case PERMISSION_OPERATION_FAILURE: {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002028 return;
2029 }
2030
2031 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2032 if (callback != null) {
2033 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2034 }
2035 }
2036 break;
2037 }
2038
2039 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002040 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002041 }
2042
2043 if (callback != null) {
2044 callback.onPermissionGranted(uid, userId);
2045 }
2046
2047 // Only need to do this if user is initialized. Otherwise it's a new user
2048 // and there are no processes running as the user yet and there's no need
2049 // to make an expensive call to remount processes for the changed permissions.
2050 if (READ_EXTERNAL_STORAGE.equals(permName)
2051 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2052 final long token = Binder.clearCallingIdentity();
2053 try {
2054 if (mUserManagerInt.isUserInitialized(userId)) {
2055 StorageManagerInternal storageManagerInternal = LocalServices.getService(
2056 StorageManagerInternal.class);
2057 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2058 }
2059 } finally {
2060 Binder.restoreCallingIdentity(token);
2061 }
2062 }
2063
2064 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002065
2066 private void revokeRuntimePermission(String permName, String packageName,
2067 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002068 if (!mUserManagerInt.exists(userId)) {
2069 Log.e(TAG, "No such user:" + userId);
2070 return;
2071 }
2072
2073 mContext.enforceCallingOrSelfPermission(
2074 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2075 "revokeRuntimePermission");
2076
2077 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002078 true, // requireFullPermission
2079 true, // checkShell
2080 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002081 "revokeRuntimePermission");
2082
2083 final int appId;
2084
2085 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2086 if (pkg == null || pkg.mExtras == null) {
2087 throw new IllegalArgumentException("Unknown package: " + packageName);
2088 }
2089 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2090 throw new IllegalArgumentException("Unknown package: " + packageName);
2091 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002092 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002093 if (bp == null) {
2094 throw new IllegalArgumentException("Unknown permission: " + permName);
2095 }
2096
2097 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2098
2099 // If a permission review is required for legacy apps we represent
2100 // their permissions as always granted runtime ones since we need
2101 // to keep the review required permission flag per user while an
2102 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002103 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002104 && bp.isRuntime()) {
2105 return;
2106 }
2107
2108 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2109 final PermissionsState permissionsState = ps.getPermissionsState();
2110
2111 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07002112 // Only the system may revoke SYSTEM_FIXED permissions.
2113 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2114 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2115 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002116 + permName + " for package " + packageName);
2117 }
2118 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2119 throw new SecurityException("Cannot revoke policy fixed permission "
2120 + permName + " for package " + packageName);
2121 }
2122
2123 if (bp.isDevelopment()) {
2124 // Development permissions must be handled specially, since they are not
2125 // normal runtime permissions. For now they apply to all users.
2126 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002127 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002128 if (callback != null) {
2129 callback.onInstallPermissionRevoked();
2130 }
2131 }
2132 return;
2133 }
2134
2135 if (permissionsState.revokeRuntimePermission(bp, userId) ==
Philip P. Moltmann48456672019-01-20 13:14:03 -08002136 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002137 return;
2138 }
2139
2140 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002141 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002142 }
2143
2144 if (callback != null) {
2145 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2146 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2147 }
2148 }
2149
Andreas Gampea36dc622018-02-05 17:19:22 -08002150 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002151 private int[] revokeUnusedSharedUserPermissionsLocked(
2152 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002153 // Collect all used permissions in the UID
2154 final ArraySet<String> usedPermissions = new ArraySet<>();
2155 final List<PackageParser.Package> pkgList = suSetting.getPackages();
2156 if (pkgList == null || pkgList.size() == 0) {
2157 return EmptyArray.INT;
2158 }
2159 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07002160 if (pkg.requestedPermissions == null) {
2161 continue;
2162 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002163 final int requestedPermCount = pkg.requestedPermissions.size();
2164 for (int j = 0; j < requestedPermCount; j++) {
2165 String permission = pkg.requestedPermissions.get(j);
2166 BasePermission bp = mSettings.getPermissionLocked(permission);
2167 if (bp != null) {
2168 usedPermissions.add(permission);
2169 }
2170 }
2171 }
2172
2173 PermissionsState permissionsState = suSetting.getPermissionsState();
2174 // Prune install permissions
2175 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2176 final int installPermCount = installPermStates.size();
2177 for (int i = installPermCount - 1; i >= 0; i--) {
2178 PermissionState permissionState = installPermStates.get(i);
2179 if (!usedPermissions.contains(permissionState.getName())) {
2180 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2181 if (bp != null) {
2182 permissionsState.revokeInstallPermission(bp);
2183 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
2184 PackageManager.MASK_PERMISSION_FLAGS, 0);
2185 }
2186 }
2187 }
2188
2189 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2190
2191 // Prune runtime permissions
2192 for (int userId : allUserIds) {
2193 List<PermissionState> runtimePermStates = permissionsState
2194 .getRuntimePermissionStates(userId);
2195 final int runtimePermCount = runtimePermStates.size();
2196 for (int i = runtimePermCount - 1; i >= 0; i--) {
2197 PermissionState permissionState = runtimePermStates.get(i);
2198 if (!usedPermissions.contains(permissionState.getName())) {
2199 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2200 if (bp != null) {
2201 permissionsState.revokeRuntimePermission(bp, userId);
2202 permissionsState.updatePermissionFlags(bp, userId,
2203 PackageManager.MASK_PERMISSION_FLAGS, 0);
2204 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2205 runtimePermissionChangedUserIds, userId);
2206 }
2207 }
2208 }
2209 }
2210
2211 return runtimePermissionChangedUserIds;
2212 }
2213
Todd Kennedyc8423932017-10-05 08:58:36 -07002214 private String[] getAppOpPermissionPackages(String permName) {
2215 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2216 return null;
2217 }
2218 synchronized (mLock) {
2219 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2220 if (pkgs == null) {
2221 return null;
2222 }
2223 return pkgs.toArray(new String[pkgs.size()]);
2224 }
2225 }
2226
2227 private int getPermissionFlags(
2228 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002229 if (!mUserManagerInt.exists(userId)) {
2230 return 0;
2231 }
2232
2233 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
2234
2235 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002236 true, // requireFullPermission
2237 false, // checkShell
2238 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002239 "getPermissionFlags");
2240
2241 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2242 if (pkg == null || pkg.mExtras == null) {
2243 return 0;
2244 }
2245 synchronized (mLock) {
2246 if (mSettings.getPermissionLocked(permName) == null) {
2247 return 0;
2248 }
2249 }
2250 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2251 return 0;
2252 }
2253 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2254 PermissionsState permissionsState = ps.getPermissionsState();
2255 return permissionsState.getPermissionFlags(permName, userId);
2256 }
2257
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002258 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2259 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2260 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2261
2262 private void updatePermissions(String packageName, PackageParser.Package pkg,
2263 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2264 PermissionCallback callback) {
2265 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2266 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2267 updatePermissions(
2268 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2269 if (pkg != null && pkg.childPackages != null) {
2270 for (PackageParser.Package childPkg : pkg.childPackages) {
2271 updatePermissions(childPkg.packageName, childPkg,
2272 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2273 }
2274 }
2275 }
2276
2277 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2278 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2279 final int flags = UPDATE_PERMISSIONS_ALL |
2280 (sdkUpdated
2281 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2282 : 0);
2283 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2284 }
2285
2286 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2287 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2288 PermissionCallback callback) {
2289 // TODO: Most of the methods exposing BasePermission internals [source package name,
2290 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2291 // have package settings, we should make note of it elsewhere [map between
2292 // source package name and BasePermission] and cycle through that here. Then we
2293 // define a single method on BasePermission that takes a PackageSetting, changing
2294 // package name and a package.
2295 // NOTE: With this approach, we also don't need to tree trees differently than
2296 // normal permissions. Today, we need two separate loops because these BasePermission
2297 // objects are stored separately.
2298 // Make sure there are no dangling permission trees.
2299 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2300
2301 // Make sure all dynamic permissions have been assigned to a package,
2302 // and make sure there are no dangling permissions.
2303 flags = updatePermissions(changingPkgName, changingPkg, flags);
2304
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002305 synchronized (mLock) {
2306 if (mBackgroundPermissions == null) {
2307 // Cache background -> foreground permission mapping.
2308 // Only system declares background permissions, hence mapping does never change.
2309 mBackgroundPermissions = new ArrayMap<>();
2310 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002311 if (bp.perm != null && bp.perm.info != null
2312 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002313 String fgPerm = bp.name;
2314 String bgPerm = bp.perm.info.backgroundPermission;
2315
2316 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2317 if (fgPerms == null) {
2318 fgPerms = new ArrayList<>();
2319 mBackgroundPermissions.put(bgPerm, fgPerms);
2320 }
2321
2322 fgPerms.add(fgPerm);
2323 }
2324 }
2325 }
2326 }
2327
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002328 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002329 // Now update the permissions for all packages, in particular
2330 // replace the granted permissions of the system packages.
2331 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2332 for (PackageParser.Package pkg : allPackages) {
2333 if (pkg != changingPkg) {
2334 // Only replace for packages on requested volume
2335 final String volumeUuid = getVolumeUuidForPackage(pkg);
2336 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2337 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002338 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002339 }
2340 }
2341 }
2342
2343 if (changingPkg != null) {
2344 // Only replace for packages on requested volume
2345 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2346 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2347 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002348 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002349 }
2350 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2351 }
2352
2353 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002354 Set<BasePermission> needsUpdate = null;
2355 synchronized (mLock) {
2356 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2357 while (it.hasNext()) {
2358 final BasePermission bp = it.next();
2359 if (bp.isDynamic()) {
2360 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2361 }
2362 if (bp.getSourcePackageSetting() != null) {
2363 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002364 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002365 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2366 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002367 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002368 it.remove();
2369 }
2370 continue;
2371 }
2372 if (needsUpdate == null) {
2373 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2374 }
2375 needsUpdate.add(bp);
2376 }
2377 }
2378 if (needsUpdate != null) {
2379 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002380 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002381 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2382 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002383 if (sourcePkg != null && sourcePkg.mExtras != null) {
2384 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002385 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002386 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002387 }
2388 continue;
2389 }
2390 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2391 + " from package " + bp.getSourcePackageName());
2392 mSettings.removePermissionLocked(bp.getName());
2393 }
2394 }
2395 }
2396 return flags;
2397 }
2398
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002399 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002400 int flags) {
2401 Set<BasePermission> needsUpdate = null;
2402 synchronized (mLock) {
2403 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2404 while (it.hasNext()) {
2405 final BasePermission bp = it.next();
2406 if (bp.getSourcePackageSetting() != null) {
2407 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002408 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002409 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2410 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002411 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002412 it.remove();
2413 }
2414 continue;
2415 }
2416 if (needsUpdate == null) {
2417 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2418 }
2419 needsUpdate.add(bp);
2420 }
2421 }
2422 if (needsUpdate != null) {
2423 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002424 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002425 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2426 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002427 if (sourcePkg != null && sourcePkg.mExtras != null) {
2428 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002429 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002430 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002431 }
2432 continue;
2433 }
2434 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2435 + " from package " + bp.getSourcePackageName());
2436 mSettings.removePermissionLocked(bp.getName());
2437 }
2438 }
2439 }
2440 return flags;
2441 }
2442
Todd Kennedy0eb97382017-10-03 16:57:22 -07002443 private void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002444 int flagValues, int callingUid, int userId, boolean overridePolicy,
2445 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002446 if (!mUserManagerInt.exists(userId)) {
2447 return;
2448 }
2449
2450 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2451
2452 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002453 true, // requireFullPermission
2454 true, // checkShell
2455 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002456 "updatePermissionFlags");
2457
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002458 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2459 throw new SecurityException("updatePermissionFlags requires "
2460 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2461 }
2462
Todd Kennedy0eb97382017-10-03 16:57:22 -07002463 // Only the system can change these flags and nothing else.
2464 if (callingUid != Process.SYSTEM_UID) {
2465 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2466 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2467 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2468 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2469 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2470 }
2471
2472 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2473 if (pkg == null || pkg.mExtras == null) {
2474 throw new IllegalArgumentException("Unknown package: " + packageName);
2475 }
2476 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2477 throw new IllegalArgumentException("Unknown package: " + packageName);
2478 }
2479
2480 final BasePermission bp;
2481 synchronized (mLock) {
2482 bp = mSettings.getPermissionLocked(permName);
2483 }
2484 if (bp == null) {
2485 throw new IllegalArgumentException("Unknown permission: " + permName);
2486 }
2487
2488 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2489 final PermissionsState permissionsState = ps.getPermissionsState();
2490 final boolean hadState =
2491 permissionsState.getRuntimePermissionState(permName, userId) != null;
2492 final boolean permissionUpdated =
2493 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2494 if (permissionUpdated && callback != null) {
2495 // Install and runtime permissions are stored in different places,
2496 // so figure out what permission changed and persist the change.
2497 if (permissionsState.getInstallPermissionState(permName) != null) {
2498 callback.onInstallPermissionUpdated();
2499 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2500 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002501 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002502 }
2503 }
2504 }
2505
2506 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2507 int userId, Collection<Package> packages, PermissionCallback callback) {
2508 if (!mUserManagerInt.exists(userId)) {
2509 return false;
2510 }
2511
2512 enforceGrantRevokeRuntimePermissionPermissions(
2513 "updatePermissionFlagsForAllApps");
2514 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002515 true, // requireFullPermission
2516 true, // checkShell
2517 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002518 "updatePermissionFlagsForAllApps");
2519
2520 // Only the system can change system fixed flags.
2521 if (callingUid != Process.SYSTEM_UID) {
2522 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2523 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2524 }
2525
2526 boolean changed = false;
2527 for (PackageParser.Package pkg : packages) {
2528 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2529 if (ps == null) {
2530 continue;
2531 }
2532 PermissionsState permissionsState = ps.getPermissionsState();
2533 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2534 userId, flagMask, flagValues);
2535 }
2536 return changed;
2537 }
2538
2539 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2540 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2541 != PackageManager.PERMISSION_GRANTED
2542 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2543 != PackageManager.PERMISSION_GRANTED) {
2544 throw new SecurityException(message + " requires "
2545 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2546 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2547 }
2548 }
2549
2550 /**
2551 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2552 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2553 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2554 * @param message the message to log on security exception
2555 */
2556 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002557 boolean requireFullPermission, boolean checkShell,
2558 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002559 if (userId < 0) {
2560 throw new IllegalArgumentException("Invalid userId " + userId);
2561 }
2562 if (checkShell) {
2563 PackageManagerServiceUtils.enforceShellRestriction(
2564 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2565 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002566 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002567 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002568 if (requireFullPermission) {
2569 mContext.enforceCallingOrSelfPermission(
2570 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2571 } else {
2572 try {
2573 mContext.enforceCallingOrSelfPermission(
2574 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2575 } catch (SecurityException se) {
2576 mContext.enforceCallingOrSelfPermission(
2577 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2578 }
2579 }
2580 }
2581 }
2582
Andreas Gampea71bee82018-07-20 12:55:36 -07002583 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002584 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2585 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002586 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002587 size += tree.calculateFootprint(perm);
2588 }
2589 return size;
2590 }
2591
Andreas Gampea71bee82018-07-20 12:55:36 -07002592 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002593 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2594 // We calculate the max size of permissions defined by this uid and throw
2595 // if that plus the size of 'info' would exceed our stated maximum.
2596 if (tree.getUid() != Process.SYSTEM_UID) {
2597 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2598 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2599 throw new SecurityException("Permission tree size cap exceeded");
2600 }
2601 }
2602 }
2603
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002604 private void systemReady() {
2605 mSystemReady = true;
2606 if (mPrivappPermissionsViolations != null) {
2607 throw new IllegalStateException("Signature|privileged permissions not in "
2608 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2609 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002610
2611 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002612 }
2613
2614 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2615 if (pkg == null) {
2616 return StorageManager.UUID_PRIVATE_INTERNAL;
2617 }
2618 if (pkg.isExternal()) {
2619 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2620 return StorageManager.UUID_PRIMARY_PHYSICAL;
2621 } else {
2622 return pkg.volumeUuid;
2623 }
2624 } else {
2625 return StorageManager.UUID_PRIVATE_INTERNAL;
2626 }
2627 }
2628
Todd Kennedyc8423932017-10-05 08:58:36 -07002629 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2630 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2631 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2632 return true;
2633 }
2634 }
2635 return false;
2636 }
2637
Todd Kennedy0eb97382017-10-03 16:57:22 -07002638 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002639 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002640 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002641 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002642 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002643 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002644 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002645 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2646 final LogMaker log = new LogMaker(action);
2647 log.setPackageName(packageName);
2648 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002649
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002650 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002651 }
2652
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002653 /**
2654 * Get the mapping of background permissions to their foreground permissions.
2655 *
2656 * <p>Only initialized in the system server.
2657 *
2658 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2659 */
2660 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2661 return mBackgroundPermissions;
2662 }
2663
Philip P. Moltmann48456672019-01-20 13:14:03 -08002664 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002665 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002666 public void systemReady() {
2667 PermissionManagerService.this.systemReady();
2668 }
2669 @Override
2670 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2671 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2672 }
2673 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002674 public void revokeRuntimePermissionsIfGroupChanged(
2675 @NonNull PackageParser.Package newPackage,
2676 @NonNull PackageParser.Package oldPackage,
2677 @NonNull ArrayList<String> allPackageNames,
2678 @NonNull PermissionCallback permissionCallback) {
2679 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2680 oldPackage, allPackageNames, permissionCallback);
2681 }
2682 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002683 public void addAllPermissions(Package pkg, boolean chatty) {
2684 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002685 }
2686 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002687 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2688 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2689 }
2690 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00002691 public void removeAllPermissions(Package pkg, boolean chatty) {
2692 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002693 }
2694 @Override
2695 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002696 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002697 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2698 }
2699 @Override
2700 public void removeDynamicPermission(String permName, int callingUid,
2701 PermissionCallback callback) {
2702 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002703 }
2704 @Override
2705 public void grantRuntimePermission(String permName, String packageName,
2706 boolean overridePolicy, int callingUid, int userId,
2707 PermissionCallback callback) {
2708 PermissionManagerService.this.grantRuntimePermission(
2709 permName, packageName, overridePolicy, callingUid, userId, callback);
2710 }
2711 @Override
2712 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2713 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2714 PermissionManagerService.this.grantRequestedRuntimePermissions(
2715 pkg, userIds, grantedPermissions, callingUid, callback);
2716 }
2717 @Override
2718 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2719 int callingUid, PermissionCallback callback) {
2720 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2721 pkg, callingUid, callback);
2722 }
2723 @Override
2724 public void revokeRuntimePermission(String permName, String packageName,
2725 boolean overridePolicy, int callingUid, int userId,
2726 PermissionCallback callback) {
2727 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jinae750fb2018-09-27 23:00:20 +00002728 overridePolicy, callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002729 }
2730 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002731 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2732 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2733 PermissionManagerService.this.updatePermissions(
2734 packageName, pkg, replaceGrant, allPackages, callback);
2735 }
2736 @Override
2737 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2738 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2739 PermissionManagerService.this.updateAllPermissions(
2740 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002741 }
2742 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002743 public String[] getAppOpPermissionPackages(String permName) {
2744 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2745 }
2746 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002747 public int getPermissionFlags(String permName, String packageName, int callingUid,
2748 int userId) {
2749 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2750 callingUid, userId);
2751 }
2752 @Override
2753 public void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002754 int flagValues, int callingUid, int userId, boolean overridePolicy,
2755 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002756 PermissionManagerService.this.updatePermissionFlags(
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002757 permName, packageName, flagMask, flagValues, callingUid, userId,
2758 overridePolicy, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002759 }
2760 @Override
2761 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2762 int userId, Collection<Package> packages, PermissionCallback callback) {
2763 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2764 flagMask, flagValues, callingUid, userId, packages, callback);
2765 }
2766 @Override
2767 public void enforceCrossUserPermission(int callingUid, int userId,
2768 boolean requireFullPermission, boolean checkShell, String message) {
2769 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002770 requireFullPermission, checkShell, false, message);
2771 }
2772 @Override
2773 public void enforceCrossUserPermission(int callingUid, int userId,
2774 boolean requireFullPermission, boolean checkShell,
2775 boolean requirePermissionWhenSameUser, String message) {
2776 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2777 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002778 }
2779 @Override
2780 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2781 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2782 }
2783 @Override
2784 public int checkPermission(String permName, String packageName, int callingUid,
2785 int userId) {
2786 return PermissionManagerService.this.checkPermission(
2787 permName, packageName, callingUid, userId);
2788 }
2789 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002790 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2791 int callingUid) {
2792 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002793 }
2794 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002795 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2796 int callingUid) {
2797 return PermissionManagerService.this.getPermissionGroupInfo(
2798 groupName, flags, callingUid);
2799 }
2800 @Override
2801 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2802 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2803 }
2804 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002805 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2806 int callingUid) {
2807 return PermissionManagerService.this.getPermissionInfo(
2808 permName, packageName, flags, callingUid);
2809 }
2810 @Override
2811 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2812 int callingUid) {
2813 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2814 }
2815 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002816 public PermissionSettings getPermissionSettings() {
2817 return mSettings;
2818 }
2819 @Override
2820 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2821 return mDefaultPermissionGrantPolicy;
2822 }
2823 @Override
2824 public BasePermission getPermissionTEMP(String permName) {
2825 synchronized (PermissionManagerService.this.mLock) {
2826 return mSettings.getPermissionLocked(permName);
2827 }
2828 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002829
2830 @Override
2831 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
2832 return PermissionManagerService.this.backupRuntimePermissions(user);
2833 }
2834
2835 @Override
2836 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
2837 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
2838 }
2839
2840 @Override
2841 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
2842 @NonNull UserHandle user) {
2843 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
2844 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002845 }
2846}