blob: bb9d92120f4393adbf73192ca5005c20b1157bef [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 }
1713 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1714 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1715 final PackageParser.Package systemPackage =
1716 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001717
1718 // check if the package is allow to use this signature permission. A package is allowed to
1719 // use a signature permission if:
1720 // - it has the same set of signing certificates as the source package
1721 // - or its signing certificate was rotated from the source package's certificate
1722 // - or its signing certificate is a previous signing certificate of the defining
1723 // package, and the defining package still trusts the old certificate for permissions
1724 // - or it shares the above relationships with the system package
1725 boolean allowed =
1726 pkg.mSigningDetails.hasAncestorOrSelf(
1727 bp.getSourcePackageSetting().getSigningDetails())
1728 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1729 pkg.mSigningDetails,
1730 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1731 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1732 || systemPackage.mSigningDetails.checkCapability(
1733 pkg.mSigningDetails,
1734 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001735 if (!allowed && (privilegedPermission || oemPermission)) {
1736 if (pkg.isSystem()) {
1737 // For updated system applications, a privileged/oem permission
1738 // is granted only if it had been defined by the original application.
1739 if (pkg.isUpdatedSystemApp()) {
1740 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001741 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001742 final PackageSetting disabledPs =
1743 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1744 if (disabledPs != null
1745 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1746 // If the original was granted this permission, we take
1747 // that grant decision as read and propagate it to the
1748 // update.
1749 if ((privilegedPermission && disabledPs.isPrivileged())
1750 || (oemPermission && disabledPs.isOem()
1751 && canGrantOemPermission(disabledPs, perm))) {
1752 allowed = true;
1753 }
1754 } else {
1755 // The system apk may have been updated with an older
1756 // version of the one on the data partition, but which
1757 // granted a new system permission that it didn't have
1758 // before. In this case we do want to allow the app to
1759 // now get the new permission if the ancestral apk is
1760 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001761 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001762 && isPackageRequestingPermission(disabledPkg, perm)
1763 && ((privilegedPermission && disabledPs.isPrivileged())
1764 || (oemPermission && disabledPs.isOem()
1765 && canGrantOemPermission(disabledPs, perm)))) {
1766 allowed = true;
1767 }
1768 // Also if a privileged parent package on the system image or any of
1769 // its children requested a privileged/oem permission, the updated child
1770 // packages can also get the permission.
1771 if (pkg.parentPackage != null) {
1772 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001773 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001774 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1775 ? (PackageSetting) disabledParentPkg.mExtras : null;
1776 if (disabledParentPkg != null
1777 && ((privilegedPermission && disabledParentPs.isPrivileged())
1778 || (oemPermission && disabledParentPs.isOem()))) {
1779 if (isPackageRequestingPermission(disabledParentPkg, perm)
1780 && canGrantOemPermission(disabledParentPs, perm)) {
1781 allowed = true;
1782 } else if (disabledParentPkg.childPackages != null) {
1783 for (PackageParser.Package disabledChildPkg
1784 : disabledParentPkg.childPackages) {
1785 final PackageSetting disabledChildPs =
1786 (disabledChildPkg != null)
1787 ? (PackageSetting) disabledChildPkg.mExtras
1788 : null;
1789 if (isPackageRequestingPermission(disabledChildPkg, perm)
1790 && canGrantOemPermission(
1791 disabledChildPs, perm)) {
1792 allowed = true;
1793 break;
1794 }
1795 }
1796 }
1797 }
1798 }
1799 }
1800 } else {
1801 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1802 allowed = (privilegedPermission && pkg.isPrivileged())
1803 || (oemPermission && pkg.isOem()
1804 && canGrantOemPermission(ps, perm));
1805 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001806 // In any case, don't grant a privileged permission to privileged vendor apps, if
1807 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1808 // flag.
1809 if (allowed && privilegedPermission &&
1810 !vendorPrivilegedPermission && pkg.isVendor()) {
1811 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1812 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1813 allowed = false;
1814 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001815 }
1816 }
1817 if (!allowed) {
1818 if (!allowed
1819 && bp.isPre23()
1820 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1821 // If this was a previously normal/dangerous permission that got moved
1822 // to a system permission as part of the runtime permission redesign, then
1823 // we still want to blindly grant it to old apps.
1824 allowed = true;
1825 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001826 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1827 // need a separate flag anymore. Hence we need to check which
1828 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001829 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001830 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1831 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1832 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1833 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1834 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001835 // If this permission is to be granted to the system installer and
1836 // this app is an installer, then it gets the permission.
1837 allowed = true;
1838 }
1839 if (!allowed && bp.isVerifier()
1840 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1841 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1842 // If this permission is to be granted to the system verifier and
1843 // this app is a verifier, then it gets the permission.
1844 allowed = true;
1845 }
1846 if (!allowed && bp.isPreInstalled()
1847 && pkg.isSystem()) {
1848 // Any pre-installed system app is allowed to get this permission.
1849 allowed = true;
1850 }
1851 if (!allowed && bp.isDevelopment()) {
1852 // For development permissions, a development permission
1853 // is granted only if it was already granted.
1854 allowed = origPermissions.hasInstallPermission(perm);
1855 }
1856 if (!allowed && bp.isSetup()
1857 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1858 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1859 // If this permission is to be granted to the system setup wizard and
1860 // this app is a setup wizard, then it gets the permission.
1861 allowed = true;
1862 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001863 if (!allowed && bp.isSystemTextClassifier()
1864 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1865 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1866 UserHandle.USER_SYSTEM))) {
1867 // Special permissions for the system default text classifier.
1868 allowed = true;
1869 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001870 if (!allowed && bp.isConfigurator()
1871 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1872 PackageManagerInternal.PACKAGE_CONFIGURATOR,
1873 UserHandle.USER_SYSTEM))) {
1874 // Special permissions for the device configurator.
1875 allowed = true;
1876 }
Varun Shah5f303652018-11-16 18:11:19 -08001877 if (!allowed && bp.isWellbeing()
1878 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1879 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
1880 // Special permission granted only to the OEM specified wellbeing app
1881 allowed = true;
1882 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07001883 if (!allowed && bp.isDocumenter()
1884 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1885 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
1886 // If this permission is to be granted to the documenter and
1887 // this app is the documenter, then it gets the permission.
1888 allowed = true;
1889 }
Joe Onorato5a15b552018-12-18 10:40:04 -08001890 if (!allowed && bp.isIncidentReportApprover()
1891 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1892 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
1893 UserHandle.USER_SYSTEM))) {
1894 // If this permission is to be granted to the incident report approver and
1895 // this app is the incident report approver, then it gets the permission.
1896 allowed = true;
1897 }
George Hodulikcd7695d2019-01-29 18:17:05 -08001898 if (!allowed && bp.isAppPredictor()
1899 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1900 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
1901 // Special permissions for the system app predictor.
1902 allowed = true;
1903 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001904 }
1905 return allowed;
1906 }
1907
1908 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1909 if (!ps.isOem()) {
1910 return false;
1911 }
1912 // all oem permissions must explicitly be granted or denied
1913 final Boolean granted =
1914 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1915 if (granted == null) {
1916 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1917 + ps.name + " must be explicitly declared granted or not");
1918 }
1919 return Boolean.TRUE == granted;
1920 }
1921
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001922 private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
1923 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001924 // Permission review applies only to apps not supporting the new permission model.
1925 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1926 return false;
1927 }
1928
1929 // Legacy apps have the permission and get user consent on launch.
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001930 if (pkg.mExtras == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001931 return false;
1932 }
1933 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1934 final PermissionsState permissionsState = ps.getPermissionsState();
1935 return permissionsState.isPermissionReviewRequired(userId);
1936 }
1937
1938 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1939 final int permCount = pkg.requestedPermissions.size();
1940 for (int j = 0; j < permCount; j++) {
1941 String requestedPermission = pkg.requestedPermissions.get(j);
1942 if (permission.equals(requestedPermission)) {
1943 return true;
1944 }
1945 }
1946 return false;
1947 }
1948
Andreas Gampea36dc622018-02-05 17:19:22 -08001949 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001950 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1951 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1952 if (pkg.parentPackage == null) {
1953 return;
1954 }
1955 if (pkg.requestedPermissions == null) {
1956 return;
1957 }
1958 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001959 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001960 if (disabledPkg == null || disabledPkg.mExtras == null) {
1961 return;
1962 }
1963 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1964 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1965 return;
1966 }
1967 final int permCount = pkg.requestedPermissions.size();
1968 for (int i = 0; i < permCount; i++) {
1969 String permission = pkg.requestedPermissions.get(i);
1970 BasePermission bp = mSettings.getPermissionLocked(permission);
1971 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1972 continue;
1973 }
1974 for (int userId : mUserManagerInt.getUserIds()) {
1975 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1976 grantRuntimePermission(
1977 permission, pkg.packageName, false, callingUid, userId, callback);
1978 }
1979 }
1980 }
1981 }
1982
1983 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1984 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1985 for (int userId : userIds) {
1986 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1987 callback);
1988 }
1989 }
1990
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001991 private @Nullable List<String> getWhitelistedRestrictedPermissions(
1992 @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
1993 @UserIdInt int userId) {
1994 final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
1995 if (packageSetting == null) {
1996 return null;
1997 }
1998
1999 final PermissionsState permissionsState = packageSetting.getPermissionsState();
2000
2001 int queryFlags = 0;
2002 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
2003 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2004 }
2005 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
2006 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2007 }
2008 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
2009 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2010 }
2011
2012 ArrayList<String> whitelistedPermissions = null;
2013
2014 final int permissionCount = pkg.requestedPermissions.size();
2015 for (int i = 0; i < permissionCount; i++) {
2016 final String permissionName = pkg.requestedPermissions.get(i);
2017 final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
2018 if ((currentFlags & queryFlags) != 0) {
2019 if (whitelistedPermissions == null) {
2020 whitelistedPermissions = new ArrayList<>();
2021 }
2022 whitelistedPermissions.add(permissionName);
2023 }
2024 }
2025
2026 return whitelistedPermissions;
2027 }
2028
Todd Kennedy0eb97382017-10-03 16:57:22 -07002029 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2030 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2031 PackageSetting ps = (PackageSetting) pkg.mExtras;
2032 if (ps == null) {
2033 return;
2034 }
2035
2036 PermissionsState permissionsState = ps.getPermissionsState();
2037
2038 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2039 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2040
2041 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2042 >= Build.VERSION_CODES.M;
2043
2044 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
2045
2046 for (String permission : pkg.requestedPermissions) {
2047 final BasePermission bp;
2048 synchronized (mLock) {
2049 bp = mSettings.getPermissionLocked(permission);
2050 }
2051 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2052 && (!instantApp || bp.isInstant())
2053 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2054 && (grantedPermissions == null
2055 || ArrayUtils.contains(grantedPermissions, permission))) {
2056 final int flags = permissionsState.getPermissionFlags(permission, userId);
2057 if (supportsRuntimePermissions) {
2058 // Installer cannot change immutable permissions.
2059 if ((flags & immutableFlags) == 0) {
2060 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
2061 userId, callback);
2062 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002063 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002064 // In permission review mode we clear the review flag when we
2065 // are asked to install the app with all permissions granted.
2066 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2067 updatePermissionFlags(permission, pkg.packageName,
2068 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002069 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002070 }
2071 }
2072 }
2073 }
2074 }
2075
2076 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2077 int callingUid, final int userId, PermissionCallback callback) {
2078 if (!mUserManagerInt.exists(userId)) {
2079 Log.e(TAG, "No such user:" + userId);
2080 return;
2081 }
2082
2083 mContext.enforceCallingOrSelfPermission(
2084 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
2085 "grantRuntimePermission");
2086
2087 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002088 true, // requireFullPermission
2089 true, // checkShell
2090 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002091 "grantRuntimePermission");
2092
2093 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2094 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002095 Log.e(TAG, "Unknown package: " + packageName);
2096 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002097 }
2098 final BasePermission bp;
2099 synchronized(mLock) {
2100 bp = mSettings.getPermissionLocked(permName);
2101 }
2102 if (bp == null) {
2103 throw new IllegalArgumentException("Unknown permission: " + permName);
2104 }
2105 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2106 throw new IllegalArgumentException("Unknown package: " + packageName);
2107 }
2108
2109 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2110
2111 // If a permission review is required for legacy apps we represent
2112 // their permissions as always granted runtime ones since we need
2113 // to keep the review required permission flag per user while an
2114 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002115 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002116 && bp.isRuntime()) {
2117 return;
2118 }
2119
2120 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2121
2122 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2123 final PermissionsState permissionsState = ps.getPermissionsState();
2124
2125 final int flags = permissionsState.getPermissionFlags(permName, userId);
2126 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002127 Log.e(TAG, "Cannot grant system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002128 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002129 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002130 }
2131 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002132 Log.e(TAG, "Cannot grant policy fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002133 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002134 return;
2135 }
2136
Philip P. Moltmannd6b849c2019-05-15 16:36:32 -07002137 if (bp.isHardRestricted()
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002138 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002139 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002140 + permName + " for package " + packageName);
2141 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002142 }
2143
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002144 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Philip P. Moltmann69b645f2019-06-17 14:28:11 -07002145 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002146 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
2147 + packageName);
2148 return;
2149 }
2150
Todd Kennedy0eb97382017-10-03 16:57:22 -07002151 if (bp.isDevelopment()) {
2152 // Development permissions must be handled specially, since they are not
2153 // normal runtime permissions. For now they apply to all users.
2154 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002155 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002156 if (callback != null) {
2157 callback.onInstallPermissionGranted();
2158 }
2159 }
2160 return;
2161 }
2162
2163 if (ps.getInstantApp(userId) && !bp.isInstant()) {
2164 throw new SecurityException("Cannot grant non-ephemeral permission"
2165 + permName + " for package " + packageName);
2166 }
2167
2168 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2169 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2170 return;
2171 }
2172
2173 final int result = permissionsState.grantRuntimePermission(bp, userId);
2174 switch (result) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002175 case PERMISSION_OPERATION_FAILURE: {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002176 return;
2177 }
2178
2179 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2180 if (callback != null) {
2181 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2182 }
2183 }
2184 break;
2185 }
2186
2187 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002188 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002189 }
2190
2191 if (callback != null) {
2192 callback.onPermissionGranted(uid, userId);
2193 }
2194
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002195 if (bp.isRuntime()) {
2196 notifyRuntimePermissionStateChanged(packageName, userId);
2197 }
2198
Todd Kennedy0eb97382017-10-03 16:57:22 -07002199 // Only need to do this if user is initialized. Otherwise it's a new user
2200 // and there are no processes running as the user yet and there's no need
2201 // to make an expensive call to remount processes for the changed permissions.
2202 if (READ_EXTERNAL_STORAGE.equals(permName)
2203 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2204 final long token = Binder.clearCallingIdentity();
2205 try {
2206 if (mUserManagerInt.isUserInitialized(userId)) {
2207 StorageManagerInternal storageManagerInternal = LocalServices.getService(
2208 StorageManagerInternal.class);
2209 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2210 }
2211 } finally {
2212 Binder.restoreCallingIdentity(token);
2213 }
2214 }
2215
2216 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002217
2218 private void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002219 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002220 if (!mUserManagerInt.exists(userId)) {
2221 Log.e(TAG, "No such user:" + userId);
2222 return;
2223 }
2224
2225 mContext.enforceCallingOrSelfPermission(
2226 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2227 "revokeRuntimePermission");
2228
2229 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002230 true, // requireFullPermission
2231 true, // checkShell
2232 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002233 "revokeRuntimePermission");
2234
Todd Kennedy0eb97382017-10-03 16:57:22 -07002235 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2236 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002237 Log.e(TAG, "Unknown package: " + packageName);
2238 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002239 }
2240 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2241 throw new IllegalArgumentException("Unknown package: " + packageName);
2242 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002243 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002244 if (bp == null) {
2245 throw new IllegalArgumentException("Unknown permission: " + permName);
2246 }
2247
2248 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2249
2250 // If a permission review is required for legacy apps we represent
2251 // their permissions as always granted runtime ones since we need
2252 // to keep the review required permission flag per user while an
2253 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002254 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002255 && bp.isRuntime()) {
2256 return;
2257 }
2258
2259 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2260 final PermissionsState permissionsState = ps.getPermissionsState();
2261
2262 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07002263 // Only the system may revoke SYSTEM_FIXED permissions.
2264 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2265 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2266 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002267 + permName + " for package " + packageName);
2268 }
2269 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2270 throw new SecurityException("Cannot revoke policy fixed permission "
2271 + permName + " for package " + packageName);
2272 }
2273
2274 if (bp.isDevelopment()) {
2275 // Development permissions must be handled specially, since they are not
2276 // normal runtime permissions. For now they apply to all users.
2277 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002278 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002279 if (callback != null) {
2280 callback.onInstallPermissionRevoked();
2281 }
2282 }
2283 return;
2284 }
2285
Philip P. Moltmannf50316c2019-07-03 15:44:00 -07002286 // Permission is already revoked, no need to do anything.
2287 if (!permissionsState.hasRuntimePermission(permName, userId)) {
2288 return;
2289 }
2290
Todd Kennedy0eb97382017-10-03 16:57:22 -07002291 if (permissionsState.revokeRuntimePermission(bp, userId) ==
Philip P. Moltmann48456672019-01-20 13:14:03 -08002292 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002293 return;
2294 }
2295
2296 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002297 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002298 }
2299
2300 if (callback != null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002301 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2302 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002303
2304 if (bp.isRuntime()) {
2305 notifyRuntimePermissionStateChanged(packageName, userId);
2306 }
2307 }
2308
Nicholas Sauerdf932932019-08-27 08:43:23 -07002309 private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
2310 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
2311 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
2312 @NonNull PermissionCallback callback) {
2313
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002314 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2315 if (ps == null) {
2316 return;
2317 }
2318
2319 final PermissionsState permissionsState = ps.getPermissionsState();
Nicholas Sauerdf932932019-08-27 08:43:23 -07002320 SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002321 boolean updatePermissions = false;
2322
2323 final int permissionCount = pkg.requestedPermissions.size();
Nicholas Sauerdf932932019-08-27 08:43:23 -07002324 for (int userId : userIds) {
2325 for (int i = 0; i < permissionCount; i++) {
2326 final String permissionName = pkg.requestedPermissions.get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002327
Nicholas Sauerdf932932019-08-27 08:43:23 -07002328 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
2329 if (bp == null) {
2330 Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
2331 continue;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002332 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002333
Nicholas Sauerdf932932019-08-27 08:43:23 -07002334 if (!bp.isHardOrSoftRestricted()) {
2335 continue;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002336 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002337
Nicholas Sauerdf932932019-08-27 08:43:23 -07002338 if (permissionsState.hasPermission(permissionName, userId)) {
2339 if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) {
2340 oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>());
2341 }
2342 oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002343 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002344
Nicholas Sauerdf932932019-08-27 08:43:23 -07002345 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
Svet Ganovd563e932019-04-14 13:07:41 -07002346
Nicholas Sauerdf932932019-08-27 08:43:23 -07002347 int newFlags = oldFlags;
2348 int mask = 0;
2349 int whitelistFlagsCopy = whitelistFlags;
2350 while (whitelistFlagsCopy != 0) {
2351 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
2352 whitelistFlagsCopy &= ~flag;
2353 switch (flag) {
2354 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
2355 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2356 if (permissions != null && permissions.contains(permissionName)) {
2357 newFlags |=
2358 PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2359 } else {
2360 newFlags &=
2361 ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2362 }
2363 }
2364 break;
2365 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
2366 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2367 if (permissions != null && permissions.contains(permissionName)) {
2368 newFlags |=
2369 PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2370 } else {
2371 newFlags &=
2372 ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2373 }
2374 }
2375 break;
2376 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
2377 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2378 if (permissions != null && permissions.contains(permissionName)) {
2379 newFlags |=
2380 PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2381 } else {
2382 newFlags &= ~PackageManager
2383 .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2384 }
2385 }
2386 break;
2387 }
2388 }
2389
2390 if (oldFlags == newFlags) {
2391 continue;
2392 }
2393
2394 updatePermissions = true;
2395
2396 final boolean wasWhitelisted = (oldFlags
2397 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2398 final boolean isWhitelisted = (newFlags
2399 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2400
2401 // If the permission is policy fixed as granted but it is no longer
2402 // on any of the whitelists we need to clear the policy fixed flag
2403 // as whitelisting trumps policy i.e. policy cannot grant a non
2404 // grantable permission.
2405 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2406 final boolean isGranted = permissionsState.hasPermission(permissionName,
2407 userId);
2408 if (!isWhitelisted && isGranted) {
2409 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2410 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2411 }
2412 }
2413
2414 // If we are whitelisting an app that does not support runtime permissions
2415 // we need to make sure it goes through the permission review UI at launch.
2416 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2417 && !wasWhitelisted && isWhitelisted) {
2418 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2419 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2420 }
2421
2422 updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
2423 callingUid, userId, false, null /*callback*/);
2424 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002425 }
2426
2427 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07002428 // Update permission of this app to take into account the new whitelist state.
2429 restorePermissionState(pkg, false, pkg.packageName, callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002430
2431 // If this resulted in losing a permission we need to kill the app.
Nicholas Sauerdf932932019-08-27 08:43:23 -07002432 int oldGrantedRestrictedPermissionsByUserCount =
2433 oldGrantedRestrictedPermissionsByUser.size();
2434 for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) {
2435 final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j);
2436 final ArraySet<String> oldGrantedRestrictedPermissions =
2437 oldGrantedRestrictedPermissionsByUser.valueAt(j);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002438 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
2439 for (int i = 0; i < oldGrantedCount; i++) {
2440 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
2441 // Sometimes we create a new permission state instance during update.
2442 if (!ps.getPermissionsState().hasPermission(permission, userId)) {
2443 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2444 break;
2445 }
2446 }
2447 }
2448 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002449 }
2450
Andreas Gampea36dc622018-02-05 17:19:22 -08002451 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002452 private int[] revokeUnusedSharedUserPermissionsLocked(
2453 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002454 // Collect all used permissions in the UID
2455 final ArraySet<String> usedPermissions = new ArraySet<>();
2456 final List<PackageParser.Package> pkgList = suSetting.getPackages();
2457 if (pkgList == null || pkgList.size() == 0) {
2458 return EmptyArray.INT;
2459 }
2460 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07002461 if (pkg.requestedPermissions == null) {
2462 continue;
2463 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002464 final int requestedPermCount = pkg.requestedPermissions.size();
2465 for (int j = 0; j < requestedPermCount; j++) {
2466 String permission = pkg.requestedPermissions.get(j);
2467 BasePermission bp = mSettings.getPermissionLocked(permission);
2468 if (bp != null) {
2469 usedPermissions.add(permission);
2470 }
2471 }
2472 }
2473
2474 PermissionsState permissionsState = suSetting.getPermissionsState();
2475 // Prune install permissions
2476 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2477 final int installPermCount = installPermStates.size();
2478 for (int i = installPermCount - 1; i >= 0; i--) {
2479 PermissionState permissionState = installPermStates.get(i);
2480 if (!usedPermissions.contains(permissionState.getName())) {
2481 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2482 if (bp != null) {
2483 permissionsState.revokeInstallPermission(bp);
2484 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002485 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002486 }
2487 }
2488 }
2489
2490 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2491
2492 // Prune runtime permissions
2493 for (int userId : allUserIds) {
2494 List<PermissionState> runtimePermStates = permissionsState
2495 .getRuntimePermissionStates(userId);
2496 final int runtimePermCount = runtimePermStates.size();
2497 for (int i = runtimePermCount - 1; i >= 0; i--) {
2498 PermissionState permissionState = runtimePermStates.get(i);
2499 if (!usedPermissions.contains(permissionState.getName())) {
2500 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2501 if (bp != null) {
2502 permissionsState.revokeRuntimePermission(bp, userId);
2503 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002504 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002505 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2506 runtimePermissionChangedUserIds, userId);
2507 }
2508 }
2509 }
2510 }
2511
2512 return runtimePermissionChangedUserIds;
2513 }
2514
Todd Kennedyc8423932017-10-05 08:58:36 -07002515 private String[] getAppOpPermissionPackages(String permName) {
2516 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2517 return null;
2518 }
2519 synchronized (mLock) {
2520 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2521 if (pkgs == null) {
2522 return null;
2523 }
2524 return pkgs.toArray(new String[pkgs.size()]);
2525 }
2526 }
2527
2528 private int getPermissionFlags(
2529 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002530 if (!mUserManagerInt.exists(userId)) {
2531 return 0;
2532 }
2533
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002534 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
Todd Kennedy0eb97382017-10-03 16:57:22 -07002535
2536 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002537 true, // requireFullPermission
2538 false, // checkShell
2539 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002540 "getPermissionFlags");
2541
2542 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2543 if (pkg == null || pkg.mExtras == null) {
2544 return 0;
2545 }
2546 synchronized (mLock) {
2547 if (mSettings.getPermissionLocked(permName) == null) {
2548 return 0;
2549 }
2550 }
2551 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2552 return 0;
2553 }
2554 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2555 PermissionsState permissionsState = ps.getPermissionsState();
2556 return permissionsState.getPermissionFlags(permName, userId);
2557 }
2558
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002559 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2560 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2561 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2562
2563 private void updatePermissions(String packageName, PackageParser.Package pkg,
2564 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2565 PermissionCallback callback) {
2566 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2567 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2568 updatePermissions(
2569 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2570 if (pkg != null && pkg.childPackages != null) {
2571 for (PackageParser.Package childPkg : pkg.childPackages) {
2572 updatePermissions(childPkg.packageName, childPkg,
2573 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2574 }
2575 }
2576 }
2577
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002578 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07002579 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002580 final int flags = UPDATE_PERMISSIONS_ALL |
2581 (sdkUpdated
2582 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2583 : 0);
2584 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2585 }
2586
2587 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2588 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2589 PermissionCallback callback) {
2590 // TODO: Most of the methods exposing BasePermission internals [source package name,
2591 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2592 // have package settings, we should make note of it elsewhere [map between
2593 // source package name and BasePermission] and cycle through that here. Then we
2594 // define a single method on BasePermission that takes a PackageSetting, changing
2595 // package name and a package.
2596 // NOTE: With this approach, we also don't need to tree trees differently than
2597 // normal permissions. Today, we need two separate loops because these BasePermission
2598 // objects are stored separately.
2599 // Make sure there are no dangling permission trees.
2600 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2601
2602 // Make sure all dynamic permissions have been assigned to a package,
2603 // and make sure there are no dangling permissions.
2604 flags = updatePermissions(changingPkgName, changingPkg, flags);
2605
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002606 synchronized (mLock) {
2607 if (mBackgroundPermissions == null) {
2608 // Cache background -> foreground permission mapping.
2609 // Only system declares background permissions, hence mapping does never change.
2610 mBackgroundPermissions = new ArrayMap<>();
2611 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002612 if (bp.perm != null && bp.perm.info != null
2613 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002614 String fgPerm = bp.name;
2615 String bgPerm = bp.perm.info.backgroundPermission;
2616
2617 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2618 if (fgPerms == null) {
2619 fgPerms = new ArrayList<>();
2620 mBackgroundPermissions.put(bgPerm, fgPerms);
2621 }
2622
2623 fgPerms.add(fgPerm);
2624 }
2625 }
2626 }
2627 }
2628
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002629 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002630 // Now update the permissions for all packages, in particular
2631 // replace the granted permissions of the system packages.
2632 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2633 for (PackageParser.Package pkg : allPackages) {
2634 if (pkg != changingPkg) {
2635 // Only replace for packages on requested volume
2636 final String volumeUuid = getVolumeUuidForPackage(pkg);
2637 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2638 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002639 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002640 }
2641 }
2642 }
2643
2644 if (changingPkg != null) {
2645 // Only replace for packages on requested volume
2646 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2647 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2648 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002649 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002650 }
2651 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2652 }
2653
2654 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002655 Set<BasePermission> needsUpdate = null;
2656 synchronized (mLock) {
2657 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2658 while (it.hasNext()) {
2659 final BasePermission bp = it.next();
2660 if (bp.isDynamic()) {
2661 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2662 }
2663 if (bp.getSourcePackageSetting() != null) {
2664 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002665 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002666 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2667 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002668 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002669 it.remove();
2670 }
2671 continue;
2672 }
2673 if (needsUpdate == null) {
2674 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2675 }
2676 needsUpdate.add(bp);
2677 }
2678 }
2679 if (needsUpdate != null) {
2680 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002681 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002682 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2683 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002684 if (sourcePkg != null && sourcePkg.mExtras != null) {
2685 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002686 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002687 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002688 }
2689 continue;
2690 }
2691 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2692 + " from package " + bp.getSourcePackageName());
2693 mSettings.removePermissionLocked(bp.getName());
2694 }
2695 }
2696 }
2697 return flags;
2698 }
2699
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002700 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002701 int flags) {
2702 Set<BasePermission> needsUpdate = null;
2703 synchronized (mLock) {
2704 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2705 while (it.hasNext()) {
2706 final BasePermission bp = it.next();
2707 if (bp.getSourcePackageSetting() != null) {
2708 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002709 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002710 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2711 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002712 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002713 it.remove();
2714 }
2715 continue;
2716 }
2717 if (needsUpdate == null) {
2718 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2719 }
2720 needsUpdate.add(bp);
2721 }
2722 }
2723 if (needsUpdate != null) {
2724 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002725 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002726 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2727 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002728 if (sourcePkg != null && sourcePkg.mExtras != null) {
2729 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002730 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002731 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002732 }
2733 continue;
2734 }
2735 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2736 + " from package " + bp.getSourcePackageName());
2737 mSettings.removePermissionLocked(bp.getName());
2738 }
2739 }
2740 }
2741 return flags;
2742 }
2743
Todd Kennedy0eb97382017-10-03 16:57:22 -07002744 private void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002745 int flagValues, int callingUid, int userId, boolean overridePolicy,
2746 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002747 if (!mUserManagerInt.exists(userId)) {
2748 return;
2749 }
2750
2751 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2752
2753 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002754 true, // requireFullPermission
2755 true, // checkShell
2756 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002757 "updatePermissionFlags");
2758
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002759 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2760 throw new SecurityException("updatePermissionFlags requires "
2761 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2762 }
2763
Todd Kennedy0eb97382017-10-03 16:57:22 -07002764 // Only the system can change these flags and nothing else.
2765 if (callingUid != Process.SYSTEM_UID) {
2766 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2767 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2768 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2769 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2770 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002771 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2772 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2773 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2774 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002775 }
2776
2777 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2778 if (pkg == null || pkg.mExtras == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002779 Log.e(TAG, "Unknown package: " + packageName);
2780 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002781 }
2782 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2783 throw new IllegalArgumentException("Unknown package: " + packageName);
2784 }
2785
2786 final BasePermission bp;
2787 synchronized (mLock) {
2788 bp = mSettings.getPermissionLocked(permName);
2789 }
2790 if (bp == null) {
2791 throw new IllegalArgumentException("Unknown permission: " + permName);
2792 }
2793
2794 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2795 final PermissionsState permissionsState = ps.getPermissionsState();
2796 final boolean hadState =
2797 permissionsState.getRuntimePermissionState(permName, userId) != null;
2798 final boolean permissionUpdated =
2799 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002800 if (permissionUpdated && bp.isRuntime()) {
2801 notifyRuntimePermissionStateChanged(packageName, userId);
2802 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002803 if (permissionUpdated && callback != null) {
2804 // Install and runtime permissions are stored in different places,
2805 // so figure out what permission changed and persist the change.
2806 if (permissionsState.getInstallPermissionState(permName) != null) {
2807 callback.onInstallPermissionUpdated();
2808 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2809 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002810 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002811 }
2812 }
2813 }
2814
2815 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2816 int userId, Collection<Package> packages, PermissionCallback callback) {
2817 if (!mUserManagerInt.exists(userId)) {
2818 return false;
2819 }
2820
2821 enforceGrantRevokeRuntimePermissionPermissions(
2822 "updatePermissionFlagsForAllApps");
2823 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002824 true, // requireFullPermission
2825 true, // checkShell
2826 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002827 "updatePermissionFlagsForAllApps");
2828
2829 // Only the system can change system fixed flags.
2830 if (callingUid != Process.SYSTEM_UID) {
2831 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2832 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2833 }
2834
2835 boolean changed = false;
2836 for (PackageParser.Package pkg : packages) {
2837 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2838 if (ps == null) {
2839 continue;
2840 }
2841 PermissionsState permissionsState = ps.getPermissionsState();
2842 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2843 userId, flagMask, flagValues);
2844 }
2845 return changed;
2846 }
2847
2848 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2849 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2850 != PackageManager.PERMISSION_GRANTED
2851 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2852 != PackageManager.PERMISSION_GRANTED) {
2853 throw new SecurityException(message + " requires "
2854 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2855 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2856 }
2857 }
2858
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002859 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2860 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2861 != PackageManager.PERMISSION_GRANTED
2862 && 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 + " or "
2869 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2870 }
2871 }
2872
Todd Kennedy0eb97382017-10-03 16:57:22 -07002873 /**
2874 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2875 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2876 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2877 * @param message the message to log on security exception
2878 */
2879 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002880 boolean requireFullPermission, boolean checkShell,
2881 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002882 if (userId < 0) {
2883 throw new IllegalArgumentException("Invalid userId " + userId);
2884 }
2885 if (checkShell) {
2886 PackageManagerServiceUtils.enforceShellRestriction(
2887 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2888 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002889 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002890 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002891 if (requireFullPermission) {
2892 mContext.enforceCallingOrSelfPermission(
2893 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2894 } else {
2895 try {
2896 mContext.enforceCallingOrSelfPermission(
2897 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2898 } catch (SecurityException se) {
2899 mContext.enforceCallingOrSelfPermission(
2900 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2901 }
2902 }
2903 }
2904 }
2905
Andreas Gampea71bee82018-07-20 12:55:36 -07002906 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002907 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2908 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002909 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002910 size += tree.calculateFootprint(perm);
2911 }
2912 return size;
2913 }
2914
Andreas Gampea71bee82018-07-20 12:55:36 -07002915 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002916 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2917 // We calculate the max size of permissions defined by this uid and throw
2918 // if that plus the size of 'info' would exceed our stated maximum.
2919 if (tree.getUid() != Process.SYSTEM_UID) {
2920 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2921 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2922 throw new SecurityException("Permission tree size cap exceeded");
2923 }
2924 }
2925 }
2926
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002927 private void systemReady() {
2928 mSystemReady = true;
2929 if (mPrivappPermissionsViolations != null) {
2930 throw new IllegalStateException("Signature|privileged permissions not in "
2931 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2932 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002933
2934 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov0b41c892019-07-26 17:45:56 -07002935 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002936 }
2937
2938 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2939 if (pkg == null) {
2940 return StorageManager.UUID_PRIVATE_INTERNAL;
2941 }
2942 if (pkg.isExternal()) {
2943 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2944 return StorageManager.UUID_PRIMARY_PHYSICAL;
2945 } else {
2946 return pkg.volumeUuid;
2947 }
2948 } else {
2949 return StorageManager.UUID_PRIVATE_INTERNAL;
2950 }
2951 }
2952
Todd Kennedyc8423932017-10-05 08:58:36 -07002953 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2954 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2955 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2956 return true;
2957 }
2958 }
2959 return false;
2960 }
2961
Todd Kennedy0eb97382017-10-03 16:57:22 -07002962 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002963 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002964 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002965 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002966 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002967 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002968 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002969 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2970 final LogMaker log = new LogMaker(action);
2971 log.setPackageName(packageName);
2972 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002973
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002974 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002975 }
2976
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002977 /**
2978 * Get the mapping of background permissions to their foreground permissions.
2979 *
2980 * <p>Only initialized in the system server.
2981 *
2982 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2983 */
2984 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2985 return mBackgroundPermissions;
2986 }
2987
Philip P. Moltmann48456672019-01-20 13:14:03 -08002988 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002989 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002990 public void systemReady() {
2991 PermissionManagerService.this.systemReady();
2992 }
2993 @Override
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07002994 public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002995 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2996 }
2997 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002998 public void revokeRuntimePermissionsIfGroupChanged(
2999 @NonNull PackageParser.Package newPackage,
3000 @NonNull PackageParser.Package oldPackage,
3001 @NonNull ArrayList<String> allPackageNames,
3002 @NonNull PermissionCallback permissionCallback) {
3003 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
3004 oldPackage, allPackageNames, permissionCallback);
3005 }
3006 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003007 public void addAllPermissions(Package pkg, boolean chatty) {
3008 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003009 }
3010 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003011 public void addAllPermissionGroups(Package pkg, boolean chatty) {
3012 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
3013 }
3014 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00003015 public void removeAllPermissions(Package pkg, boolean chatty) {
3016 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07003017 }
3018 @Override
3019 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003020 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07003021 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
3022 }
3023 @Override
3024 public void removeDynamicPermission(String permName, int callingUid,
3025 PermissionCallback callback) {
3026 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003027 }
3028 @Override
3029 public void grantRuntimePermission(String permName, String packageName,
3030 boolean overridePolicy, int callingUid, int userId,
3031 PermissionCallback callback) {
3032 PermissionManagerService.this.grantRuntimePermission(
3033 permName, packageName, overridePolicy, callingUid, userId, callback);
3034 }
3035 @Override
3036 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3037 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3038 PermissionManagerService.this.grantRequestedRuntimePermissions(
3039 pkg, userIds, grantedPermissions, callingUid, callback);
3040 }
3041 @Override
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003042 public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
3043 @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
3044 return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
3045 whitelistFlags, userId);
3046 }
3047 @Override
3048 public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
3049 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
3050 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
3051 @NonNull PermissionCallback callback) {
3052 PermissionManagerService.this.setWhitelistedRestrictedPermissions(
3053 pkg, userIds, permissions, callingUid, whitelistFlags, callback);
3054 }
3055 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003056 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
3057 int callingUid, PermissionCallback callback) {
3058 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
3059 pkg, callingUid, callback);
3060 }
3061 @Override
3062 public void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003063 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003064 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003065 overridePolicy, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003066 }
3067 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003068 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
3069 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3070 PermissionManagerService.this.updatePermissions(
3071 packageName, pkg, replaceGrant, allPackages, callback);
3072 }
3073 @Override
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08003074 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003075 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003076 PermissionManagerService.this.updateAllPermissions(
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003077 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003078 }
3079 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003080 public String[] getAppOpPermissionPackages(String permName) {
3081 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
3082 }
3083 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003084 public int getPermissionFlags(String permName, String packageName, int callingUid,
3085 int userId) {
3086 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
3087 callingUid, userId);
3088 }
3089 @Override
3090 public void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003091 int flagValues, int callingUid, int userId, boolean overridePolicy,
3092 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003093 PermissionManagerService.this.updatePermissionFlags(
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003094 permName, packageName, flagMask, flagValues, callingUid, userId,
3095 overridePolicy, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003096 }
3097 @Override
3098 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
3099 int userId, Collection<Package> packages, PermissionCallback callback) {
3100 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
3101 flagMask, flagValues, callingUid, userId, packages, callback);
3102 }
3103 @Override
3104 public void enforceCrossUserPermission(int callingUid, int userId,
3105 boolean requireFullPermission, boolean checkShell, String message) {
3106 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07003107 requireFullPermission, checkShell, false, message);
3108 }
3109 @Override
3110 public void enforceCrossUserPermission(int callingUid, int userId,
3111 boolean requireFullPermission, boolean checkShell,
3112 boolean requirePermissionWhenSameUser, String message) {
3113 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3114 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003115 }
3116 @Override
3117 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3118 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
3119 }
3120 @Override
3121 public int checkPermission(String permName, String packageName, int callingUid,
3122 int userId) {
3123 return PermissionManagerService.this.checkPermission(
3124 permName, packageName, callingUid, userId);
3125 }
3126 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07003127 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
3128 int callingUid) {
3129 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07003130 }
3131 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003132 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
3133 int callingUid) {
3134 return PermissionManagerService.this.getPermissionGroupInfo(
3135 groupName, flags, callingUid);
3136 }
3137 @Override
3138 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
3139 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
3140 }
3141 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003142 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
3143 int callingUid) {
3144 return PermissionManagerService.this.getPermissionInfo(
3145 permName, packageName, flags, callingUid);
3146 }
3147 @Override
3148 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
3149 int callingUid) {
3150 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
3151 }
3152 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003153 public PermissionSettings getPermissionSettings() {
3154 return mSettings;
3155 }
3156 @Override
3157 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
3158 return mDefaultPermissionGrantPolicy;
3159 }
3160 @Override
3161 public BasePermission getPermissionTEMP(String permName) {
3162 synchronized (PermissionManagerService.this.mLock) {
3163 return mSettings.getPermissionLocked(permName);
3164 }
3165 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08003166
3167 @Override
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07003168 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
3169 @PermissionInfo.Protection int protectionLevel) {
3170 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
3171
3172 synchronized (PermissionManagerService.this.mLock) {
3173 int numTotalPermissions = mSettings.mPermissions.size();
3174
3175 for (int i = 0; i < numTotalPermissions; i++) {
3176 BasePermission bp = mSettings.mPermissions.valueAt(i);
3177
3178 if (bp.perm != null && bp.perm.info != null
3179 && bp.protectionLevel == protectionLevel) {
3180 matchingPermissions.add(bp.perm.info);
3181 }
3182 }
3183 }
3184
3185 return matchingPermissions;
3186 }
3187
3188 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08003189 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
3190 return PermissionManagerService.this.backupRuntimePermissions(user);
3191 }
3192
3193 @Override
3194 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
3195 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
3196 }
3197
3198 @Override
3199 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
3200 @NonNull UserHandle user) {
3201 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
3202 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003203
3204 @Override
3205 public void addOnRuntimePermissionStateChangedListener(
3206 OnRuntimePermissionStateChangedListener listener) {
3207 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
3208 listener);
3209 }
3210
3211 @Override
3212 public void removeOnRuntimePermissionStateChangedListener(
3213 OnRuntimePermissionStateChangedListener listener) {
3214 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
3215 listener);
3216 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003217 }
3218}