blob: 6fced8acf1dfc9354ad38b46b4df8e8b3ff4f560 [file] [log] [blame]
Todd Kennedy0eb97382017-10-03 16:57:22 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm.permission;
18
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070021import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
22import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070023import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
24import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070025import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann48456672019-01-20 13:14:03 -080026import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070027import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
28import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070034import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Hongwei Wangf391b552018-04-06 13:52:46 -070035import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
36
Todd Kennedyc29b11a2017-10-23 15:55:59 -070037import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
38import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
39import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
40import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
41import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080042import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
43
44import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070045
46import android.Manifest;
47import android.annotation.NonNull;
48import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070049import android.annotation.UserIdInt;
Todd Kennedy0eb97382017-10-03 16:57:22 -070050import android.content.Context;
51import android.content.pm.PackageManager;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070052import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.content.pm.PackageManagerInternal;
54import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070055import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070056import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070057import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070058import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070059import android.os.Binder;
60import android.os.Build;
61import android.os.Handler;
62import android.os.HandlerThread;
63import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070064import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070065import android.os.UserHandle;
66import android.os.UserManager;
67import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070068import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070069import android.os.storage.StorageManagerInternal;
Philip P. Moltmann48456672019-01-20 13:14:03 -080070import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070071import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080072import android.permission.PermissionManagerInternal;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070073import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070074import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070075import android.util.ArrayMap;
76import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070077import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070078import android.util.Log;
79import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070080import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -080081import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070082
Todd Kennedyc29b11a2017-10-23 15:55:59 -070083import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070084import com.android.internal.logging.MetricsLogger;
85import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070086import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070087import com.android.internal.util.ArrayUtils;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070088import com.android.internal.util.function.pooled.PooledLambda;
89import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -070090import com.android.server.LocalServices;
91import com.android.server.ServiceThread;
92import com.android.server.SystemConfig;
93import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070094import com.android.server.pm.PackageManagerServiceUtils;
95import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070097import com.android.server.pm.UserManagerService;
Philip P. Moltmann48456672019-01-20 13:14:03 -080098import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070099import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov0b41c892019-07-26 17:45:56 -0700100import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700101import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700102
103import libcore.util.EmptyArray;
104
105import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700106import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700107import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700108import java.util.Iterator;
109import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700110import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700111import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700112import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800113import java.util.concurrent.CompletableFuture;
114import java.util.concurrent.ExecutionException;
115import java.util.concurrent.TimeUnit;
116import java.util.concurrent.TimeoutException;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700117
118/**
119 * Manages all permissions and handles permissions related tasks.
120 */
121public class PermissionManagerService {
122 private static final String TAG = "PackageManager";
123
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700124 /** Permission grant: not grant the permission. */
125 private static final int GRANT_DENIED = 1;
126 /** Permission grant: grant the permission as an install permission. */
127 private static final int GRANT_INSTALL = 2;
128 /** Permission grant: grant the permission as a runtime one. */
129 private static final int GRANT_RUNTIME = 3;
130 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
131 private static final int GRANT_UPGRADE = 4;
132
Philip P. Moltmann48456672019-01-20 13:14:03 -0800133 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
134
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700135 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
136 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
137 /** Empty array to avoid allocations */
138 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700139
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800140 /**
141 * When these flags are set, the system should not automatically modify the permission grant
142 * state.
143 */
144 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
145 | FLAG_PERMISSION_POLICY_FIXED
146 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
147
148 /** Permission flags set by the user */
149 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
150 | FLAG_PERMISSION_USER_FIXED;
151
Hongwei Wangf391b552018-04-06 13:52:46 -0700152 /** If the permission of the value is granted, so is the key */
153 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
154
155 static {
156 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
157 Manifest.permission.ACCESS_FINE_LOCATION);
158 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
159 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
160 }
161
Todd Kennedy0eb97382017-10-03 16:57:22 -0700162 /** Lock to protect internal data access */
163 private final Object mLock;
164
165 /** Internal connection to the package manager */
166 private final PackageManagerInternal mPackageManagerInt;
167
168 /** Internal connection to the user manager */
169 private final UserManagerInternal mUserManagerInt;
170
Philip P. Moltmann48456672019-01-20 13:14:03 -0800171 /** Permission controller: User space permission management */
172 private PermissionControllerManager mPermissionControllerManager;
173
Todd Kennedy0eb97382017-10-03 16:57:22 -0700174 /** Default permission policy to provide proper behaviour out-of-the-box */
175 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
176
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700177 /**
178 * Built-in permissions. Read from system configuration files. Mapping is from
179 * UID to permission name.
180 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700181 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700182
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700183 /** Built-in group IDs given to all packages. Read from system configuration files. */
184 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700185
186 private final HandlerThread mHandlerThread;
187 private final Handler mHandler;
188 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700189 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700190
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700191 /** Internal storage for permissions and related settings */
192 @GuardedBy("mLock")
193 private final PermissionSettings mSettings;
194
195 @GuardedBy("mLock")
196 private ArraySet<String> mPrivappPermissionsViolations;
197
198 @GuardedBy("mLock")
199 private boolean mSystemReady;
200
Svet Ganov0b41c892019-07-26 17:45:56 -0700201 @GuardedBy("mLock")
202 private PermissionPolicyInternal mPermissionPolicyInternal;
203
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700204 /**
205 * For each foreground/background permission the mapping:
206 * Background permission -> foreground permissions
207 */
208 @GuardedBy("mLock")
209 private ArrayMap<String, List<String>> mBackgroundPermissions;
210
Philip P. Moltmann48456672019-01-20 13:14:03 -0800211 /**
212 * A permission backup might contain apps that are not installed. In this case we delay the
213 * restoration until the app is installed.
214 *
215 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
216 * there is <u>no more</u> delayed backup left.
217 */
218 @GuardedBy("mLock")
219 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
220
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700221 /** Listeners for permission state (granting and flags) changes */
222 @GuardedBy("mLock")
223 final private ArrayList<OnRuntimePermissionStateChangedListener>
224 mRuntimePermissionStateChangedListeners = new ArrayList<>();
225
Todd Kennedy0eb97382017-10-03 16:57:22 -0700226 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700227 @NonNull Object externalLock) {
228 mContext = context;
229 mLock = externalLock;
230 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
231 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700232 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700233
234 mHandlerThread = new ServiceThread(TAG,
235 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
236 mHandlerThread.start();
237 mHandler = new Handler(mHandlerThread.getLooper());
238 Watchdog.getInstance().addThread(mHandler);
239
240 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700241 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700242 SystemConfig systemConfig = SystemConfig.getInstance();
243 mSystemPermissions = systemConfig.getSystemPermissions();
244 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700245
246 // propagate permission configuration
247 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
248 SystemConfig.getInstance().getPermissions();
249 synchronized (mLock) {
250 for (int i=0; i<permConfig.size(); i++) {
251 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
252 BasePermission bp = mSettings.getPermissionLocked(perm.name);
253 if (bp == null) {
254 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
255 mSettings.putPermissionLocked(perm.name, bp);
256 }
257 if (perm.gids != null) {
258 bp.setGids(perm.gids, perm.perUser);
259 }
260 }
261 }
262
Philip P. Moltmann48456672019-01-20 13:14:03 -0800263 PermissionManagerServiceInternalImpl localService =
264 new PermissionManagerServiceInternalImpl();
265 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
266 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700267 }
268
269 /**
270 * Creates and returns an initialized, internal service for use by other components.
271 * <p>
272 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800273 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700274 * <p>
275 * NOTE: The external lock is temporary and should be removed. This needs to be a
276 * lock created by the permission manager itself.
277 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800278 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700279 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800280 final PermissionManagerServiceInternal permMgrInt =
281 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700282 if (permMgrInt != null) {
283 return permMgrInt;
284 }
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700285 new PermissionManagerService(context, externalLock);
Philip P. Moltmann48456672019-01-20 13:14:03 -0800286 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700287 }
288
289 @Nullable BasePermission getPermission(String permName) {
290 synchronized (mLock) {
291 return mSettings.getPermissionLocked(permName);
292 }
293 }
294
295 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
296 if (!mUserManagerInt.exists(userId)) {
297 return PackageManager.PERMISSION_DENIED;
298 }
299
Patrick Baumann97b9b532018-04-11 14:51:30 +0000300 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
301 if (pkg != null && pkg.mExtras != null) {
302 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700303 return PackageManager.PERMISSION_DENIED;
304 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000305 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700306 final boolean instantApp = ps.getInstantApp(userId);
307 final PermissionsState permissionsState = ps.getPermissionsState();
308 if (permissionsState.hasPermission(permName, userId)) {
309 if (instantApp) {
310 synchronized (mLock) {
311 BasePermission bp = mSettings.getPermissionLocked(permName);
312 if (bp != null && bp.isInstant()) {
313 return PackageManager.PERMISSION_GRANTED;
314 }
315 }
316 } else {
317 return PackageManager.PERMISSION_GRANTED;
318 }
319 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700320 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700321 return PackageManager.PERMISSION_GRANTED;
322 }
323 }
324
325 return PackageManager.PERMISSION_DENIED;
326 }
327
Todd Kennedy3c714492017-10-27 09:12:50 -0700328 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
329 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700330 final int callingUserId = UserHandle.getUserId(callingUid);
331 final boolean isCallerInstantApp =
332 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
333 final boolean isUidInstantApp =
334 mPackageManagerInt.getInstantAppPackageName(uid) != null;
335 final int userId = UserHandle.getUserId(uid);
336 if (!mUserManagerInt.exists(userId)) {
337 return PackageManager.PERMISSION_DENIED;
338 }
339
Todd Kennedy3c714492017-10-27 09:12:50 -0700340 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700341 if (pkg.mSharedUserId != null) {
342 if (isCallerInstantApp) {
343 return PackageManager.PERMISSION_DENIED;
344 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700345 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
346 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700347 }
348 final PermissionsState permissionsState =
349 ((PackageSetting) pkg.mExtras).getPermissionsState();
350 if (permissionsState.hasPermission(permName, userId)) {
351 if (isUidInstantApp) {
352 if (mSettings.isPermissionInstant(permName)) {
353 return PackageManager.PERMISSION_GRANTED;
354 }
355 } else {
356 return PackageManager.PERMISSION_GRANTED;
357 }
358 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700359 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700360 return PackageManager.PERMISSION_GRANTED;
361 }
362 } else {
363 ArraySet<String> perms = mSystemPermissions.get(uid);
364 if (perms != null) {
365 if (perms.contains(permName)) {
366 return PackageManager.PERMISSION_GRANTED;
367 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700368 if (FULLER_PERMISSION_MAP.containsKey(permName)
369 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700370 return PackageManager.PERMISSION_GRANTED;
371 }
372 }
373 }
374 return PackageManager.PERMISSION_DENIED;
375 }
376
Hongwei Wangf391b552018-04-06 13:52:46 -0700377 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -0800378 * Get the state of the runtime permissions as xml file.
379 *
380 * <p>Can not be called on main thread.
381 *
382 * @param user The user the data should be extracted for
383 *
384 * @return The state as a xml file
385 */
386 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
387 CompletableFuture<byte[]> backup = new CompletableFuture<>();
388 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
389 backup::complete);
390
391 try {
392 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
393 } catch (InterruptedException | ExecutionException | TimeoutException e) {
394 Slog.e(TAG, "Cannot create permission backup for " + user, e);
395 return null;
396 }
397 }
398
399 /**
400 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
401 *
402 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
403 * applied via {@link #restoreDelayedRuntimePermissions}.
404 *
405 * @param backup The state as an xml file
406 * @param user The user the data should be restored for
407 */
408 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
409 synchronized (mLock) {
410 mHasNoDelayedPermBackup.delete(user.getIdentifier());
411 mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
412 }
413 }
414
415 /**
416 * Try to apply permission backup that was previously not applied.
417 *
418 * <p>Can not be called on main thread.
419 *
420 * @param packageName The package that is newly installed
421 * @param user The user the package is installed for
422 *
423 * @see #restoreRuntimePermissions
424 */
425 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
426 @NonNull UserHandle user) {
427 synchronized (mLock) {
428 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
429 return;
430 }
431
432 mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
433 mContext.getMainExecutor(), (hasMoreBackup) -> {
434 if (hasMoreBackup) {
435 return;
436 }
437
438 synchronized (mLock) {
439 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
440 }
441 });
442 }
443 }
444
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700445 private void addOnRuntimePermissionStateChangedListener(@NonNull
446 OnRuntimePermissionStateChangedListener listener) {
447 synchronized (mLock) {
448 mRuntimePermissionStateChangedListeners.add(listener);
449 }
450 }
451
452 private void removeOnRuntimePermissionStateChangedListener(@NonNull
453 OnRuntimePermissionStateChangedListener listener) {
454 synchronized (mLock) {
455 mRuntimePermissionStateChangedListeners.remove(listener);
456 }
457 }
458
459 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
460 @UserIdInt int userId) {
461 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
462 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
463 PermissionManagerService.this, packageName, userId));
464 }
465
466 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
467 @UserIdInt int userId) {
468 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
469 synchronized (mLock) {
470 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
471 return;
472 }
473 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
474 }
475 final int listenerCount = listeners.size();
476 for (int i = 0; i < listenerCount; i++) {
477 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
478 }
479 }
480
Philip P. Moltmann48456672019-01-20 13:14:03 -0800481 /**
Hongwei Wangf391b552018-04-06 13:52:46 -0700482 * Returns {@code true} if the permission can be implied from another granted permission.
483 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
484 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
485 * it access to any implied permissions.
486 */
487 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
488 String permName, int userId) {
489 return FULLER_PERMISSION_MAP.containsKey(permName)
490 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
491 }
492
Todd Kennedy460f28c2017-10-06 13:46:22 -0700493 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
494 int callingUid) {
495 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
496 return null;
497 }
498 synchronized (mLock) {
499 return PackageParser.generatePermissionGroupInfo(
500 mSettings.mPermissionGroups.get(groupName), flags);
501 }
502 }
503
504 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
505 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
506 return null;
507 }
508 synchronized (mLock) {
509 final int N = mSettings.mPermissionGroups.size();
510 final ArrayList<PermissionGroupInfo> out
511 = new ArrayList<PermissionGroupInfo>(N);
512 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
513 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
514 }
515 return out;
516 }
517 }
518
519 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700520 int callingUid) {
521 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
522 return null;
523 }
524 // reader
525 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700526 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700527 if (bp == null) {
528 return null;
529 }
530 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
531 bp.getProtectionLevel(), packageName, callingUid);
532 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
533 }
534 }
535
536 private List<PermissionInfo> getPermissionInfoByGroup(
537 String groupName, int flags, int callingUid) {
538 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
539 return null;
540 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700541 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700542 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
543 return null;
544 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700545 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700546 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700547 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
548 if (pi != null) {
549 out.add(pi);
550 }
551 }
552 return out;
553 }
554 }
555
556 private int adjustPermissionProtectionFlagsLocked(
557 int protectionLevel, String packageName, int uid) {
558 // Signature permission flags area always reported
559 final int protectionLevelMasked = protectionLevel
560 & (PermissionInfo.PROTECTION_NORMAL
561 | PermissionInfo.PROTECTION_DANGEROUS
562 | PermissionInfo.PROTECTION_SIGNATURE);
563 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
564 return protectionLevel;
565 }
566 // System sees all flags.
567 final int appId = UserHandle.getAppId(uid);
568 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
569 || appId == Process.SHELL_UID) {
570 return protectionLevel;
571 }
572 // Normalize package name to handle renamed packages and static libs
573 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
574 if (pkg == null) {
575 return protectionLevel;
576 }
577 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
578 return protectionLevelMasked;
579 }
580 // Apps that target O see flags for all protection levels.
581 final PackageSetting ps = (PackageSetting) pkg.mExtras;
582 if (ps == null) {
583 return protectionLevel;
584 }
585 if (ps.getAppId() != appId) {
586 return protectionLevel;
587 }
588 return protectionLevel;
589 }
590
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700591 /**
592 * We might auto-grant permissions if any permission of the group is already granted. Hence if
593 * the group of a granted permission changes we need to revoke it to avoid having permissions of
594 * the new group auto-granted.
595 *
596 * @param newPackage The new package that was installed
597 * @param oldPackage The old package that was updated
598 * @param allPackageNames All package names
599 * @param permissionCallback Callback for permission changed
600 */
601 private void revokeRuntimePermissionsIfGroupChanged(
602 @NonNull PackageParser.Package newPackage,
603 @NonNull PackageParser.Package oldPackage,
604 @NonNull ArrayList<String> allPackageNames,
605 @NonNull PermissionCallback permissionCallback) {
606 final int numOldPackagePermissions = oldPackage.permissions.size();
607 final ArrayMap<String, String> oldPermissionNameToGroupName
608 = new ArrayMap<>(numOldPackagePermissions);
609
610 for (int i = 0; i < numOldPackagePermissions; i++) {
611 final PackageParser.Permission permission = oldPackage.permissions.get(i);
612
613 if (permission.group != null) {
614 oldPermissionNameToGroupName.put(permission.info.name,
615 permission.group.info.name);
616 }
617 }
618
619 final int numNewPackagePermissions = newPackage.permissions.size();
620 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
621 newPermissionNum++) {
622 final PackageParser.Permission newPermission =
623 newPackage.permissions.get(newPermissionNum);
624 final int newProtection = newPermission.info.getProtection();
625
626 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
627 final String permissionName = newPermission.info.name;
628 final String newPermissionGroupName =
629 newPermission.group == null ? null : newPermission.group.info.name;
630 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
631 permissionName);
632
633 if (newPermissionGroupName != null
634 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
635 final int[] userIds = mUserManagerInt.getUserIds();
636 final int numUserIds = userIds.length;
637 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
638 final int userId = userIds[userIdNum];
639
640 final int numPackages = allPackageNames.size();
641 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
642 final String packageName = allPackageNames.get(packageNum);
643
644 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
645 userId) == PackageManager.PERMISSION_GRANTED) {
646 EventLog.writeEvent(0x534e4554, "72710897",
647 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900648 "Revoking permission " + permissionName +
649 " from package " + packageName +
650 " as the group changed from " + oldPermissionGroupName +
651 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700652
653 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000654 revokeRuntimePermission(permissionName, packageName, false,
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700655 userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700656 } catch (IllegalArgumentException e) {
657 Slog.e(TAG, "Could not revoke " + permissionName + " from "
658 + packageName, e);
659 }
660 }
661 }
662 }
663 }
664 }
665 }
666 }
667
Todd Kennedyc8423932017-10-05 08:58:36 -0700668 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
669 final int N = pkg.permissions.size();
670 for (int i=0; i<N; i++) {
671 PackageParser.Permission p = pkg.permissions.get(i);
672
673 // Assume by default that we did not install this permission into the system.
674 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
675
Todd Kennedyc8423932017-10-05 08:58:36 -0700676 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700677 // Now that permission groups have a special meaning, we ignore permission
678 // groups for legacy apps to prevent unexpected behavior. In particular,
679 // permissions for one app being granted to someone just because they happen
680 // to be in a group defined by another app (before this had no implications).
681 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
682 p.group = mSettings.mPermissionGroups.get(p.info.group);
683 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700684 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700685 && p.info.group != null && p.group == null) {
686 Slog.i(TAG, "Permission " + p.info.name + " from package "
687 + p.info.packageName + " in an unknown group " + p.info.group);
688 }
689 }
690
Todd Kennedyc8423932017-10-05 08:58:36 -0700691 if (p.tree) {
692 final BasePermission bp = BasePermission.createOrUpdate(
693 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
694 mSettings.getAllPermissionTreesLocked(), chatty);
695 mSettings.putPermissionTreeLocked(p.info.name, bp);
696 } else {
697 final BasePermission bp = BasePermission.createOrUpdate(
698 mSettings.getPermissionLocked(p.info.name),
699 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
700 mSettings.putPermissionLocked(p.info.name, bp);
701 }
702 }
703 }
704 }
705
Todd Kennedy460f28c2017-10-06 13:46:22 -0700706 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
707 final int N = pkg.permissionGroups.size();
708 StringBuilder r = null;
709 for (int i=0; i<N; i++) {
710 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
711 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
712 final String curPackageName = (cur == null) ? null : cur.info.packageName;
713 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
714 if (cur == null || isPackageUpdate) {
715 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700716 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700717 if (r == null) {
718 r = new StringBuilder(256);
719 } else {
720 r.append(' ');
721 }
722 if (isPackageUpdate) {
723 r.append("UPD:");
724 }
725 r.append(pg.info.name);
726 }
727 } else {
728 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
729 + pg.info.packageName + " ignored: original from "
730 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700731 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700732 if (r == null) {
733 r = new StringBuilder(256);
734 } else {
735 r.append(' ');
736 }
737 r.append("DUP:");
738 r.append(pg.info.name);
739 }
740 }
741 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700742 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700743 Log.d(TAG, " Permission Groups: " + r);
744 }
745
746 }
747
Hongming Jinae750fb2018-09-27 23:00:20 +0000748 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700749 synchronized (mLock) {
750 int N = pkg.permissions.size();
751 StringBuilder r = null;
752 for (int i=0; i<N; i++) {
753 PackageParser.Permission p = pkg.permissions.get(i);
754 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
755 if (bp == null) {
756 bp = mSettings.mPermissionTrees.get(p.info.name);
757 }
758 if (bp != null && bp.isPermission(p)) {
759 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700760 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700761 if (r == null) {
762 r = new StringBuilder(256);
763 } else {
764 r.append(' ');
765 }
766 r.append(p.info.name);
767 }
768 }
769 if (p.isAppOp()) {
770 ArraySet<String> appOpPkgs =
771 mSettings.mAppOpPermissionPackages.get(p.info.name);
772 if (appOpPkgs != null) {
773 appOpPkgs.remove(pkg.packageName);
774 }
775 }
776 }
777 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700778 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700779 }
780
781 N = pkg.requestedPermissions.size();
782 r = null;
783 for (int i=0; i<N; i++) {
784 String perm = pkg.requestedPermissions.get(i);
785 if (mSettings.isPermissionAppOp(perm)) {
786 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
787 if (appOpPkgs != null) {
788 appOpPkgs.remove(pkg.packageName);
789 if (appOpPkgs.isEmpty()) {
790 mSettings.mAppOpPermissionPackages.remove(perm);
791 }
792 }
793 }
794 }
795 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700796 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700797 }
798 }
799 }
800
801 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700802 PermissionInfo info, int callingUid, PermissionCallback callback) {
803 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
804 throw new SecurityException("Instant apps can't add permissions");
805 }
806 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
807 throw new SecurityException("Label must be specified in permission");
808 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700809 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700810 final boolean added;
811 final boolean changed;
812 synchronized (mLock) {
813 BasePermission bp = mSettings.getPermissionLocked(info.name);
814 added = bp == null;
815 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
816 if (added) {
817 enforcePermissionCapLocked(info, tree);
818 bp = new BasePermission(info.name, tree.getSourcePackageName(),
819 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700820 } else if (!bp.isDynamic()) {
821 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700822 + info.name);
823 }
824 changed = bp.addToTree(fixedLevel, info, tree);
825 if (added) {
826 mSettings.putPermissionLocked(info.name, bp);
827 }
828 }
829 if (changed && callback != null) {
830 callback.onPermissionChanged();
831 }
832 return added;
833 }
834
Todd Kennedyc8423932017-10-05 08:58:36 -0700835 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700836 String permName, int callingUid, PermissionCallback callback) {
837 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
838 throw new SecurityException("Instant applications don't have access to this method");
839 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700840 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700841 synchronized (mLock) {
842 final BasePermission bp = mSettings.getPermissionLocked(permName);
843 if (bp == null) {
844 return;
845 }
846 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600847 // TODO: switch this back to SecurityException
848 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700849 + permName);
850 }
851 mSettings.removePermissionLocked(permName);
852 if (callback != null) {
853 callback.onPermissionRemoved();
854 }
855 }
856 }
857
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700858 /**
859 * Restore the permission state for a package.
860 *
861 * <ul>
862 * <li>During boot the state gets restored from the disk</li>
863 * <li>During app update the state gets restored from the last version of the app</li>
864 * </ul>
865 *
866 * <p>This restores the permission state for all users.
867 *
868 * @param pkg the package the permissions belong to
869 * @param replace if the package is getting replaced (this might change the requested
870 * permissions of this package)
871 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
872 * @param callback Result call back
873 */
874 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
875 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700876 // IMPORTANT: There are two types of permissions: install and runtime.
877 // Install time permissions are granted when the app is installed to
878 // all device users and users added in the future. Runtime permissions
879 // are granted at runtime explicitly to specific users. Normal and signature
880 // protected permissions are install time permissions. Dangerous permissions
881 // are install permissions if the app's target SDK is Lollipop MR1 or older,
882 // otherwise they are runtime permissions. This function does not manage
883 // runtime permissions except for the case an app targeting Lollipop MR1
884 // being upgraded to target a newer SDK, in which case dangerous permissions
885 // are transformed from install time to runtime ones.
886
887 final PackageSetting ps = (PackageSetting) pkg.mExtras;
888 if (ps == null) {
889 return;
890 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700891
892 final PermissionsState permissionsState = ps.getPermissionsState();
893 PermissionsState origPermissions = permissionsState;
894
895 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
896
897 boolean runtimePermissionsRevoked = false;
898 int[] updatedUserIds = EMPTY_INT_ARRAY;
899
900 boolean changedInstallPermission = false;
901
902 if (replace) {
903 ps.setInstallPermissionsFixed(false);
904 if (!ps.isSharedUser()) {
905 origPermissions = new PermissionsState(permissionsState);
906 permissionsState.reset();
907 } else {
908 // We need to know only about runtime permission changes since the
909 // calling code always writes the install permissions state but
910 // the runtime ones are written only if changed. The only cases of
911 // changed runtime permissions here are promotion of an install to
912 // runtime and revocation of a runtime from a shared user.
913 synchronized (mLock) {
914 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
915 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
916 if (!ArrayUtils.isEmpty(updatedUserIds)) {
917 runtimePermissionsRevoked = true;
918 }
919 }
920 }
921 }
922
923 permissionsState.setGlobalGids(mGlobalGids);
924
925 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700926 ArraySet<String> newImplicitPermissions = new ArraySet<>();
927
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700928 final int N = pkg.requestedPermissions.size();
929 for (int i = 0; i < N; i++) {
930 final String permName = pkg.requestedPermissions.get(i);
931 final BasePermission bp = mSettings.getPermissionLocked(permName);
932 final boolean appSupportsRuntimePermissions =
933 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +0100934 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700935
936 if (DEBUG_INSTALL) {
937 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
938 }
939
940 if (bp == null || bp.getSourcePackageSetting() == null) {
941 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
942 if (DEBUG_PERMISSIONS) {
943 Slog.i(TAG, "Unknown permission " + permName
944 + " in package " + pkg.packageName);
945 }
946 }
947 continue;
948 }
949
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700950 // Cache newImplicitPermissions before modifing permissionsState as for the shared
951 // uids the original and new state are the same object
952 if (!origPermissions.hasRequestedPermission(permName)
Zimuzoe6411402019-05-13 16:32:57 +0100953 && (pkg.implicitPermissions.contains(permName)
954 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
955 if (pkg.implicitPermissions.contains(permName)) {
956 // If permName is an implicit permission, try to auto-grant
957 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700958
Zimuzoe6411402019-05-13 16:32:57 +0100959 if (DEBUG_PERMISSIONS) {
960 Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
961 }
962 } else {
963 // Special case for Activity Recognition permission. Even if AR permission
964 // is not an implicit permission we want to add it to the list (try to
965 // auto-grant it) if the app was installed on a device before AR permission
966 // was split, regardless of if the app now requests the new AR permission
967 // or has updated its target SDK and AR is no longer implicit to it.
968 // This is a compatibility workaround for apps when AR permission was
969 // split in Q.
Anthony Hugh6f5eadc2019-08-22 15:35:48 -0700970 final List<PermissionManager.SplitPermissionInfo> permissionList =
971 getSplitPermissions();
972 int numSplitPerms = permissionList.size();
Zimuzoe6411402019-05-13 16:32:57 +0100973 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
974 PermissionManager.SplitPermissionInfo sp =
Anthony Hugh6f5eadc2019-08-22 15:35:48 -0700975 permissionList.get(splitPermNum);
Zimuzoe6411402019-05-13 16:32:57 +0100976 String splitPermName = sp.getSplitPermission();
977 if (sp.getNewPermissions().contains(permName)
978 && origPermissions.hasInstallPermission(splitPermName)) {
979 upgradedActivityRecognitionPermission = splitPermName;
980 newImplicitPermissions.add(permName);
981
982 if (DEBUG_PERMISSIONS) {
983 Slog.i(TAG, permName + " is newly added for "
984 + pkg.packageName);
985 }
986 break;
987 }
988 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700989 }
990 }
991
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700992 // Limit ephemeral apps to ephemeral allowed permissions.
993 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
994 if (DEBUG_PERMISSIONS) {
995 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
996 + " for package " + pkg.packageName);
997 }
998 continue;
999 }
1000
1001 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
1002 if (DEBUG_PERMISSIONS) {
1003 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
1004 + " for package " + pkg.packageName);
1005 }
1006 continue;
1007 }
1008
1009 final String perm = bp.getName();
1010 boolean allowedSig = false;
1011 int grant = GRANT_DENIED;
1012
1013 // Keep track of app op permissions.
1014 if (bp.isAppOp()) {
1015 mSettings.addAppOpPackage(perm, pkg.packageName);
1016 }
1017
1018 if (bp.isNormal()) {
1019 // For all apps normal permissions are install time ones.
1020 grant = GRANT_INSTALL;
1021 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01001022 if (origPermissions.hasInstallPermission(bp.getName())
1023 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001024 // Before Q we represented some runtime permissions as install permissions,
1025 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001026 grant = GRANT_UPGRADE;
1027 } else {
1028 // For modern apps keep runtime permissions unchanged.
1029 grant = GRANT_RUNTIME;
1030 }
1031 } else if (bp.isSignature()) {
1032 // For all apps signature permissions are install time ones.
1033 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
1034 if (allowedSig) {
1035 grant = GRANT_INSTALL;
1036 }
1037 }
1038
1039 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001040 Slog.i(TAG, "Considering granting permission " + perm + " to package "
1041 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001042 }
1043
1044 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001045 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001046 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001047 // we can't add any new permissions to it. Runtime
1048 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001049 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
1050 // Except... if this is a permission that was added
1051 // to the platform (note: need to only do this when
1052 // updating the platform).
1053 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
1054 grant = GRANT_DENIED;
1055 }
1056 }
1057 }
1058
1059 switch (grant) {
1060 case GRANT_INSTALL: {
1061 // Revoke this as runtime permission to handle the case of
1062 // a runtime permission being downgraded to an install one.
1063 // Also in permission review mode we keep dangerous permissions
1064 // for legacy apps
1065 for (int userId : UserManagerService.getInstance().getUserIds()) {
1066 if (origPermissions.getRuntimePermissionState(
1067 perm, userId) != null) {
1068 // Revoke the runtime permission and clear the flags.
1069 origPermissions.revokeRuntimePermission(bp, userId);
1070 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001071 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001072 // If we revoked a permission permission, we have to write.
1073 updatedUserIds = ArrayUtils.appendInt(
1074 updatedUserIds, userId);
1075 }
1076 }
1077 // Grant an install permission.
1078 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001079 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001080 changedInstallPermission = true;
1081 }
1082 } break;
1083
1084 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001085 boolean hardRestricted = bp.isHardRestricted();
1086 boolean softRestricted = bp.isSoftRestricted();
1087
Philip P. Moltmann48456672019-01-20 13:14:03 -08001088 for (int userId : currentUserIds) {
Svet Ganov0b41c892019-07-26 17:45:56 -07001089 // If permission policy is not ready we don't deal with restricted
1090 // permissions as the policy may whitelist some permissions. Once
1091 // the policy is initialized we would re-evaluate permissions.
1092 final boolean permissionPolicyInitialized =
1093 mPermissionPolicyInternal != null
1094 && mPermissionPolicyInternal.isInitialized(userId);
1095
Philip P. Moltmann48456672019-01-20 13:14:03 -08001096 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001097 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001098 int flags = permState != null ? permState.getFlags() : 0;
1099
1100 boolean wasChanged = false;
1101
Svet Ganov83a3a4a2019-05-03 18:50:43 -07001102 boolean restrictionExempt =
1103 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001104 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1105 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1106 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1107
Philip P. Moltmann48456672019-01-20 13:14:03 -08001108 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001109 // If hard restricted we don't allow holding it
Svet Ganov0b41c892019-07-26 17:45:56 -07001110 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001111 if (!restrictionExempt) {
1112 if (permState != null && permState.isGranted()
1113 && permissionsState.revokeRuntimePermission(
1114 bp, userId) != PERMISSION_OPERATION_FAILURE) {
1115 wasChanged = true;
1116 }
1117 if (!restrictionApplied) {
1118 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1119 wasChanged = true;
1120 }
1121 }
1122 // If soft restricted we allow holding in a restricted form
Svet Ganov0b41c892019-07-26 17:45:56 -07001123 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001124 // Regardless if granted set the restriction flag as it
1125 // may affect app treatment based on this permission.
1126 if (!restrictionExempt && !restrictionApplied) {
1127 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1128 wasChanged = true;
1129 }
1130 }
1131
Philip P. Moltmann48456672019-01-20 13:14:03 -08001132 // Remove review flag as it is not necessary anymore
1133 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1134 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1135 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001136 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001137
1138 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1139 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1140 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001141 // Hard restricted permissions cannot be held.
Svet Ganov0b41c892019-07-26 17:45:56 -07001142 } else if (!permissionPolicyInitialized
1143 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001144 if (permState != null && permState.isGranted()) {
1145 if (permissionsState.grantRuntimePermission(bp, userId)
1146 == PERMISSION_OPERATION_FAILURE) {
1147 wasChanged = true;
1148 }
1149 }
1150 }
1151 } else {
1152 if (permState == null) {
1153 // New permission
1154 if (PLATFORM_PACKAGE_NAME.equals(
1155 bp.getSourcePackageName())) {
1156 if (!bp.isRemoved()) {
1157 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1158 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1159 wasChanged = true;
1160 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001161 }
1162 }
1163
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001164 if (!permissionsState.hasRuntimePermission(bp.name, userId)
1165 && permissionsState.grantRuntimePermission(bp, userId)
1166 != PERMISSION_OPERATION_FAILURE) {
1167 wasChanged = true;
1168 }
1169
1170 // If legacy app always grant the permission but if restricted
1171 // and not exempt take a note a restriction should be applied.
Svet Ganov0b41c892019-07-26 17:45:56 -07001172 if (permissionPolicyInitialized
1173 && (hardRestricted || softRestricted)
1174 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001175 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1176 wasChanged = true;
1177 }
1178 }
1179
1180 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov0b41c892019-07-26 17:45:56 -07001181 if (permissionPolicyInitialized) {
1182 if (!(hardRestricted || softRestricted) || restrictionExempt) {
1183 if (restrictionApplied) {
1184 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1185 // Dropping restriction on a legacy app implies a review
1186 if (!appSupportsRuntimePermissions) {
1187 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1188 }
1189 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001190 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001191 }
1192 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001193
1194 if (wasChanged) {
1195 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1196 }
1197
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001198 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001199 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001200 }
1201 } break;
1202
1203 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001204 // Upgrade from Pre-Q to Q permission model. Make all permissions
1205 // runtime
1206 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001207 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001208 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001209
Zimuzoe6411402019-05-13 16:32:57 +01001210 BasePermission bpToRevoke =
1211 upgradedActivityRecognitionPermission == null
1212 ? bp : mSettings.getPermissionLocked(
1213 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001214 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01001215 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001216 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01001217 origPermissions.updatePermissionFlags(bpToRevoke,
1218 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001219 (MASK_PERMISSION_FLAGS_ALL
1220 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001221 changedInstallPermission = true;
1222 }
1223
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001224 boolean hardRestricted = bp.isHardRestricted();
1225 boolean softRestricted = bp.isSoftRestricted();
1226
Philip P. Moltmann48456672019-01-20 13:14:03 -08001227 for (int userId : currentUserIds) {
Svet Ganov0b41c892019-07-26 17:45:56 -07001228 // If permission policy is not ready we don't deal with restricted
1229 // permissions as the policy may whitelist some permissions. Once
1230 // the policy is initialized we would re-evaluate permissions.
1231 final boolean permissionPolicyInitialized =
1232 mPermissionPolicyInternal != null
1233 && mPermissionPolicyInternal.isInitialized(userId);
1234
Philip P. Moltmann48456672019-01-20 13:14:03 -08001235 boolean wasChanged = false;
1236
Svet Ganov83a3a4a2019-05-03 18:50:43 -07001237 boolean restrictionExempt =
1238 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001239 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1240 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1241 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1242
Philip P. Moltmann48456672019-01-20 13:14:03 -08001243 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001244 // If hard restricted we don't allow holding it
Svet Ganov0b41c892019-07-26 17:45:56 -07001245 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001246 if (!restrictionExempt) {
1247 if (permState != null && permState.isGranted()
1248 && permissionsState.revokeRuntimePermission(
1249 bp, userId) != PERMISSION_OPERATION_FAILURE) {
1250 wasChanged = true;
1251 }
1252 if (!restrictionApplied) {
1253 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1254 wasChanged = true;
1255 }
1256 }
1257 // If soft restricted we allow holding in a restricted form
Svet Ganov0b41c892019-07-26 17:45:56 -07001258 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001259 // Regardless if granted set the restriction flag as it
1260 // may affect app treatment based on this permission.
1261 if (!restrictionExempt && !restrictionApplied) {
1262 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1263 wasChanged = true;
1264 }
1265 }
1266
Philip P. Moltmann48456672019-01-20 13:14:03 -08001267 // Remove review flag as it is not necessary anymore
1268 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1269 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1270 wasChanged = true;
1271 }
1272
1273 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1274 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1275 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001276 // Hard restricted permissions cannot be held.
Svet Ganov0b41c892019-07-26 17:45:56 -07001277 } else if (!permissionPolicyInitialized ||
1278 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001279 if (permissionsState.grantRuntimePermission(bp, userId) !=
1280 PERMISSION_OPERATION_FAILURE) {
1281 wasChanged = true;
1282 }
1283 }
1284 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001285 if (!permissionsState.hasRuntimePermission(bp.name, userId)
1286 && permissionsState.grantRuntimePermission(bp,
1287 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001288 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1289 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001290 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001291
1292 // If legacy app always grant the permission but if restricted
1293 // and not exempt take a note a restriction should be applied.
Svet Ganov0b41c892019-07-26 17:45:56 -07001294 if (permissionPolicyInitialized
1295 && (hardRestricted || softRestricted)
1296 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001297 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1298 wasChanged = true;
1299 }
1300 }
1301
1302 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov0b41c892019-07-26 17:45:56 -07001303 if (permissionPolicyInitialized) {
1304 if (!(hardRestricted || softRestricted) || restrictionExempt) {
1305 if (restrictionApplied) {
1306 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1307 // Dropping restriction on a legacy app implies a review
1308 if (!appSupportsRuntimePermissions) {
1309 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1310 }
1311 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001312 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001313 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001314 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001315
1316 if (wasChanged) {
1317 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1318 }
1319
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001320 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001321 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001322 }
1323 } break;
1324
1325 default: {
1326 if (packageOfInterest == null
1327 || packageOfInterest.equals(pkg.packageName)) {
1328 if (DEBUG_PERMISSIONS) {
1329 Slog.i(TAG, "Not granting permission " + perm
1330 + " to package " + pkg.packageName
1331 + " because it was previously installed without");
1332 }
1333 }
1334 } break;
1335 }
1336 } else {
1337 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001338 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001339 // Also drop the permission flags.
1340 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001341 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001342 changedInstallPermission = true;
1343 Slog.i(TAG, "Un-granting permission " + perm
1344 + " from package " + pkg.packageName
1345 + " (protectionLevel=" + bp.getProtectionLevel()
1346 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1347 + ")");
1348 } else if (bp.isAppOp()) {
1349 // Don't print warning for app op permissions, since it is fine for them
1350 // not to be granted, there is a UI for the user to decide.
1351 if (DEBUG_PERMISSIONS
1352 && (packageOfInterest == null
1353 || packageOfInterest.equals(pkg.packageName))) {
1354 Slog.i(TAG, "Not granting permission " + perm
1355 + " to package " + pkg.packageName
1356 + " (protectionLevel=" + bp.getProtectionLevel()
1357 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1358 + ")");
1359 }
1360 }
1361 }
1362 }
1363
1364 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1365 !ps.isSystem() || ps.isUpdatedSystem()) {
1366 // This is the first that we have heard about this package, so the
1367 // permissions we have now selected are fixed until explicitly
1368 // changed.
1369 ps.setInstallPermissionsFixed(true);
1370 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001371
1372 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1373 updatedUserIds);
1374 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07001375 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07001376 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001377 }
1378
1379 // Persist the runtime permissions state for users with changes. If permissions
1380 // were revoked because no app in the shared user declares them we have to
1381 // write synchronously to avoid losing runtime permissions state.
1382 if (callback != null) {
1383 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1384 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001385
1386 for (int userId : updatedUserIds) {
1387 notifyRuntimePermissionStateChanged(pkg.packageName, userId);
1388 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001389 }
1390
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001391 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001392 * Revoke permissions that are not implicit anymore and that have
1393 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1394 *
1395 * @param ps The state of the permissions of the package
1396 * @param pkg The package that is currently looked at
1397 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1398 * for a user is changed.
1399 *
1400 * @return The updated value of the {@code updatedUserIds} parameter
1401 */
1402 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1403 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1404 @NonNull int[] updatedUserIds) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001405 String pkgName = pkg.packageName;
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08001406 boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1407 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001408
1409 int[] users = UserManagerService.getInstance().getUserIds();
1410 int numUsers = users.length;
1411 for (int i = 0; i < numUsers; i++) {
1412 int userId = users[i];
1413
1414 for (String permission : ps.getPermissions(userId)) {
1415 if (!pkg.implicitPermissions.contains(permission)) {
1416 if (!ps.hasInstallPermission(permission)) {
1417 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1418
1419 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1420 BasePermission bp = mSettings.getPermissionLocked(permission);
1421
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001422 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001423
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001424 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
1425 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001426 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1427 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1428 if (DEBUG_PERMISSIONS) {
1429 Slog.i(TAG, "Revoking runtime permission "
1430 + permission + " for " + pkgName
1431 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001432 }
1433 }
1434
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001435 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001436 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001437
1438 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1439 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001440 }
1441 }
1442 }
1443 }
1444 }
1445
1446 return updatedUserIds;
1447 }
1448
1449 /**
1450 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1451 *
1452 * <p>A single new permission can be split off from several source permissions. In this case
1453 * the most leniant state is inherited.
1454 *
1455 * <p>Warning: This does not handle foreground / background permissions
1456 *
1457 * @param sourcePerms The permissions to inherit from
1458 * @param newPerm The permission to inherit to
1459 * @param ps The permission state of the package
1460 * @param pkg The package requesting the permissions
1461 * @param userId The user the permission belongs to
1462 */
1463 private void inheritPermissionStateToNewImplicitPermissionLocked(
1464 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1465 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1466 @UserIdInt int userId) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001467 String pkgName = pkg.packageName;
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001468 boolean isGranted = false;
1469 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001470
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001471 int numSourcePerm = sourcePerms.size();
1472 for (int i = 0; i < numSourcePerm; i++) {
1473 String sourcePerm = sourcePerms.valueAt(i);
1474 if ((ps.hasRuntimePermission(sourcePerm, userId))
1475 || ps.hasInstallPermission(sourcePerm)) {
1476 if (!isGranted) {
1477 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001478 }
1479
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001480 isGranted = true;
1481 flags |= ps.getPermissionFlags(sourcePerm, userId);
1482 } else {
1483 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001484 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001485 }
1486 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001487 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001488
1489 if (isGranted) {
1490 if (DEBUG_PERMISSIONS) {
1491 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1492 + " for " + pkgName);
1493 }
1494
1495 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1496 }
1497
1498 // Add permission flags
1499 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001500 }
1501
1502 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07001503 * When the app has requested legacy storage we might need to update
1504 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
1505 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
1506 *
1507 * @param pkg The package for which the permissions are updated
1508 * @param replace If the app is being replaced
1509 * @param updatedUserIds The ids of the users that already changed.
1510 *
1511 * @return The ids of the users that are changed
1512 */
1513 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
1514 @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
1515 if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
1516 pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
1517 || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
1518 return UserManagerService.getInstance().getUserIds();
1519 }
1520
1521 return updatedUserIds;
1522 }
1523
1524 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001525 * Set the state of a implicit permission that is seen for the first time.
1526 *
1527 * @param origPs The permission state of the package before the split
1528 * @param ps The new permission state
1529 * @param pkg The package the permission belongs to
1530 * @param updatedUserIds List of users for which the permission state has already been changed
1531 *
1532 * @return List of users for which the permission state has been changed
1533 */
1534 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1535 @NonNull PermissionsState origPs,
1536 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07001537 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001538 @NonNull int[] updatedUserIds) {
1539 String pkgName = pkg.packageName;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001540 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1541
Anthony Hugh6f5eadc2019-08-22 15:35:48 -07001542 final List<PermissionManager.SplitPermissionInfo> permissionList = getSplitPermissions();
1543 int numSplitPerms = permissionList.size();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001544 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hugh6f5eadc2019-08-22 15:35:48 -07001545 PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001546
1547 List<String> newPerms = spi.getNewPermissions();
1548 int numNewPerms = newPerms.size();
1549 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1550 String newPerm = newPerms.get(newPermNum);
1551
1552 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1553 if (splitPerms == null) {
1554 splitPerms = new ArraySet<>();
1555 newToSplitPerms.put(newPerm, splitPerms);
1556 }
1557
1558 splitPerms.add(spi.getSplitPermission());
1559 }
1560 }
1561
1562 int numNewImplicitPerms = newImplicitPermissions.size();
1563 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1564 newImplicitPermNum++) {
1565 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1566 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1567
1568 if (sourcePerms != null) {
1569 if (!ps.hasInstallPermission(newPerm)) {
1570 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1571
1572 int[] users = UserManagerService.getInstance().getUserIds();
1573 int numUsers = users.length;
1574 for (int userNum = 0; userNum < numUsers; userNum++) {
1575 int userId = users[userNum];
1576
Zimuzoe6411402019-05-13 16:32:57 +01001577 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
1578 ps.updatePermissionFlags(bp, userId,
1579 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1580 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1581 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001582 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1583
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001584 boolean inheritsFromInstallPerm = false;
1585 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1586 sourcePermNum++) {
1587 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1588 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001589 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001590 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001591 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001592
1593 if (!origPs.hasRequestedPermission(sourcePerms)
1594 && !inheritsFromInstallPerm) {
1595 // Both permissions are new so nothing to inherit.
1596 if (DEBUG_PERMISSIONS) {
1597 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1598 + " for " + pkgName + " as split permission is also new");
1599 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001600 } else {
1601 // Inherit from new install or existing runtime permissions
1602 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1603 newPerm, ps, pkg, userId);
1604 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001605 }
1606 }
1607 }
1608 }
1609
1610 return updatedUserIds;
1611 }
1612
Anthony Hugh6f5eadc2019-08-22 15:35:48 -07001613 private List<PermissionManager.SplitPermissionInfo> getSplitPermissions() {
1614 return SystemConfig.getInstance().getSplitPermissions();
1615 }
1616
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001617 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1618 boolean allowed = false;
1619 final int NP = PackageParser.NEW_PERMISSIONS.length;
1620 for (int ip=0; ip<NP; ip++) {
1621 final PackageParser.NewPermissionInfo npi
1622 = PackageParser.NEW_PERMISSIONS[ip];
1623 if (npi.name.equals(perm)
1624 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1625 allowed = true;
1626 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1627 + pkg.packageName);
1628 break;
1629 }
1630 }
1631 return allowed;
1632 }
1633
1634 /**
1635 * Determines whether a package is whitelisted for a particular privapp permission.
1636 *
1637 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1638 *
1639 * <p>This handles parent/child apps.
1640 */
1641 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001642 ArraySet<String> wlPermissions = null;
1643 if (pkg.isVendor()) {
1644 wlPermissions =
1645 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1646 } else if (pkg.isProduct()) {
1647 wlPermissions =
1648 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Jeongik Chaf6629832019-07-04 21:12:06 +09001649 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01001650 wlPermissions =
Jeongik Chaf6629832019-07-04 21:12:06 +09001651 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Dario Freni2bef1762018-06-01 14:02:08 +01001652 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001653 } else {
1654 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1655 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001656 // Let's check if this package is whitelisted...
1657 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1658 // If it's not, we'll also tail-recurse to the parent.
1659 return whitelisted ||
1660 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1661 }
1662
1663 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1664 BasePermission bp, PermissionsState origPermissions) {
1665 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001666 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1667 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001668 boolean privappPermissionsDisable =
1669 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1670 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1671 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1672 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1673 && !platformPackage && platformPermission) {
1674 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001675 // Only report violations for apps on system image
1676 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1677 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001678 ArraySet<String> deniedPermissions = null;
1679 if (pkg.isVendor()) {
1680 deniedPermissions = SystemConfig.getInstance()
1681 .getVendorPrivAppDenyPermissions(pkg.packageName);
1682 } else if (pkg.isProduct()) {
1683 deniedPermissions = SystemConfig.getInstance()
1684 .getProductPrivAppDenyPermissions(pkg.packageName);
Jeongik Chaf6629832019-07-04 21:12:06 +09001685 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01001686 deniedPermissions = SystemConfig.getInstance()
Jeongik Chaf6629832019-07-04 21:12:06 +09001687 .getSystemExtPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001688 } else {
1689 deniedPermissions = SystemConfig.getInstance()
1690 .getPrivAppDenyPermissions(pkg.packageName);
1691 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001692 final boolean permissionViolation =
1693 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001694 if (permissionViolation) {
1695 Slog.w(TAG, "Privileged permission " + perm + " for package "
1696 + pkg.packageName + " - not in privapp-permissions whitelist");
1697
1698 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1699 if (mPrivappPermissionsViolations == null) {
1700 mPrivappPermissionsViolations = new ArraySet<>();
1701 }
1702 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001703 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001704 } else {
1705 return false;
1706 }
1707 }
1708 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1709 return false;
1710 }
1711 }
1712 }
Chen Xuda02e072019-10-07 00:24:41 -07001713 // expect single system package
1714 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
1715 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001716 final PackageParser.Package systemPackage =
1717 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001718
1719 // check if the package is allow to use this signature permission. A package is allowed to
1720 // use a signature permission if:
1721 // - it has the same set of signing certificates as the source package
1722 // - or its signing certificate was rotated from the source package's certificate
1723 // - or its signing certificate is a previous signing certificate of the defining
1724 // package, and the defining package still trusts the old certificate for permissions
1725 // - or it shares the above relationships with the system package
1726 boolean allowed =
1727 pkg.mSigningDetails.hasAncestorOrSelf(
1728 bp.getSourcePackageSetting().getSigningDetails())
1729 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1730 pkg.mSigningDetails,
1731 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1732 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1733 || systemPackage.mSigningDetails.checkCapability(
1734 pkg.mSigningDetails,
1735 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001736 if (!allowed && (privilegedPermission || oemPermission)) {
1737 if (pkg.isSystem()) {
1738 // For updated system applications, a privileged/oem permission
1739 // is granted only if it had been defined by the original application.
1740 if (pkg.isUpdatedSystemApp()) {
1741 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001742 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001743 final PackageSetting disabledPs =
1744 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1745 if (disabledPs != null
1746 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1747 // If the original was granted this permission, we take
1748 // that grant decision as read and propagate it to the
1749 // update.
1750 if ((privilegedPermission && disabledPs.isPrivileged())
1751 || (oemPermission && disabledPs.isOem()
1752 && canGrantOemPermission(disabledPs, perm))) {
1753 allowed = true;
1754 }
1755 } else {
1756 // The system apk may have been updated with an older
1757 // version of the one on the data partition, but which
1758 // granted a new system permission that it didn't have
1759 // before. In this case we do want to allow the app to
1760 // now get the new permission if the ancestral apk is
1761 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001762 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001763 && isPackageRequestingPermission(disabledPkg, perm)
1764 && ((privilegedPermission && disabledPs.isPrivileged())
1765 || (oemPermission && disabledPs.isOem()
1766 && canGrantOemPermission(disabledPs, perm)))) {
1767 allowed = true;
1768 }
1769 // Also if a privileged parent package on the system image or any of
1770 // its children requested a privileged/oem permission, the updated child
1771 // packages can also get the permission.
1772 if (pkg.parentPackage != null) {
1773 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001774 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001775 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1776 ? (PackageSetting) disabledParentPkg.mExtras : null;
1777 if (disabledParentPkg != null
1778 && ((privilegedPermission && disabledParentPs.isPrivileged())
1779 || (oemPermission && disabledParentPs.isOem()))) {
1780 if (isPackageRequestingPermission(disabledParentPkg, perm)
1781 && canGrantOemPermission(disabledParentPs, perm)) {
1782 allowed = true;
1783 } else if (disabledParentPkg.childPackages != null) {
1784 for (PackageParser.Package disabledChildPkg
1785 : disabledParentPkg.childPackages) {
1786 final PackageSetting disabledChildPs =
1787 (disabledChildPkg != null)
1788 ? (PackageSetting) disabledChildPkg.mExtras
1789 : null;
1790 if (isPackageRequestingPermission(disabledChildPkg, perm)
1791 && canGrantOemPermission(
1792 disabledChildPs, perm)) {
1793 allowed = true;
1794 break;
1795 }
1796 }
1797 }
1798 }
1799 }
1800 }
1801 } else {
1802 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1803 allowed = (privilegedPermission && pkg.isPrivileged())
1804 || (oemPermission && pkg.isOem()
1805 && canGrantOemPermission(ps, perm));
1806 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001807 // In any case, don't grant a privileged permission to privileged vendor apps, if
1808 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1809 // flag.
1810 if (allowed && privilegedPermission &&
1811 !vendorPrivilegedPermission && pkg.isVendor()) {
1812 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1813 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1814 allowed = false;
1815 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001816 }
1817 }
1818 if (!allowed) {
1819 if (!allowed
1820 && bp.isPre23()
1821 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1822 // If this was a previously normal/dangerous permission that got moved
1823 // to a system permission as part of the runtime permission redesign, then
1824 // we still want to blindly grant it to old apps.
1825 allowed = true;
1826 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001827 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1828 // need a separate flag anymore. Hence we need to check which
1829 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001830 if (!allowed && bp.isInstaller()
Chen Xuda02e072019-10-07 00:24:41 -07001831 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1832 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
1833 pkg.packageName) || ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001834 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
Chen Xuda02e072019-10-07 00:24:41 -07001835 UserHandle.USER_SYSTEM), pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001836 // If this permission is to be granted to the system installer and
1837 // this app is an installer, then it gets the permission.
1838 allowed = true;
1839 }
1840 if (!allowed && bp.isVerifier()
Chen Xuda02e072019-10-07 00:24:41 -07001841 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1842 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
1843 pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001844 // If this permission is to be granted to the system verifier and
1845 // this app is a verifier, then it gets the permission.
1846 allowed = true;
1847 }
1848 if (!allowed && bp.isPreInstalled()
1849 && pkg.isSystem()) {
1850 // Any pre-installed system app is allowed to get this permission.
1851 allowed = true;
1852 }
1853 if (!allowed && bp.isDevelopment()) {
1854 // For development permissions, a development permission
1855 // is granted only if it was already granted.
1856 allowed = origPermissions.hasInstallPermission(perm);
1857 }
1858 if (!allowed && bp.isSetup()
Chen Xuda02e072019-10-07 00:24:41 -07001859 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1860 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
1861 pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001862 // If this permission is to be granted to the system setup wizard and
1863 // this app is a setup wizard, then it gets the permission.
1864 allowed = true;
1865 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001866 if (!allowed && bp.isSystemTextClassifier()
Chen Xuda02e072019-10-07 00:24:41 -07001867 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08001868 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Chen Xuda02e072019-10-07 00:24:41 -07001869 UserHandle.USER_SYSTEM), pkg.packageName)) {
Makoto Onuki700feef2018-02-15 10:59:41 -08001870 // Special permissions for the system default text classifier.
1871 allowed = true;
1872 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001873 if (!allowed && bp.isConfigurator()
Chen Xuda02e072019-10-07 00:24:41 -07001874 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1875 PackageManagerInternal.PACKAGE_CONFIGURATOR,
1876 UserHandle.USER_SYSTEM), pkg.packageName)) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001877 // Special permissions for the device configurator.
1878 allowed = true;
1879 }
Varun Shah5f303652018-11-16 18:11:19 -08001880 if (!allowed && bp.isWellbeing()
Chen Xuda02e072019-10-07 00:24:41 -07001881 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1882 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
1883 pkg.packageName)) {
Varun Shah5f303652018-11-16 18:11:19 -08001884 // Special permission granted only to the OEM specified wellbeing app
1885 allowed = true;
1886 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07001887 if (!allowed && bp.isDocumenter()
Chen Xuda02e072019-10-07 00:24:41 -07001888 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1889 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
1890 pkg.packageName)) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07001891 // If this permission is to be granted to the documenter and
1892 // this app is the documenter, then it gets the permission.
1893 allowed = true;
1894 }
Joe Onorato5a15b552018-12-18 10:40:04 -08001895 if (!allowed && bp.isIncidentReportApprover()
Chen Xuda02e072019-10-07 00:24:41 -07001896 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08001897 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Chen Xuda02e072019-10-07 00:24:41 -07001898 UserHandle.USER_SYSTEM), pkg.packageName)) {
Joe Onorato5a15b552018-12-18 10:40:04 -08001899 // If this permission is to be granted to the incident report approver and
1900 // this app is the incident report approver, then it gets the permission.
1901 allowed = true;
1902 }
George Hodulikcd7695d2019-01-29 18:17:05 -08001903 if (!allowed && bp.isAppPredictor()
Chen Xuda02e072019-10-07 00:24:41 -07001904 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1905 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
1906 pkg.packageName)) {
George Hodulikcd7695d2019-01-29 18:17:05 -08001907 // Special permissions for the system app predictor.
1908 allowed = true;
1909 }
Chen Xuda02e072019-10-07 00:24:41 -07001910 if (!allowed && bp.isTelephony()
1911 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1912 PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
1913 pkg.packageName)) {
1914 // Special permissions for the system telephony apps.
1915 allowed = true;
1916 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001917 }
1918 return allowed;
1919 }
1920
1921 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1922 if (!ps.isOem()) {
1923 return false;
1924 }
1925 // all oem permissions must explicitly be granted or denied
1926 final Boolean granted =
1927 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1928 if (granted == null) {
1929 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1930 + ps.name + " must be explicitly declared granted or not");
1931 }
1932 return Boolean.TRUE == granted;
1933 }
1934
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001935 private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
1936 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001937 // Permission review applies only to apps not supporting the new permission model.
1938 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1939 return false;
1940 }
1941
1942 // Legacy apps have the permission and get user consent on launch.
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001943 if (pkg.mExtras == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001944 return false;
1945 }
1946 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1947 final PermissionsState permissionsState = ps.getPermissionsState();
1948 return permissionsState.isPermissionReviewRequired(userId);
1949 }
1950
1951 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1952 final int permCount = pkg.requestedPermissions.size();
1953 for (int j = 0; j < permCount; j++) {
1954 String requestedPermission = pkg.requestedPermissions.get(j);
1955 if (permission.equals(requestedPermission)) {
1956 return true;
1957 }
1958 }
1959 return false;
1960 }
1961
Andreas Gampea36dc622018-02-05 17:19:22 -08001962 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001963 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1964 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1965 if (pkg.parentPackage == null) {
1966 return;
1967 }
1968 if (pkg.requestedPermissions == null) {
1969 return;
1970 }
1971 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001972 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001973 if (disabledPkg == null || disabledPkg.mExtras == null) {
1974 return;
1975 }
1976 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1977 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1978 return;
1979 }
1980 final int permCount = pkg.requestedPermissions.size();
1981 for (int i = 0; i < permCount; i++) {
1982 String permission = pkg.requestedPermissions.get(i);
1983 BasePermission bp = mSettings.getPermissionLocked(permission);
1984 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1985 continue;
1986 }
1987 for (int userId : mUserManagerInt.getUserIds()) {
1988 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1989 grantRuntimePermission(
1990 permission, pkg.packageName, false, callingUid, userId, callback);
1991 }
1992 }
1993 }
1994 }
1995
1996 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1997 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1998 for (int userId : userIds) {
1999 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
2000 callback);
2001 }
2002 }
2003
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002004 private @Nullable List<String> getWhitelistedRestrictedPermissions(
2005 @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
2006 @UserIdInt int userId) {
2007 final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
2008 if (packageSetting == null) {
2009 return null;
2010 }
2011
2012 final PermissionsState permissionsState = packageSetting.getPermissionsState();
2013
2014 int queryFlags = 0;
2015 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
2016 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2017 }
2018 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
2019 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2020 }
2021 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
2022 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2023 }
2024
2025 ArrayList<String> whitelistedPermissions = null;
2026
2027 final int permissionCount = pkg.requestedPermissions.size();
2028 for (int i = 0; i < permissionCount; i++) {
2029 final String permissionName = pkg.requestedPermissions.get(i);
2030 final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
2031 if ((currentFlags & queryFlags) != 0) {
2032 if (whitelistedPermissions == null) {
2033 whitelistedPermissions = new ArrayList<>();
2034 }
2035 whitelistedPermissions.add(permissionName);
2036 }
2037 }
2038
2039 return whitelistedPermissions;
2040 }
2041
Todd Kennedy0eb97382017-10-03 16:57:22 -07002042 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2043 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2044 PackageSetting ps = (PackageSetting) pkg.mExtras;
2045 if (ps == null) {
2046 return;
2047 }
2048
2049 PermissionsState permissionsState = ps.getPermissionsState();
2050
2051 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2052 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2053
2054 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2055 >= Build.VERSION_CODES.M;
2056
2057 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
2058
2059 for (String permission : pkg.requestedPermissions) {
2060 final BasePermission bp;
2061 synchronized (mLock) {
2062 bp = mSettings.getPermissionLocked(permission);
2063 }
2064 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2065 && (!instantApp || bp.isInstant())
2066 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2067 && (grantedPermissions == null
2068 || ArrayUtils.contains(grantedPermissions, permission))) {
2069 final int flags = permissionsState.getPermissionFlags(permission, userId);
2070 if (supportsRuntimePermissions) {
2071 // Installer cannot change immutable permissions.
2072 if ((flags & immutableFlags) == 0) {
2073 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
2074 userId, callback);
2075 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002076 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002077 // In permission review mode we clear the review flag when we
2078 // are asked to install the app with all permissions granted.
2079 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2080 updatePermissionFlags(permission, pkg.packageName,
2081 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002082 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002083 }
2084 }
2085 }
2086 }
2087 }
2088
2089 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2090 int callingUid, final int userId, PermissionCallback callback) {
2091 if (!mUserManagerInt.exists(userId)) {
2092 Log.e(TAG, "No such user:" + userId);
2093 return;
2094 }
2095
2096 mContext.enforceCallingOrSelfPermission(
2097 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
2098 "grantRuntimePermission");
2099
2100 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002101 true, // requireFullPermission
2102 true, // checkShell
2103 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002104 "grantRuntimePermission");
2105
2106 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2107 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002108 Log.e(TAG, "Unknown package: " + packageName);
2109 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002110 }
2111 final BasePermission bp;
2112 synchronized(mLock) {
2113 bp = mSettings.getPermissionLocked(permName);
2114 }
2115 if (bp == null) {
2116 throw new IllegalArgumentException("Unknown permission: " + permName);
2117 }
2118 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2119 throw new IllegalArgumentException("Unknown package: " + packageName);
2120 }
2121
2122 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2123
2124 // If a permission review is required for legacy apps we represent
2125 // their permissions as always granted runtime ones since we need
2126 // to keep the review required permission flag per user while an
2127 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002128 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002129 && bp.isRuntime()) {
2130 return;
2131 }
2132
2133 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2134
2135 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2136 final PermissionsState permissionsState = ps.getPermissionsState();
2137
2138 final int flags = permissionsState.getPermissionFlags(permName, userId);
2139 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002140 Log.e(TAG, "Cannot grant system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002141 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002142 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002143 }
2144 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002145 Log.e(TAG, "Cannot grant policy fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002146 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002147 return;
2148 }
2149
Philip P. Moltmannd6b849c2019-05-15 16:36:32 -07002150 if (bp.isHardRestricted()
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002151 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002152 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002153 + permName + " for package " + packageName);
2154 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002155 }
2156
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002157 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Philip P. Moltmann69b645f2019-06-17 14:28:11 -07002158 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002159 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
2160 + packageName);
2161 return;
2162 }
2163
Todd Kennedy0eb97382017-10-03 16:57:22 -07002164 if (bp.isDevelopment()) {
2165 // Development permissions must be handled specially, since they are not
2166 // normal runtime permissions. For now they apply to all users.
2167 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002168 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002169 if (callback != null) {
2170 callback.onInstallPermissionGranted();
2171 }
2172 }
2173 return;
2174 }
2175
2176 if (ps.getInstantApp(userId) && !bp.isInstant()) {
2177 throw new SecurityException("Cannot grant non-ephemeral permission"
2178 + permName + " for package " + packageName);
2179 }
2180
2181 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2182 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2183 return;
2184 }
2185
2186 final int result = permissionsState.grantRuntimePermission(bp, userId);
2187 switch (result) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002188 case PERMISSION_OPERATION_FAILURE: {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002189 return;
2190 }
2191
2192 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2193 if (callback != null) {
2194 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2195 }
2196 }
2197 break;
2198 }
2199
2200 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002201 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002202 }
2203
2204 if (callback != null) {
2205 callback.onPermissionGranted(uid, userId);
2206 }
2207
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002208 if (bp.isRuntime()) {
2209 notifyRuntimePermissionStateChanged(packageName, userId);
2210 }
2211
Todd Kennedy0eb97382017-10-03 16:57:22 -07002212 // Only need to do this if user is initialized. Otherwise it's a new user
2213 // and there are no processes running as the user yet and there's no need
2214 // to make an expensive call to remount processes for the changed permissions.
2215 if (READ_EXTERNAL_STORAGE.equals(permName)
2216 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2217 final long token = Binder.clearCallingIdentity();
2218 try {
2219 if (mUserManagerInt.isUserInitialized(userId)) {
2220 StorageManagerInternal storageManagerInternal = LocalServices.getService(
2221 StorageManagerInternal.class);
2222 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2223 }
2224 } finally {
2225 Binder.restoreCallingIdentity(token);
2226 }
2227 }
2228
2229 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002230
2231 private void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002232 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002233 if (!mUserManagerInt.exists(userId)) {
2234 Log.e(TAG, "No such user:" + userId);
2235 return;
2236 }
2237
2238 mContext.enforceCallingOrSelfPermission(
2239 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2240 "revokeRuntimePermission");
2241
2242 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002243 true, // requireFullPermission
2244 true, // checkShell
2245 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002246 "revokeRuntimePermission");
2247
Todd Kennedy0eb97382017-10-03 16:57:22 -07002248 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2249 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002250 Log.e(TAG, "Unknown package: " + packageName);
2251 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002252 }
2253 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2254 throw new IllegalArgumentException("Unknown package: " + packageName);
2255 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002256 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002257 if (bp == null) {
2258 throw new IllegalArgumentException("Unknown permission: " + permName);
2259 }
2260
2261 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2262
2263 // If a permission review is required for legacy apps we represent
2264 // their permissions as always granted runtime ones since we need
2265 // to keep the review required permission flag per user while an
2266 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002267 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002268 && bp.isRuntime()) {
2269 return;
2270 }
2271
2272 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2273 final PermissionsState permissionsState = ps.getPermissionsState();
2274
2275 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07002276 // Only the system may revoke SYSTEM_FIXED permissions.
2277 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2278 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2279 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002280 + permName + " for package " + packageName);
2281 }
2282 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2283 throw new SecurityException("Cannot revoke policy fixed permission "
2284 + permName + " for package " + packageName);
2285 }
2286
2287 if (bp.isDevelopment()) {
2288 // Development permissions must be handled specially, since they are not
2289 // normal runtime permissions. For now they apply to all users.
2290 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002291 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002292 if (callback != null) {
2293 callback.onInstallPermissionRevoked();
2294 }
2295 }
2296 return;
2297 }
2298
Philip P. Moltmannf50316c2019-07-03 15:44:00 -07002299 // Permission is already revoked, no need to do anything.
2300 if (!permissionsState.hasRuntimePermission(permName, userId)) {
2301 return;
2302 }
2303
Todd Kennedy0eb97382017-10-03 16:57:22 -07002304 if (permissionsState.revokeRuntimePermission(bp, userId) ==
Philip P. Moltmann48456672019-01-20 13:14:03 -08002305 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002306 return;
2307 }
2308
2309 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002310 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002311 }
2312
2313 if (callback != null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002314 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2315 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002316
2317 if (bp.isRuntime()) {
2318 notifyRuntimePermissionStateChanged(packageName, userId);
2319 }
2320 }
2321
Nicholas Sauerdf932932019-08-27 08:43:23 -07002322 private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
2323 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
2324 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
2325 @NonNull PermissionCallback callback) {
2326
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002327 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2328 if (ps == null) {
2329 return;
2330 }
2331
2332 final PermissionsState permissionsState = ps.getPermissionsState();
Nicholas Sauerdf932932019-08-27 08:43:23 -07002333 SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002334 boolean updatePermissions = false;
2335
2336 final int permissionCount = pkg.requestedPermissions.size();
Nicholas Sauerdf932932019-08-27 08:43:23 -07002337 for (int userId : userIds) {
2338 for (int i = 0; i < permissionCount; i++) {
2339 final String permissionName = pkg.requestedPermissions.get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002340
Nicholas Sauerdf932932019-08-27 08:43:23 -07002341 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
2342 if (bp == null) {
2343 Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
2344 continue;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002345 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002346
Nicholas Sauerdf932932019-08-27 08:43:23 -07002347 if (!bp.isHardOrSoftRestricted()) {
2348 continue;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002349 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002350
Nicholas Sauerdf932932019-08-27 08:43:23 -07002351 if (permissionsState.hasPermission(permissionName, userId)) {
2352 if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
2353 oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
2354 }
2355 oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002356 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002357
Nicholas Sauerdf932932019-08-27 08:43:23 -07002358 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
Svet Ganovd563e932019-04-14 13:07:41 -07002359
Nicholas Sauerdf932932019-08-27 08:43:23 -07002360 int newFlags = oldFlags;
2361 int mask = 0;
2362 int whitelistFlagsCopy = whitelistFlags;
2363 while (whitelistFlagsCopy != 0) {
2364 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
2365 whitelistFlagsCopy &= ~flag;
2366 switch (flag) {
2367 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
2368 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2369 if (permissions != null && permissions.contains(permissionName)) {
2370 newFlags |=
2371 PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2372 } else {
2373 newFlags &=
2374 ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2375 }
2376 }
2377 break;
2378 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
2379 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2380 if (permissions != null && permissions.contains(permissionName)) {
2381 newFlags |=
2382 PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2383 } else {
2384 newFlags &=
2385 ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2386 }
2387 }
2388 break;
2389 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
2390 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2391 if (permissions != null && permissions.contains(permissionName)) {
2392 newFlags |=
2393 PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2394 } else {
2395 newFlags &= ~PackageManager
2396 .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2397 }
2398 }
2399 break;
2400 }
2401 }
2402
2403 if (oldFlags == newFlags) {
2404 continue;
2405 }
2406
2407 updatePermissions = true;
2408
2409 final boolean wasWhitelisted = (oldFlags
2410 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2411 final boolean isWhitelisted = (newFlags
2412 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2413
2414 // If the permission is policy fixed as granted but it is no longer
2415 // on any of the whitelists we need to clear the policy fixed flag
2416 // as whitelisting trumps policy i.e. policy cannot grant a non
2417 // grantable permission.
2418 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2419 final boolean isGranted = permissionsState.hasPermission(permissionName,
2420 userId);
2421 if (!isWhitelisted && isGranted) {
2422 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2423 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2424 }
2425 }
2426
2427 // If we are whitelisting an app that does not support runtime permissions
2428 // we need to make sure it goes through the permission review UI at launch.
2429 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2430 && !wasWhitelisted && isWhitelisted) {
2431 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2432 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2433 }
2434
2435 updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
2436 callingUid, userId, false, null /*callback*/);
2437 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002438 }
2439
2440 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07002441 // Update permission of this app to take into account the new whitelist state.
2442 restorePermissionState(pkg, false, pkg.packageName, callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002443
2444 // If this resulted in losing a permission we need to kill the app.
Nicholas Sauerdf932932019-08-27 08:43:23 -07002445 int oldGrantedRestrictedPermissionsByUserCount =
2446 oldGrantedRestrictedPermissionsByUser.size();
2447 for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
2448 final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
2449 final ArraySet<String> oldGrantedRestrictedPermissions =
2450 oldGrantedRestrictedPermissionsByUser.valueAt(j);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002451 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
2452 for (int i = 0; i < oldGrantedCount; i++) {
2453 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
2454 // Sometimes we create a new permission state instance during update.
2455 if (!ps.getPermissionsState().hasPermission(permission, userId)) {
2456 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2457 break;
2458 }
2459 }
2460 }
2461 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002462 }
2463
Andreas Gampea36dc622018-02-05 17:19:22 -08002464 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002465 private int[] revokeUnusedSharedUserPermissionsLocked(
2466 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002467 // Collect all used permissions in the UID
2468 final ArraySet<String> usedPermissions = new ArraySet<>();
2469 final List<PackageParser.Package> pkgList = suSetting.getPackages();
2470 if (pkgList == null || pkgList.size() == 0) {
2471 return EmptyArray.INT;
2472 }
2473 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07002474 if (pkg.requestedPermissions == null) {
2475 continue;
2476 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002477 final int requestedPermCount = pkg.requestedPermissions.size();
2478 for (int j = 0; j < requestedPermCount; j++) {
2479 String permission = pkg.requestedPermissions.get(j);
2480 BasePermission bp = mSettings.getPermissionLocked(permission);
2481 if (bp != null) {
2482 usedPermissions.add(permission);
2483 }
2484 }
2485 }
2486
2487 PermissionsState permissionsState = suSetting.getPermissionsState();
2488 // Prune install permissions
2489 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2490 final int installPermCount = installPermStates.size();
2491 for (int i = installPermCount - 1; i >= 0; i--) {
2492 PermissionState permissionState = installPermStates.get(i);
2493 if (!usedPermissions.contains(permissionState.getName())) {
2494 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2495 if (bp != null) {
2496 permissionsState.revokeInstallPermission(bp);
2497 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002498 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002499 }
2500 }
2501 }
2502
2503 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2504
2505 // Prune runtime permissions
2506 for (int userId : allUserIds) {
2507 List<PermissionState> runtimePermStates = permissionsState
2508 .getRuntimePermissionStates(userId);
2509 final int runtimePermCount = runtimePermStates.size();
2510 for (int i = runtimePermCount - 1; i >= 0; i--) {
2511 PermissionState permissionState = runtimePermStates.get(i);
2512 if (!usedPermissions.contains(permissionState.getName())) {
2513 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2514 if (bp != null) {
2515 permissionsState.revokeRuntimePermission(bp, userId);
2516 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002517 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002518 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2519 runtimePermissionChangedUserIds, userId);
2520 }
2521 }
2522 }
2523 }
2524
2525 return runtimePermissionChangedUserIds;
2526 }
2527
Todd Kennedyc8423932017-10-05 08:58:36 -07002528 private String[] getAppOpPermissionPackages(String permName) {
2529 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2530 return null;
2531 }
2532 synchronized (mLock) {
2533 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2534 if (pkgs == null) {
2535 return null;
2536 }
2537 return pkgs.toArray(new String[pkgs.size()]);
2538 }
2539 }
2540
2541 private int getPermissionFlags(
2542 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002543 if (!mUserManagerInt.exists(userId)) {
2544 return 0;
2545 }
2546
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002547 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
Todd Kennedy0eb97382017-10-03 16:57:22 -07002548
2549 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002550 true, // requireFullPermission
2551 false, // checkShell
2552 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002553 "getPermissionFlags");
2554
2555 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2556 if (pkg == null || pkg.mExtras == null) {
2557 return 0;
2558 }
2559 synchronized (mLock) {
2560 if (mSettings.getPermissionLocked(permName) == null) {
2561 return 0;
2562 }
2563 }
2564 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2565 return 0;
2566 }
2567 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2568 PermissionsState permissionsState = ps.getPermissionsState();
2569 return permissionsState.getPermissionFlags(permName, userId);
2570 }
2571
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002572 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2573 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2574 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2575
2576 private void updatePermissions(String packageName, PackageParser.Package pkg,
2577 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2578 PermissionCallback callback) {
2579 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2580 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2581 updatePermissions(
2582 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2583 if (pkg != null && pkg.childPackages != null) {
2584 for (PackageParser.Package childPkg : pkg.childPackages) {
2585 updatePermissions(childPkg.packageName, childPkg,
2586 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2587 }
2588 }
2589 }
2590
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002591 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07002592 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002593 final int flags = UPDATE_PERMISSIONS_ALL |
2594 (sdkUpdated
2595 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2596 : 0);
2597 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2598 }
2599
2600 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2601 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2602 PermissionCallback callback) {
2603 // TODO: Most of the methods exposing BasePermission internals [source package name,
2604 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2605 // have package settings, we should make note of it elsewhere [map between
2606 // source package name and BasePermission] and cycle through that here. Then we
2607 // define a single method on BasePermission that takes a PackageSetting, changing
2608 // package name and a package.
2609 // NOTE: With this approach, we also don't need to tree trees differently than
2610 // normal permissions. Today, we need two separate loops because these BasePermission
2611 // objects are stored separately.
2612 // Make sure there are no dangling permission trees.
2613 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2614
2615 // Make sure all dynamic permissions have been assigned to a package,
2616 // and make sure there are no dangling permissions.
2617 flags = updatePermissions(changingPkgName, changingPkg, flags);
2618
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002619 synchronized (mLock) {
2620 if (mBackgroundPermissions == null) {
2621 // Cache background -> foreground permission mapping.
2622 // Only system declares background permissions, hence mapping does never change.
2623 mBackgroundPermissions = new ArrayMap<>();
2624 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002625 if (bp.perm != null && bp.perm.info != null
2626 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002627 String fgPerm = bp.name;
2628 String bgPerm = bp.perm.info.backgroundPermission;
2629
2630 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2631 if (fgPerms == null) {
2632 fgPerms = new ArrayList<>();
2633 mBackgroundPermissions.put(bgPerm, fgPerms);
2634 }
2635
2636 fgPerms.add(fgPerm);
2637 }
2638 }
2639 }
2640 }
2641
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002642 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002643 // Now update the permissions for all packages, in particular
2644 // replace the granted permissions of the system packages.
2645 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2646 for (PackageParser.Package pkg : allPackages) {
2647 if (pkg != changingPkg) {
2648 // Only replace for packages on requested volume
2649 final String volumeUuid = getVolumeUuidForPackage(pkg);
2650 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2651 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002652 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002653 }
2654 }
2655 }
2656
2657 if (changingPkg != null) {
2658 // Only replace for packages on requested volume
2659 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2660 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2661 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002662 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002663 }
2664 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2665 }
2666
2667 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002668 Set<BasePermission> needsUpdate = null;
2669 synchronized (mLock) {
2670 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2671 while (it.hasNext()) {
2672 final BasePermission bp = it.next();
2673 if (bp.isDynamic()) {
2674 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2675 }
2676 if (bp.getSourcePackageSetting() != null) {
2677 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002678 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002679 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2680 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002681 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002682 it.remove();
2683 }
2684 continue;
2685 }
2686 if (needsUpdate == null) {
2687 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2688 }
2689 needsUpdate.add(bp);
2690 }
2691 }
2692 if (needsUpdate != null) {
2693 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002694 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002695 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2696 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002697 if (sourcePkg != null && sourcePkg.mExtras != null) {
2698 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002699 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002700 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002701 }
2702 continue;
2703 }
2704 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2705 + " from package " + bp.getSourcePackageName());
2706 mSettings.removePermissionLocked(bp.getName());
2707 }
2708 }
2709 }
2710 return flags;
2711 }
2712
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002713 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002714 int flags) {
2715 Set<BasePermission> needsUpdate = null;
2716 synchronized (mLock) {
2717 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2718 while (it.hasNext()) {
2719 final BasePermission bp = it.next();
2720 if (bp.getSourcePackageSetting() != null) {
2721 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002722 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002723 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2724 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002725 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002726 it.remove();
2727 }
2728 continue;
2729 }
2730 if (needsUpdate == null) {
2731 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2732 }
2733 needsUpdate.add(bp);
2734 }
2735 }
2736 if (needsUpdate != null) {
2737 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002738 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002739 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2740 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002741 if (sourcePkg != null && sourcePkg.mExtras != null) {
2742 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002743 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002744 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002745 }
2746 continue;
2747 }
2748 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2749 + " from package " + bp.getSourcePackageName());
2750 mSettings.removePermissionLocked(bp.getName());
2751 }
2752 }
2753 }
2754 return flags;
2755 }
2756
Todd Kennedy0eb97382017-10-03 16:57:22 -07002757 private void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002758 int flagValues, int callingUid, int userId, boolean overridePolicy,
2759 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002760 if (!mUserManagerInt.exists(userId)) {
2761 return;
2762 }
2763
2764 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2765
2766 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002767 true, // requireFullPermission
2768 true, // checkShell
2769 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002770 "updatePermissionFlags");
2771
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002772 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2773 throw new SecurityException("updatePermissionFlags requires "
2774 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2775 }
2776
Todd Kennedy0eb97382017-10-03 16:57:22 -07002777 // Only the system can change these flags and nothing else.
2778 if (callingUid != Process.SYSTEM_UID) {
2779 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2780 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2781 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2782 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2783 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002784 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2785 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2786 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2787 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002788 }
2789
2790 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2791 if (pkg == null || pkg.mExtras == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002792 Log.e(TAG, "Unknown package: " + packageName);
2793 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002794 }
2795 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2796 throw new IllegalArgumentException("Unknown package: " + packageName);
2797 }
2798
2799 final BasePermission bp;
2800 synchronized (mLock) {
2801 bp = mSettings.getPermissionLocked(permName);
2802 }
2803 if (bp == null) {
2804 throw new IllegalArgumentException("Unknown permission: " + permName);
2805 }
2806
2807 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2808 final PermissionsState permissionsState = ps.getPermissionsState();
2809 final boolean hadState =
2810 permissionsState.getRuntimePermissionState(permName, userId) != null;
2811 final boolean permissionUpdated =
2812 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002813 if (permissionUpdated && bp.isRuntime()) {
2814 notifyRuntimePermissionStateChanged(packageName, userId);
2815 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002816 if (permissionUpdated && callback != null) {
2817 // Install and runtime permissions are stored in different places,
2818 // so figure out what permission changed and persist the change.
2819 if (permissionsState.getInstallPermissionState(permName) != null) {
2820 callback.onInstallPermissionUpdated();
2821 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2822 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002823 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002824 }
2825 }
2826 }
2827
2828 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2829 int userId, Collection<Package> packages, PermissionCallback callback) {
2830 if (!mUserManagerInt.exists(userId)) {
2831 return false;
2832 }
2833
2834 enforceGrantRevokeRuntimePermissionPermissions(
2835 "updatePermissionFlagsForAllApps");
2836 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002837 true, // requireFullPermission
2838 true, // checkShell
2839 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002840 "updatePermissionFlagsForAllApps");
2841
2842 // Only the system can change system fixed flags.
2843 if (callingUid != Process.SYSTEM_UID) {
2844 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2845 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2846 }
2847
2848 boolean changed = false;
2849 for (PackageParser.Package pkg : packages) {
2850 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2851 if (ps == null) {
2852 continue;
2853 }
2854 PermissionsState permissionsState = ps.getPermissionsState();
2855 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2856 userId, flagMask, flagValues);
2857 }
2858 return changed;
2859 }
2860
2861 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2862 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2863 != PackageManager.PERMISSION_GRANTED
2864 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2865 != PackageManager.PERMISSION_GRANTED) {
2866 throw new SecurityException(message + " requires "
2867 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2868 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2869 }
2870 }
2871
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002872 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2873 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2874 != PackageManager.PERMISSION_GRANTED
2875 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2876 != PackageManager.PERMISSION_GRANTED
2877 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2878 != PackageManager.PERMISSION_GRANTED) {
2879 throw new SecurityException(message + " requires "
2880 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2881 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
2882 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2883 }
2884 }
2885
Todd Kennedy0eb97382017-10-03 16:57:22 -07002886 /**
2887 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2888 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2889 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2890 * @param message the message to log on security exception
2891 */
2892 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002893 boolean requireFullPermission, boolean checkShell,
2894 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002895 if (userId < 0) {
2896 throw new IllegalArgumentException("Invalid userId " + userId);
2897 }
2898 if (checkShell) {
2899 PackageManagerServiceUtils.enforceShellRestriction(
2900 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2901 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002902 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002903 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002904 if (requireFullPermission) {
2905 mContext.enforceCallingOrSelfPermission(
2906 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2907 } else {
2908 try {
2909 mContext.enforceCallingOrSelfPermission(
2910 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2911 } catch (SecurityException se) {
2912 mContext.enforceCallingOrSelfPermission(
2913 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2914 }
2915 }
2916 }
2917 }
2918
Andreas Gampea71bee82018-07-20 12:55:36 -07002919 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002920 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2921 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002922 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002923 size += tree.calculateFootprint(perm);
2924 }
2925 return size;
2926 }
2927
Andreas Gampea71bee82018-07-20 12:55:36 -07002928 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002929 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2930 // We calculate the max size of permissions defined by this uid and throw
2931 // if that plus the size of 'info' would exceed our stated maximum.
2932 if (tree.getUid() != Process.SYSTEM_UID) {
2933 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2934 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2935 throw new SecurityException("Permission tree size cap exceeded");
2936 }
2937 }
2938 }
2939
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002940 private void systemReady() {
2941 mSystemReady = true;
2942 if (mPrivappPermissionsViolations != null) {
2943 throw new IllegalStateException("Signature|privileged permissions not in "
2944 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2945 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002946
2947 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov0b41c892019-07-26 17:45:56 -07002948 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002949 }
2950
2951 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2952 if (pkg == null) {
2953 return StorageManager.UUID_PRIVATE_INTERNAL;
2954 }
2955 if (pkg.isExternal()) {
2956 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2957 return StorageManager.UUID_PRIMARY_PHYSICAL;
2958 } else {
2959 return pkg.volumeUuid;
2960 }
2961 } else {
2962 return StorageManager.UUID_PRIVATE_INTERNAL;
2963 }
2964 }
2965
Todd Kennedyc8423932017-10-05 08:58:36 -07002966 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2967 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2968 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2969 return true;
2970 }
2971 }
2972 return false;
2973 }
2974
Todd Kennedy0eb97382017-10-03 16:57:22 -07002975 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002976 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002977 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002978 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002979 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002980 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002981 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002982 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2983 final LogMaker log = new LogMaker(action);
2984 log.setPackageName(packageName);
2985 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002986
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002987 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002988 }
2989
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002990 /**
2991 * Get the mapping of background permissions to their foreground permissions.
2992 *
2993 * <p>Only initialized in the system server.
2994 *
2995 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2996 */
2997 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2998 return mBackgroundPermissions;
2999 }
3000
Philip P. Moltmann48456672019-01-20 13:14:03 -08003001 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003002 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003003 public void systemReady() {
3004 PermissionManagerService.this.systemReady();
3005 }
3006 @Override
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003007 public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003008 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
3009 }
3010 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07003011 public void revokeRuntimePermissionsIfGroupChanged(
3012 @NonNull PackageParser.Package newPackage,
3013 @NonNull PackageParser.Package oldPackage,
3014 @NonNull ArrayList<String> allPackageNames,
3015 @NonNull PermissionCallback permissionCallback) {
3016 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
3017 oldPackage, allPackageNames, permissionCallback);
3018 }
3019 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003020 public void addAllPermissions(Package pkg, boolean chatty) {
3021 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003022 }
3023 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003024 public void addAllPermissionGroups(Package pkg, boolean chatty) {
3025 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
3026 }
3027 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00003028 public void removeAllPermissions(Package pkg, boolean chatty) {
3029 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07003030 }
3031 @Override
3032 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003033 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07003034 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
3035 }
3036 @Override
3037 public void removeDynamicPermission(String permName, int callingUid,
3038 PermissionCallback callback) {
3039 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003040 }
3041 @Override
3042 public void grantRuntimePermission(String permName, String packageName,
3043 boolean overridePolicy, int callingUid, int userId,
3044 PermissionCallback callback) {
3045 PermissionManagerService.this.grantRuntimePermission(
3046 permName, packageName, overridePolicy, callingUid, userId, callback);
3047 }
3048 @Override
3049 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3050 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3051 PermissionManagerService.this.grantRequestedRuntimePermissions(
3052 pkg, userIds, grantedPermissions, callingUid, callback);
3053 }
3054 @Override
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003055 public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
3056 @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
3057 return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
3058 whitelistFlags, userId);
3059 }
3060 @Override
3061 public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
3062 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
3063 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
3064 @NonNull PermissionCallback callback) {
3065 PermissionManagerService.this.setWhitelistedRestrictedPermissions(
3066 pkg, userIds, permissions, callingUid, whitelistFlags, callback);
3067 }
3068 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003069 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
3070 int callingUid, PermissionCallback callback) {
3071 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
3072 pkg, callingUid, callback);
3073 }
3074 @Override
3075 public void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003076 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003077 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003078 overridePolicy, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003079 }
3080 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003081 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
3082 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3083 PermissionManagerService.this.updatePermissions(
3084 packageName, pkg, replaceGrant, allPackages, callback);
3085 }
3086 @Override
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08003087 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003088 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003089 PermissionManagerService.this.updateAllPermissions(
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003090 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003091 }
3092 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003093 public String[] getAppOpPermissionPackages(String permName) {
3094 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
3095 }
3096 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003097 public int getPermissionFlags(String permName, String packageName, int callingUid,
3098 int userId) {
3099 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
3100 callingUid, userId);
3101 }
3102 @Override
3103 public void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003104 int flagValues, int callingUid, int userId, boolean overridePolicy,
3105 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003106 PermissionManagerService.this.updatePermissionFlags(
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003107 permName, packageName, flagMask, flagValues, callingUid, userId,
3108 overridePolicy, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003109 }
3110 @Override
3111 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
3112 int userId, Collection<Package> packages, PermissionCallback callback) {
3113 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
3114 flagMask, flagValues, callingUid, userId, packages, callback);
3115 }
3116 @Override
3117 public void enforceCrossUserPermission(int callingUid, int userId,
3118 boolean requireFullPermission, boolean checkShell, String message) {
3119 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07003120 requireFullPermission, checkShell, false, message);
3121 }
3122 @Override
3123 public void enforceCrossUserPermission(int callingUid, int userId,
3124 boolean requireFullPermission, boolean checkShell,
3125 boolean requirePermissionWhenSameUser, String message) {
3126 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3127 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003128 }
3129 @Override
3130 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3131 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
3132 }
3133 @Override
3134 public int checkPermission(String permName, String packageName, int callingUid,
3135 int userId) {
3136 return PermissionManagerService.this.checkPermission(
3137 permName, packageName, callingUid, userId);
3138 }
3139 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07003140 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
3141 int callingUid) {
3142 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07003143 }
3144 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003145 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
3146 int callingUid) {
3147 return PermissionManagerService.this.getPermissionGroupInfo(
3148 groupName, flags, callingUid);
3149 }
3150 @Override
3151 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
3152 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
3153 }
3154 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003155 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
3156 int callingUid) {
3157 return PermissionManagerService.this.getPermissionInfo(
3158 permName, packageName, flags, callingUid);
3159 }
3160 @Override
3161 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
3162 int callingUid) {
3163 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
3164 }
3165 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003166 public PermissionSettings getPermissionSettings() {
3167 return mSettings;
3168 }
3169 @Override
3170 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
3171 return mDefaultPermissionGrantPolicy;
3172 }
3173 @Override
3174 public BasePermission getPermissionTEMP(String permName) {
3175 synchronized (PermissionManagerService.this.mLock) {
3176 return mSettings.getPermissionLocked(permName);
3177 }
3178 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08003179
3180 @Override
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07003181 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
3182 @PermissionInfo.Protection int protectionLevel) {
3183 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
3184
3185 synchronized (PermissionManagerService.this.mLock) {
3186 int numTotalPermissions = mSettings.mPermissions.size();
3187
3188 for (int i = 0; i < numTotalPermissions; i++) {
3189 BasePermission bp = mSettings.mPermissions.valueAt(i);
3190
3191 if (bp.perm != null && bp.perm.info != null
3192 && bp.protectionLevel == protectionLevel) {
3193 matchingPermissions.add(bp.perm.info);
3194 }
3195 }
3196 }
3197
3198 return matchingPermissions;
3199 }
3200
3201 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08003202 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
3203 return PermissionManagerService.this.backupRuntimePermissions(user);
3204 }
3205
3206 @Override
3207 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
3208 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
3209 }
3210
3211 @Override
3212 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
3213 @NonNull UserHandle user) {
3214 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
3215 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003216
3217 @Override
3218 public void addOnRuntimePermissionStateChangedListener(
3219 OnRuntimePermissionStateChangedListener listener) {
3220 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
3221 listener);
3222 }
3223
3224 @Override
3225 public void removeOnRuntimePermissionStateChangedListener(
3226 OnRuntimePermissionStateChangedListener listener) {
3227 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
3228 listener);
3229 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003230 }
3231}