blob: f7d8e0e2783179dcbe13e5c99d859d33b4da16f0 [file] [log] [blame]
Todd Kennedy0eb97382017-10-03 16:57:22 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm.permission;
18
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070021import static android.app.AppOpsManager.MODE_ALLOWED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070022import static android.app.AppOpsManager.MODE_ERRORED;
23import static android.app.AppOpsManager.MODE_FOREGROUND;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070024import static android.app.AppOpsManager.OP_NONE;
25import static android.app.AppOpsManager.permissionToOp;
26import static android.app.AppOpsManager.permissionToOpCode;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070027import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
28import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070029import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann48456672019-01-20 13:14:03 -080030import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Philip P. Moltmann76597692019-03-02 13:18:41 -080035import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Hongwei Wangf391b552018-04-06 13:52:46 -070036import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070037import static android.os.UserHandle.getAppId;
38import static android.os.UserHandle.getUid;
Hongwei Wangf391b552018-04-06 13:52:46 -070039
Todd Kennedyc29b11a2017-10-23 15:55:59 -070040import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
41import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
42import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
43import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
44import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080045import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
46
47import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070048
49import android.Manifest;
50import android.annotation.NonNull;
51import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070052import android.annotation.UserIdInt;
53import android.app.AppOpsManager;
54import android.app.AppOpsManagerInternal;
Todd Kennedy0eb97382017-10-03 16:57:22 -070055import android.content.Context;
56import android.content.pm.PackageManager;
57import android.content.pm.PackageManagerInternal;
58import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070059import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070060import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070061import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070062import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070063import android.os.Binder;
64import android.os.Build;
65import android.os.Handler;
66import android.os.HandlerThread;
67import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070068import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070069import android.os.UserHandle;
70import android.os.UserManager;
71import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070072import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070073import android.os.storage.StorageManagerInternal;
Philip P. Moltmann48456672019-01-20 13:14:03 -080074import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070075import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080076import android.permission.PermissionManagerInternal;
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -080077import android.provider.Settings;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070078import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070079import android.util.ArrayMap;
80import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070081import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070082import android.util.Log;
83import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070084import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -080085import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070086
Todd Kennedyc29b11a2017-10-23 15:55:59 -070087import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070088import com.android.internal.logging.MetricsLogger;
89import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070090import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070091import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070092import com.android.server.LocalServices;
93import com.android.server.ServiceThread;
94import com.android.server.SystemConfig;
95import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import com.android.server.pm.PackageManagerServiceUtils;
97import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070098import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070099import com.android.server.pm.UserManagerService;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800100import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
101import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700102import com.android.server.pm.permission.PermissionsState.PermissionState;
103
104import libcore.util.EmptyArray;
105
106import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700107import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700108import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700109import java.util.Iterator;
110import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700111import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700112import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700113import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800114import java.util.concurrent.CompletableFuture;
115import java.util.concurrent.ExecutionException;
116import java.util.concurrent.TimeUnit;
117import java.util.concurrent.TimeoutException;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700118
119/**
120 * Manages all permissions and handles permissions related tasks.
121 */
122public class PermissionManagerService {
123 private static final String TAG = "PackageManager";
124
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700125 /** Permission grant: not grant the permission. */
126 private static final int GRANT_DENIED = 1;
127 /** Permission grant: grant the permission as an install permission. */
128 private static final int GRANT_INSTALL = 2;
129 /** Permission grant: grant the permission as a runtime one. */
130 private static final int GRANT_RUNTIME = 3;
131 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
132 private static final int GRANT_UPGRADE = 4;
133
Philip P. Moltmann48456672019-01-20 13:14:03 -0800134 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
135
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700136 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
137 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
138 /** Empty array to avoid allocations */
139 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700140
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800141 /**
142 * When these flags are set, the system should not automatically modify the permission grant
143 * state.
144 */
145 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
146 | FLAG_PERMISSION_POLICY_FIXED
147 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
148
149 /** Permission flags set by the user */
150 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
151 | FLAG_PERMISSION_USER_FIXED;
152
Hongwei Wangf391b552018-04-06 13:52:46 -0700153 /** If the permission of the value is granted, so is the key */
154 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
155
156 static {
157 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
158 Manifest.permission.ACCESS_FINE_LOCATION);
159 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
160 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
161 }
162
Todd Kennedy0eb97382017-10-03 16:57:22 -0700163 /** Lock to protect internal data access */
164 private final Object mLock;
165
166 /** Internal connection to the package manager */
167 private final PackageManagerInternal mPackageManagerInt;
168
169 /** Internal connection to the user manager */
170 private final UserManagerInternal mUserManagerInt;
171
Philip P. Moltmann48456672019-01-20 13:14:03 -0800172 /** Permission controller: User space permission management */
173 private PermissionControllerManager mPermissionControllerManager;
174
Todd Kennedy0eb97382017-10-03 16:57:22 -0700175 /** Default permission policy to provide proper behaviour out-of-the-box */
176 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
177
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700178 /**
179 * Built-in permissions. Read from system configuration files. Mapping is from
180 * UID to permission name.
181 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700182 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700183
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700184 /** Built-in group IDs given to all packages. Read from system configuration files. */
185 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700186
187 private final HandlerThread mHandlerThread;
188 private final Handler mHandler;
189 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700190 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700191
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700192 /** Internal storage for permissions and related settings */
193 @GuardedBy("mLock")
194 private final PermissionSettings mSettings;
195
196 @GuardedBy("mLock")
197 private ArraySet<String> mPrivappPermissionsViolations;
198
199 @GuardedBy("mLock")
200 private boolean mSystemReady;
201
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700202 /**
203 * For each foreground/background permission the mapping:
204 * Background permission -> foreground permissions
205 */
206 @GuardedBy("mLock")
207 private ArrayMap<String, List<String>> mBackgroundPermissions;
208
Philip P. Moltmann48456672019-01-20 13:14:03 -0800209 /**
210 * A permission backup might contain apps that are not installed. In this case we delay the
211 * restoration until the app is installed.
212 *
213 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
214 * there is <u>no more</u> delayed backup left.
215 */
216 @GuardedBy("mLock")
217 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
218
Todd Kennedy0eb97382017-10-03 16:57:22 -0700219 PermissionManagerService(Context context,
220 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
221 @NonNull Object externalLock) {
222 mContext = context;
223 mLock = externalLock;
224 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
225 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700226 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700227
228 mHandlerThread = new ServiceThread(TAG,
229 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
230 mHandlerThread.start();
231 mHandler = new Handler(mHandlerThread.getLooper());
232 Watchdog.getInstance().addThread(mHandler);
233
234 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
235 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700236 SystemConfig systemConfig = SystemConfig.getInstance();
237 mSystemPermissions = systemConfig.getSystemPermissions();
238 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700239
240 // propagate permission configuration
241 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
242 SystemConfig.getInstance().getPermissions();
243 synchronized (mLock) {
244 for (int i=0; i<permConfig.size(); i++) {
245 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
246 BasePermission bp = mSettings.getPermissionLocked(perm.name);
247 if (bp == null) {
248 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
249 mSettings.putPermissionLocked(perm.name, bp);
250 }
251 if (perm.gids != null) {
252 bp.setGids(perm.gids, perm.perUser);
253 }
254 }
255 }
256
Philip P. Moltmann48456672019-01-20 13:14:03 -0800257 PermissionManagerServiceInternalImpl localService =
258 new PermissionManagerServiceInternalImpl();
259 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
260 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700261 }
262
263 /**
264 * Creates and returns an initialized, internal service for use by other components.
265 * <p>
266 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800267 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700268 * <p>
269 * NOTE: The external lock is temporary and should be removed. This needs to be a
270 * lock created by the permission manager itself.
271 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800272 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700273 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
274 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800275 final PermissionManagerServiceInternal permMgrInt =
276 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700277 if (permMgrInt != null) {
278 return permMgrInt;
279 }
280 new PermissionManagerService(context, defaultGrantCallback, externalLock);
Philip P. Moltmann48456672019-01-20 13:14:03 -0800281 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700282 }
283
284 @Nullable BasePermission getPermission(String permName) {
285 synchronized (mLock) {
286 return mSettings.getPermissionLocked(permName);
287 }
288 }
289
290 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
291 if (!mUserManagerInt.exists(userId)) {
292 return PackageManager.PERMISSION_DENIED;
293 }
294
Patrick Baumann97b9b532018-04-11 14:51:30 +0000295 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
296 if (pkg != null && pkg.mExtras != null) {
297 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700298 return PackageManager.PERMISSION_DENIED;
299 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000300 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700301 final boolean instantApp = ps.getInstantApp(userId);
302 final PermissionsState permissionsState = ps.getPermissionsState();
303 if (permissionsState.hasPermission(permName, userId)) {
304 if (instantApp) {
305 synchronized (mLock) {
306 BasePermission bp = mSettings.getPermissionLocked(permName);
307 if (bp != null && bp.isInstant()) {
308 return PackageManager.PERMISSION_GRANTED;
309 }
310 }
311 } else {
312 return PackageManager.PERMISSION_GRANTED;
313 }
314 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700315 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700316 return PackageManager.PERMISSION_GRANTED;
317 }
318 }
319
320 return PackageManager.PERMISSION_DENIED;
321 }
322
Todd Kennedy3c714492017-10-27 09:12:50 -0700323 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
324 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700325 final int callingUserId = UserHandle.getUserId(callingUid);
326 final boolean isCallerInstantApp =
327 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
328 final boolean isUidInstantApp =
329 mPackageManagerInt.getInstantAppPackageName(uid) != null;
330 final int userId = UserHandle.getUserId(uid);
331 if (!mUserManagerInt.exists(userId)) {
332 return PackageManager.PERMISSION_DENIED;
333 }
334
Todd Kennedy3c714492017-10-27 09:12:50 -0700335 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700336 if (pkg.mSharedUserId != null) {
337 if (isCallerInstantApp) {
338 return PackageManager.PERMISSION_DENIED;
339 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700340 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
341 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700342 }
343 final PermissionsState permissionsState =
344 ((PackageSetting) pkg.mExtras).getPermissionsState();
345 if (permissionsState.hasPermission(permName, userId)) {
346 if (isUidInstantApp) {
347 if (mSettings.isPermissionInstant(permName)) {
348 return PackageManager.PERMISSION_GRANTED;
349 }
350 } else {
351 return PackageManager.PERMISSION_GRANTED;
352 }
353 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700354 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700355 return PackageManager.PERMISSION_GRANTED;
356 }
357 } else {
358 ArraySet<String> perms = mSystemPermissions.get(uid);
359 if (perms != null) {
360 if (perms.contains(permName)) {
361 return PackageManager.PERMISSION_GRANTED;
362 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700363 if (FULLER_PERMISSION_MAP.containsKey(permName)
364 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700365 return PackageManager.PERMISSION_GRANTED;
366 }
367 }
368 }
369 return PackageManager.PERMISSION_DENIED;
370 }
371
Hongwei Wangf391b552018-04-06 13:52:46 -0700372 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -0800373 * Get the state of the runtime permissions as xml file.
374 *
375 * <p>Can not be called on main thread.
376 *
377 * @param user The user the data should be extracted for
378 *
379 * @return The state as a xml file
380 */
381 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
382 CompletableFuture<byte[]> backup = new CompletableFuture<>();
383 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
384 backup::complete);
385
386 try {
387 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
388 } catch (InterruptedException | ExecutionException | TimeoutException e) {
389 Slog.e(TAG, "Cannot create permission backup for " + user, e);
390 return null;
391 }
392 }
393
394 /**
395 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
396 *
397 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
398 * applied via {@link #restoreDelayedRuntimePermissions}.
399 *
400 * @param backup The state as an xml file
401 * @param user The user the data should be restored for
402 */
403 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
404 synchronized (mLock) {
405 mHasNoDelayedPermBackup.delete(user.getIdentifier());
406 mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
407 }
408 }
409
410 /**
411 * Try to apply permission backup that was previously not applied.
412 *
413 * <p>Can not be called on main thread.
414 *
415 * @param packageName The package that is newly installed
416 * @param user The user the package is installed for
417 *
418 * @see #restoreRuntimePermissions
419 */
420 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
421 @NonNull UserHandle user) {
422 synchronized (mLock) {
423 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
424 return;
425 }
426
427 mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
428 mContext.getMainExecutor(), (hasMoreBackup) -> {
429 if (hasMoreBackup) {
430 return;
431 }
432
433 synchronized (mLock) {
434 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
435 }
436 });
437 }
438 }
439
440 /**
Hongwei Wangf391b552018-04-06 13:52:46 -0700441 * Returns {@code true} if the permission can be implied from another granted permission.
442 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
443 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
444 * it access to any implied permissions.
445 */
446 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
447 String permName, int userId) {
448 return FULLER_PERMISSION_MAP.containsKey(permName)
449 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
450 }
451
Todd Kennedy460f28c2017-10-06 13:46:22 -0700452 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
453 int callingUid) {
454 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
455 return null;
456 }
457 synchronized (mLock) {
458 return PackageParser.generatePermissionGroupInfo(
459 mSettings.mPermissionGroups.get(groupName), flags);
460 }
461 }
462
463 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
464 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
465 return null;
466 }
467 synchronized (mLock) {
468 final int N = mSettings.mPermissionGroups.size();
469 final ArrayList<PermissionGroupInfo> out
470 = new ArrayList<PermissionGroupInfo>(N);
471 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
472 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
473 }
474 return out;
475 }
476 }
477
478 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700479 int callingUid) {
480 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
481 return null;
482 }
483 // reader
484 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700485 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700486 if (bp == null) {
487 return null;
488 }
489 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
490 bp.getProtectionLevel(), packageName, callingUid);
491 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
492 }
493 }
494
495 private List<PermissionInfo> getPermissionInfoByGroup(
496 String groupName, int flags, int callingUid) {
497 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
498 return null;
499 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700500 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700501 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
502 return null;
503 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700504 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700505 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700506 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
507 if (pi != null) {
508 out.add(pi);
509 }
510 }
511 return out;
512 }
513 }
514
515 private int adjustPermissionProtectionFlagsLocked(
516 int protectionLevel, String packageName, int uid) {
517 // Signature permission flags area always reported
518 final int protectionLevelMasked = protectionLevel
519 & (PermissionInfo.PROTECTION_NORMAL
520 | PermissionInfo.PROTECTION_DANGEROUS
521 | PermissionInfo.PROTECTION_SIGNATURE);
522 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
523 return protectionLevel;
524 }
525 // System sees all flags.
526 final int appId = UserHandle.getAppId(uid);
527 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
528 || appId == Process.SHELL_UID) {
529 return protectionLevel;
530 }
531 // Normalize package name to handle renamed packages and static libs
532 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
533 if (pkg == null) {
534 return protectionLevel;
535 }
536 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
537 return protectionLevelMasked;
538 }
539 // Apps that target O see flags for all protection levels.
540 final PackageSetting ps = (PackageSetting) pkg.mExtras;
541 if (ps == null) {
542 return protectionLevel;
543 }
544 if (ps.getAppId() != appId) {
545 return protectionLevel;
546 }
547 return protectionLevel;
548 }
549
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700550 /**
551 * We might auto-grant permissions if any permission of the group is already granted. Hence if
552 * the group of a granted permission changes we need to revoke it to avoid having permissions of
553 * the new group auto-granted.
554 *
555 * @param newPackage The new package that was installed
556 * @param oldPackage The old package that was updated
557 * @param allPackageNames All package names
558 * @param permissionCallback Callback for permission changed
559 */
560 private void revokeRuntimePermissionsIfGroupChanged(
561 @NonNull PackageParser.Package newPackage,
562 @NonNull PackageParser.Package oldPackage,
563 @NonNull ArrayList<String> allPackageNames,
564 @NonNull PermissionCallback permissionCallback) {
565 final int numOldPackagePermissions = oldPackage.permissions.size();
566 final ArrayMap<String, String> oldPermissionNameToGroupName
567 = new ArrayMap<>(numOldPackagePermissions);
568
569 for (int i = 0; i < numOldPackagePermissions; i++) {
570 final PackageParser.Permission permission = oldPackage.permissions.get(i);
571
572 if (permission.group != null) {
573 oldPermissionNameToGroupName.put(permission.info.name,
574 permission.group.info.name);
575 }
576 }
577
578 final int numNewPackagePermissions = newPackage.permissions.size();
579 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
580 newPermissionNum++) {
581 final PackageParser.Permission newPermission =
582 newPackage.permissions.get(newPermissionNum);
583 final int newProtection = newPermission.info.getProtection();
584
585 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
586 final String permissionName = newPermission.info.name;
587 final String newPermissionGroupName =
588 newPermission.group == null ? null : newPermission.group.info.name;
589 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
590 permissionName);
591
592 if (newPermissionGroupName != null
593 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
594 final int[] userIds = mUserManagerInt.getUserIds();
595 final int numUserIds = userIds.length;
596 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
597 final int userId = userIds[userIdNum];
598
599 final int numPackages = allPackageNames.size();
600 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
601 final String packageName = allPackageNames.get(packageNum);
602
603 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
604 userId) == PackageManager.PERMISSION_GRANTED) {
605 EventLog.writeEvent(0x534e4554, "72710897",
606 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900607 "Revoking permission " + permissionName +
608 " from package " + packageName +
609 " as the group changed from " + oldPermissionGroupName +
610 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700611
612 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000613 revokeRuntimePermission(permissionName, packageName, false,
614 Process.SYSTEM_UID, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700615 } catch (IllegalArgumentException e) {
616 Slog.e(TAG, "Could not revoke " + permissionName + " from "
617 + packageName, e);
618 }
619 }
620 }
621 }
622 }
623 }
624 }
625 }
626
Todd Kennedyc8423932017-10-05 08:58:36 -0700627 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
628 final int N = pkg.permissions.size();
629 for (int i=0; i<N; i++) {
630 PackageParser.Permission p = pkg.permissions.get(i);
631
632 // Assume by default that we did not install this permission into the system.
633 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
634
Todd Kennedyc8423932017-10-05 08:58:36 -0700635 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700636 // Now that permission groups have a special meaning, we ignore permission
637 // groups for legacy apps to prevent unexpected behavior. In particular,
638 // permissions for one app being granted to someone just because they happen
639 // to be in a group defined by another app (before this had no implications).
640 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
641 p.group = mSettings.mPermissionGroups.get(p.info.group);
642 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700643 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700644 && p.info.group != null && p.group == null) {
645 Slog.i(TAG, "Permission " + p.info.name + " from package "
646 + p.info.packageName + " in an unknown group " + p.info.group);
647 }
648 }
649
Todd Kennedyc8423932017-10-05 08:58:36 -0700650 if (p.tree) {
651 final BasePermission bp = BasePermission.createOrUpdate(
652 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
653 mSettings.getAllPermissionTreesLocked(), chatty);
654 mSettings.putPermissionTreeLocked(p.info.name, bp);
655 } else {
656 final BasePermission bp = BasePermission.createOrUpdate(
657 mSettings.getPermissionLocked(p.info.name),
658 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
659 mSettings.putPermissionLocked(p.info.name, bp);
660 }
661 }
662 }
663 }
664
Todd Kennedy460f28c2017-10-06 13:46:22 -0700665 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
666 final int N = pkg.permissionGroups.size();
667 StringBuilder r = null;
668 for (int i=0; i<N; i++) {
669 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
670 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
671 final String curPackageName = (cur == null) ? null : cur.info.packageName;
672 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
673 if (cur == null || isPackageUpdate) {
674 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700675 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700676 if (r == null) {
677 r = new StringBuilder(256);
678 } else {
679 r.append(' ');
680 }
681 if (isPackageUpdate) {
682 r.append("UPD:");
683 }
684 r.append(pg.info.name);
685 }
686 } else {
687 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
688 + pg.info.packageName + " ignored: original from "
689 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700690 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700691 if (r == null) {
692 r = new StringBuilder(256);
693 } else {
694 r.append(' ');
695 }
696 r.append("DUP:");
697 r.append(pg.info.name);
698 }
699 }
700 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700701 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700702 Log.d(TAG, " Permission Groups: " + r);
703 }
704
705 }
706
Hongming Jinae750fb2018-09-27 23:00:20 +0000707 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700708 synchronized (mLock) {
709 int N = pkg.permissions.size();
710 StringBuilder r = null;
711 for (int i=0; i<N; i++) {
712 PackageParser.Permission p = pkg.permissions.get(i);
713 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
714 if (bp == null) {
715 bp = mSettings.mPermissionTrees.get(p.info.name);
716 }
717 if (bp != null && bp.isPermission(p)) {
718 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700719 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700720 if (r == null) {
721 r = new StringBuilder(256);
722 } else {
723 r.append(' ');
724 }
725 r.append(p.info.name);
726 }
727 }
728 if (p.isAppOp()) {
729 ArraySet<String> appOpPkgs =
730 mSettings.mAppOpPermissionPackages.get(p.info.name);
731 if (appOpPkgs != null) {
732 appOpPkgs.remove(pkg.packageName);
733 }
734 }
735 }
736 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700737 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700738 }
739
740 N = pkg.requestedPermissions.size();
741 r = null;
742 for (int i=0; i<N; i++) {
743 String perm = pkg.requestedPermissions.get(i);
744 if (mSettings.isPermissionAppOp(perm)) {
745 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
746 if (appOpPkgs != null) {
747 appOpPkgs.remove(pkg.packageName);
748 if (appOpPkgs.isEmpty()) {
749 mSettings.mAppOpPermissionPackages.remove(perm);
750 }
751 }
752 }
753 }
754 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700755 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700756 }
757 }
758 }
759
760 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700761 PermissionInfo info, int callingUid, PermissionCallback callback) {
762 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
763 throw new SecurityException("Instant apps can't add permissions");
764 }
765 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
766 throw new SecurityException("Label must be specified in permission");
767 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700768 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700769 final boolean added;
770 final boolean changed;
771 synchronized (mLock) {
772 BasePermission bp = mSettings.getPermissionLocked(info.name);
773 added = bp == null;
774 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
775 if (added) {
776 enforcePermissionCapLocked(info, tree);
777 bp = new BasePermission(info.name, tree.getSourcePackageName(),
778 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700779 } else if (!bp.isDynamic()) {
780 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700781 + info.name);
782 }
783 changed = bp.addToTree(fixedLevel, info, tree);
784 if (added) {
785 mSettings.putPermissionLocked(info.name, bp);
786 }
787 }
788 if (changed && callback != null) {
789 callback.onPermissionChanged();
790 }
791 return added;
792 }
793
Todd Kennedyc8423932017-10-05 08:58:36 -0700794 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700795 String permName, int callingUid, PermissionCallback callback) {
796 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
797 throw new SecurityException("Instant applications don't have access to this method");
798 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700799 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700800 synchronized (mLock) {
801 final BasePermission bp = mSettings.getPermissionLocked(permName);
802 if (bp == null) {
803 return;
804 }
805 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600806 // TODO: switch this back to SecurityException
807 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700808 + permName);
809 }
810 mSettings.removePermissionLocked(permName);
811 if (callback != null) {
812 callback.onPermissionRemoved();
813 }
814 }
815 }
816
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700817 /**
818 * Restore the permission state for a package.
819 *
820 * <ul>
821 * <li>During boot the state gets restored from the disk</li>
822 * <li>During app update the state gets restored from the last version of the app</li>
823 * </ul>
824 *
825 * <p>This restores the permission state for all users.
826 *
827 * @param pkg the package the permissions belong to
828 * @param replace if the package is getting replaced (this might change the requested
829 * permissions of this package)
830 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
831 * @param callback Result call back
832 */
833 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
834 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700835 // IMPORTANT: There are two types of permissions: install and runtime.
836 // Install time permissions are granted when the app is installed to
837 // all device users and users added in the future. Runtime permissions
838 // are granted at runtime explicitly to specific users. Normal and signature
839 // protected permissions are install time permissions. Dangerous permissions
840 // are install permissions if the app's target SDK is Lollipop MR1 or older,
841 // otherwise they are runtime permissions. This function does not manage
842 // runtime permissions except for the case an app targeting Lollipop MR1
843 // being upgraded to target a newer SDK, in which case dangerous permissions
844 // are transformed from install time to runtime ones.
845
846 final PackageSetting ps = (PackageSetting) pkg.mExtras;
847 if (ps == null) {
848 return;
849 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700850
851 final PermissionsState permissionsState = ps.getPermissionsState();
852 PermissionsState origPermissions = permissionsState;
853
854 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
855
856 boolean runtimePermissionsRevoked = false;
857 int[] updatedUserIds = EMPTY_INT_ARRAY;
858
859 boolean changedInstallPermission = false;
860
861 if (replace) {
862 ps.setInstallPermissionsFixed(false);
863 if (!ps.isSharedUser()) {
864 origPermissions = new PermissionsState(permissionsState);
865 permissionsState.reset();
866 } else {
867 // We need to know only about runtime permission changes since the
868 // calling code always writes the install permissions state but
869 // the runtime ones are written only if changed. The only cases of
870 // changed runtime permissions here are promotion of an install to
871 // runtime and revocation of a runtime from a shared user.
872 synchronized (mLock) {
873 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
874 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
875 if (!ArrayUtils.isEmpty(updatedUserIds)) {
876 runtimePermissionsRevoked = true;
877 }
878 }
879 }
880 }
881
882 permissionsState.setGlobalGids(mGlobalGids);
883
884 synchronized (mLock) {
885 final int N = pkg.requestedPermissions.size();
886 for (int i = 0; i < N; i++) {
887 final String permName = pkg.requestedPermissions.get(i);
888 final BasePermission bp = mSettings.getPermissionLocked(permName);
889 final boolean appSupportsRuntimePermissions =
890 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
891
892 if (DEBUG_INSTALL) {
893 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
894 }
895
896 if (bp == null || bp.getSourcePackageSetting() == null) {
897 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
898 if (DEBUG_PERMISSIONS) {
899 Slog.i(TAG, "Unknown permission " + permName
900 + " in package " + pkg.packageName);
901 }
902 }
903 continue;
904 }
905
906 // Limit ephemeral apps to ephemeral allowed permissions.
907 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
908 if (DEBUG_PERMISSIONS) {
909 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
910 + " for package " + pkg.packageName);
911 }
912 continue;
913 }
914
915 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
916 if (DEBUG_PERMISSIONS) {
917 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
918 + " for package " + pkg.packageName);
919 }
920 continue;
921 }
922
923 final String perm = bp.getName();
924 boolean allowedSig = false;
925 int grant = GRANT_DENIED;
926
927 // Keep track of app op permissions.
928 if (bp.isAppOp()) {
929 mSettings.addAppOpPackage(perm, pkg.packageName);
930 }
931
932 if (bp.isNormal()) {
933 // For all apps normal permissions are install time ones.
934 grant = GRANT_INSTALL;
935 } else if (bp.isRuntime()) {
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700936 if (origPermissions.hasInstallPermission(bp.getName())) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800937 // Before Q we represented some runtime permissions as install permissions,
938 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700939 grant = GRANT_UPGRADE;
940 } else {
941 // For modern apps keep runtime permissions unchanged.
942 grant = GRANT_RUNTIME;
943 }
944 } else if (bp.isSignature()) {
945 // For all apps signature permissions are install time ones.
946 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
947 if (allowedSig) {
948 grant = GRANT_INSTALL;
949 }
950 }
951
952 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700953 Slog.i(TAG, "Considering granting permission " + perm + " to package "
954 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700955 }
956
957 if (grant != GRANT_DENIED) {
958 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
959 // If this is an existing, non-system package, then
960 // we can't add any new permissions to it.
961 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
962 // Except... if this is a permission that was added
963 // to the platform (note: need to only do this when
964 // updating the platform).
965 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
966 grant = GRANT_DENIED;
967 }
968 }
969 }
970
971 switch (grant) {
972 case GRANT_INSTALL: {
973 // Revoke this as runtime permission to handle the case of
974 // a runtime permission being downgraded to an install one.
975 // Also in permission review mode we keep dangerous permissions
976 // for legacy apps
977 for (int userId : UserManagerService.getInstance().getUserIds()) {
978 if (origPermissions.getRuntimePermissionState(
979 perm, userId) != null) {
980 // Revoke the runtime permission and clear the flags.
981 origPermissions.revokeRuntimePermission(bp, userId);
982 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -0800983 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700984 // If we revoked a permission permission, we have to write.
985 updatedUserIds = ArrayUtils.appendInt(
986 updatedUserIds, userId);
987 }
988 }
989 // Grant an install permission.
990 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -0800991 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700992 changedInstallPermission = true;
993 }
994 } break;
995
996 case GRANT_RUNTIME: {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800997 for (int userId : currentUserIds) {
998 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700999 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001000 int flags = permState != null ? permState.getFlags() : 0;
1001
1002 boolean wasChanged = false;
1003
1004 if (appSupportsRuntimePermissions) {
1005 // Remove review flag as it is not necessary anymore
1006 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1007 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1008 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001009 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001010
1011 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1012 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1013 wasChanged = true;
1014 } else {
1015 if (permState != null && permState.isGranted()) {
1016 if (permissionsState.grantRuntimePermission(bp, userId)
1017 == PERMISSION_OPERATION_FAILURE) {
1018 wasChanged = true;
1019 }
1020 }
1021 }
1022 } else {
1023 if (permState == null) {
1024 // New permission
1025 if (PLATFORM_PACKAGE_NAME.equals(
1026 bp.getSourcePackageName())) {
1027 if (!bp.isRemoved()) {
1028 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1029 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1030 wasChanged = true;
1031 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001032 }
1033 }
1034
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001035 if (permissionsState.grantRuntimePermission(bp, userId)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001036 != PERMISSION_OPERATION_FAILURE) {
1037 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001038 }
1039 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001040
1041 if (wasChanged) {
1042 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1043 }
1044
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001045 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001046 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001047 }
1048 } break;
1049
1050 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001051 // Upgrade from Pre-Q to Q permission model. Make all permissions
1052 // runtime
1053 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001054 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001055 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001056
Philip P. Moltmann48456672019-01-20 13:14:03 -08001057 // Remove install permission
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001058 if (origPermissions.revokeInstallPermission(bp)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001059 != PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001060 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001061 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001062 changedInstallPermission = true;
1063 }
1064
Philip P. Moltmann48456672019-01-20 13:14:03 -08001065 for (int userId : currentUserIds) {
1066 boolean wasChanged = false;
1067
1068 if (appSupportsRuntimePermissions) {
1069 // Remove review flag as it is not necessary anymore
1070 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1071 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1072 wasChanged = true;
1073 }
1074
1075 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1076 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1077 wasChanged = true;
1078 } else {
1079 if (permissionsState.grantRuntimePermission(bp, userId) !=
1080 PERMISSION_OPERATION_FAILURE) {
1081 wasChanged = true;
1082 }
1083 }
1084 } else {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001085 if (permissionsState.grantRuntimePermission(bp, userId) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001086 PERMISSION_OPERATION_FAILURE) {
1087 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1088 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001089 }
1090 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001091
1092 if (wasChanged) {
1093 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1094 }
1095
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001096 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001097 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001098 }
1099 } break;
1100
1101 default: {
1102 if (packageOfInterest == null
1103 || packageOfInterest.equals(pkg.packageName)) {
1104 if (DEBUG_PERMISSIONS) {
1105 Slog.i(TAG, "Not granting permission " + perm
1106 + " to package " + pkg.packageName
1107 + " because it was previously installed without");
1108 }
1109 }
1110 } break;
1111 }
1112 } else {
1113 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001114 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001115 // Also drop the permission flags.
1116 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001117 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001118 changedInstallPermission = true;
1119 Slog.i(TAG, "Un-granting permission " + perm
1120 + " from package " + pkg.packageName
1121 + " (protectionLevel=" + bp.getProtectionLevel()
1122 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1123 + ")");
1124 } else if (bp.isAppOp()) {
1125 // Don't print warning for app op permissions, since it is fine for them
1126 // not to be granted, there is a UI for the user to decide.
1127 if (DEBUG_PERMISSIONS
1128 && (packageOfInterest == null
1129 || packageOfInterest.equals(pkg.packageName))) {
1130 Slog.i(TAG, "Not granting permission " + perm
1131 + " to package " + pkg.packageName
1132 + " (protectionLevel=" + bp.getProtectionLevel()
1133 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1134 + ")");
1135 }
1136 }
1137 }
1138 }
1139
1140 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1141 !ps.isSystem() || ps.isUpdatedSystem()) {
1142 // This is the first that we have heard about this package, so the
1143 // permissions we have now selected are fixed until explicitly
1144 // changed.
1145 ps.setInstallPermissionsFixed(true);
1146 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001147
1148 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1149 updatedUserIds);
1150 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
1151 permissionsState, pkg, updatedUserIds);
Philip P. Moltmanndde07852019-01-25 16:42:36 -08001152
1153 setAppOpsLocked(permissionsState, pkg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001154 }
1155
1156 // Persist the runtime permissions state for users with changes. If permissions
1157 // were revoked because no app in the shared user declares them we have to
1158 // write synchronously to avoid losing runtime permissions state.
1159 if (callback != null) {
1160 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1161 }
1162 }
1163
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001164 /**
1165 * Set app op for a app-op related to a permission.
1166 *
1167 * @param permission The permission the app-op belongs to
1168 * @param pkg The package the permission belongs to
1169 * @param userId The user to be changed
1170 * @param mode The new mode to set
1171 */
1172 private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg,
1173 @UserIdInt int userId, int mode) {
1174 AppOpsManagerInternal appOpsInternal = LocalServices.getService(
1175 AppOpsManagerInternal.class);
1176
Philip P. Moltmann159d98b2018-12-20 08:30:53 -08001177 appOpsInternal.setUidMode(permissionToOpCode(permission),
1178 getUid(userId, getAppId(pkg.applicationInfo.uid)), mode);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001179 }
1180
1181 /**
1182 * Revoke permissions that are not implicit anymore and that have
1183 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1184 *
1185 * @param ps The state of the permissions of the package
1186 * @param pkg The package that is currently looked at
1187 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1188 * for a user is changed.
1189 *
1190 * @return The updated value of the {@code updatedUserIds} parameter
1191 */
1192 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1193 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1194 @NonNull int[] updatedUserIds) {
1195 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1196
1197 String pkgName = pkg.packageName;
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08001198 boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1199 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001200
1201 int[] users = UserManagerService.getInstance().getUserIds();
1202 int numUsers = users.length;
1203 for (int i = 0; i < numUsers; i++) {
1204 int userId = users[i];
1205
1206 for (String permission : ps.getPermissions(userId)) {
1207 if (!pkg.implicitPermissions.contains(permission)) {
1208 if (!ps.hasInstallPermission(permission)) {
1209 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1210
1211 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1212 BasePermission bp = mSettings.getPermissionLocked(permission);
1213
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001214 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001215
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001216 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
1217 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001218 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1219 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1220 if (DEBUG_PERMISSIONS) {
1221 Slog.i(TAG, "Revoking runtime permission "
1222 + permission + " for " + pkgName
1223 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001224 }
1225 }
1226
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001227 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001228
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001229 List<String> fgPerms = mBackgroundPermissions.get(permission);
1230 if (fgPerms != null) {
1231 int numFgPerms = fgPerms.size();
1232 for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
1233 String fgPerm = fgPerms.get(fgPermNum);
1234
1235 int mode = appOpsManager.unsafeCheckOpRaw(
1236 permissionToOp(fgPerm),
1237 getUid(userId, getAppId(pkg.applicationInfo.uid)),
1238 pkgName);
1239
1240 if (mode == MODE_ALLOWED) {
1241 setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND);
1242 }
1243 }
1244 }
1245 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001246
1247 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1248 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001249 }
1250 }
1251 }
1252 }
1253 }
1254
1255 return updatedUserIds;
1256 }
1257
1258 /**
1259 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1260 *
1261 * <p>A single new permission can be split off from several source permissions. In this case
1262 * the most leniant state is inherited.
1263 *
1264 * <p>Warning: This does not handle foreground / background permissions
1265 *
1266 * @param sourcePerms The permissions to inherit from
1267 * @param newPerm The permission to inherit to
1268 * @param ps The permission state of the package
1269 * @param pkg The package requesting the permissions
1270 * @param userId The user the permission belongs to
1271 */
1272 private void inheritPermissionStateToNewImplicitPermissionLocked(
1273 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1274 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1275 @UserIdInt int userId) {
1276 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1277 String pkgName = pkg.packageName;
1278
1279 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1280 if (permissionToOp(newPerm) != null) {
1281 int mostLenientSourceMode = MODE_ERRORED;
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001282 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001283
1284 // Find most lenient source permission state.
1285 int numSourcePerms = sourcePerms.size();
1286 for (int i = 0; i < numSourcePerms; i++) {
1287 String sourcePerm = sourcePerms.valueAt(i);
1288
1289 if (ps.hasRuntimePermission(sourcePerm, userId)) {
1290 String sourceOp = permissionToOp(sourcePerm);
1291
1292 if (sourceOp != null) {
1293 int mode = appOpsManager.unsafeCheckOpRaw(sourceOp,
1294 getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName);
1295
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001296 if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) {
1297 Log.wtf(TAG, "split permission" + sourcePerm + " has app-op state "
1298 + AppOpsManager.MODE_NAMES[mode]);
1299
1300 continue;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001301 }
1302
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001303 // Leniency order: allowed < ignored < default
1304 if (mode < mostLenientSourceMode) {
1305 mostLenientSourceMode = mode;
1306 flags = ps.getPermissionFlags(sourcePerm, userId);
1307 } else if (mode == mostLenientSourceMode) {
1308 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001309 }
1310 }
1311 }
1312 }
1313
1314 if (mostLenientSourceMode != MODE_ERRORED) {
1315 if (DEBUG_PERMISSIONS) {
1316 Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode
1317 + " from " + sourcePerms + " for " + pkgName);
1318 }
1319
1320 setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode);
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001321
1322 // Add permission flags
1323 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags,
1324 flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001325 }
1326 }
1327 } else {
1328 boolean isGranted = false;
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001329 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001330
1331 int numSourcePerm = sourcePerms.size();
1332 for (int i = 0; i < numSourcePerm; i++) {
1333 String sourcePerm = sourcePerms.valueAt(i);
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001334 if ((ps.hasRuntimePermission(sourcePerm, userId))
1335 || ps.hasInstallPermission(sourcePerm)) {
1336 if (!isGranted) {
1337 flags = 0;
1338 }
1339
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001340 isGranted = true;
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001341 flags |= ps.getPermissionFlags(sourcePerm, userId);
1342 } else {
1343 if (!isGranted) {
1344 flags |= ps.getPermissionFlags(sourcePerm, userId);
1345 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001346 }
1347 }
1348
1349 if (isGranted) {
1350 if (DEBUG_PERMISSIONS) {
1351 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1352 + " for " + pkgName);
1353 }
1354
1355 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1356 }
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001357
1358 // Add permission flags
1359 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001360 }
1361 }
1362
1363 /**
1364 * Set the state of a implicit permission that is seen for the first time.
1365 *
1366 * @param origPs The permission state of the package before the split
1367 * @param ps The new permission state
1368 * @param pkg The package the permission belongs to
1369 * @param updatedUserIds List of users for which the permission state has already been changed
1370 *
1371 * @return List of users for which the permission state has been changed
1372 */
1373 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1374 @NonNull PermissionsState origPs,
1375 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1376 @NonNull int[] updatedUserIds) {
1377 String pkgName = pkg.packageName;
1378 ArraySet<String> newImplicitPermissions = new ArraySet<>();
1379
1380 int numRequestedPerms = pkg.requestedPermissions.size();
1381 for (int i = 0; i < numRequestedPerms; i++) {
1382 BasePermission bp = mSettings.getPermissionLocked(pkg.requestedPermissions.get(i));
1383 if (bp != null) {
1384 String perm = bp.getName();
1385
1386 if (!origPs.hasRequestedPermission(perm) && pkg.implicitPermissions.contains(
1387 perm)) {
1388 newImplicitPermissions.add(perm);
1389
1390 if (DEBUG_PERMISSIONS) {
1391 Slog.i(TAG, perm + " is newly added for " + pkgName);
1392 }
1393 }
1394 }
1395 }
1396
1397 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1398
1399 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1400 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1401 PermissionManager.SplitPermissionInfo spi =
1402 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1403
1404 List<String> newPerms = spi.getNewPermissions();
1405 int numNewPerms = newPerms.size();
1406 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1407 String newPerm = newPerms.get(newPermNum);
1408
1409 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1410 if (splitPerms == null) {
1411 splitPerms = new ArraySet<>();
1412 newToSplitPerms.put(newPerm, splitPerms);
1413 }
1414
1415 splitPerms.add(spi.getSplitPermission());
1416 }
1417 }
1418
1419 int numNewImplicitPerms = newImplicitPermissions.size();
1420 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1421 newImplicitPermNum++) {
1422 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1423 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1424
1425 if (sourcePerms != null) {
1426 if (!ps.hasInstallPermission(newPerm)) {
1427 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1428
1429 int[] users = UserManagerService.getInstance().getUserIds();
1430 int numUsers = users.length;
1431 for (int userNum = 0; userNum < numUsers; userNum++) {
1432 int userId = users[userNum];
1433
1434 ps.updatePermissionFlags(bp, userId,
1435 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1436 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1437 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1438
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001439 boolean inheritsFromInstallPerm = false;
1440 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1441 sourcePermNum++) {
1442 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1443 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001444 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001445 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001446 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001447
1448 if (!origPs.hasRequestedPermission(sourcePerms)
1449 && !inheritsFromInstallPerm) {
1450 // Both permissions are new so nothing to inherit.
1451 if (DEBUG_PERMISSIONS) {
1452 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1453 + " for " + pkgName + " as split permission is also new");
1454 }
1455
1456 break;
1457 } else {
1458 // Inherit from new install or existing runtime permissions
1459 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1460 newPerm, ps, pkg, userId);
1461 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001462 }
1463 }
1464 }
1465 }
1466
1467 return updatedUserIds;
1468 }
1469
Philip P. Moltmanndde07852019-01-25 16:42:36 -08001470 /**
1471 * Fix app-op modes for runtime permissions.
1472 *
1473 * @param permsState The state of the permissions of the package
1474 * @param pkg The package information
1475 */
1476 private void setAppOpsLocked(@NonNull PermissionsState permsState,
1477 @NonNull PackageParser.Package pkg) {
1478 for (int userId : UserManagerService.getInstance().getUserIds()) {
1479 int numPerms = pkg.requestedPermissions.size();
1480 for (int i = 0; i < numPerms; i++) {
1481 String permission = pkg.requestedPermissions.get(i);
1482
1483 int op = permissionToOpCode(permission);
1484 if (op == OP_NONE) {
1485 continue;
1486 }
1487
1488 // Runtime permissions are per uid, not per package, hence per package app-op
1489 // modes should never have been set. It is possible to set them via the shell
1490 // though. Revert such settings during boot to get the device back into a good
1491 // state.
1492 LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
1493 op, getUid(userId, getAppId(pkg.applicationInfo.uid)));
1494
1495 // For pre-M apps the runtime permission do not store the state
1496 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1497 continue;
1498 }
1499
1500 PermissionState state = permsState.getRuntimePermissionState(permission, userId);
1501 if (state == null) {
1502 continue;
1503 }
1504
1505 // Adjust app-op mods for foreground/background permissions. If an package used to
1506 // have both fg and bg permission granted and it lost the bg permission during an
1507 // upgrade the app-op mode should get downgraded to foreground.
1508 if (state.isGranted()) {
1509 BasePermission bp = mSettings.getPermission(permission);
1510
1511 if (bp != null && bp.perm != null && bp.perm.info != null
1512 && bp.perm.info.backgroundPermission != null) {
1513 PermissionState bgState = permsState.getRuntimePermissionState(
1514 bp.perm.info.backgroundPermission, userId);
1515
1516 setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
1517 ? MODE_ALLOWED : MODE_FOREGROUND);
1518 }
1519 }
1520 }
1521 }
1522 }
1523
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001524 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1525 boolean allowed = false;
1526 final int NP = PackageParser.NEW_PERMISSIONS.length;
1527 for (int ip=0; ip<NP; ip++) {
1528 final PackageParser.NewPermissionInfo npi
1529 = PackageParser.NEW_PERMISSIONS[ip];
1530 if (npi.name.equals(perm)
1531 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1532 allowed = true;
1533 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1534 + pkg.packageName);
1535 break;
1536 }
1537 }
1538 return allowed;
1539 }
1540
1541 /**
1542 * Determines whether a package is whitelisted for a particular privapp permission.
1543 *
1544 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1545 *
1546 * <p>This handles parent/child apps.
1547 */
1548 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001549 ArraySet<String> wlPermissions = null;
1550 if (pkg.isVendor()) {
1551 wlPermissions =
1552 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1553 } else if (pkg.isProduct()) {
1554 wlPermissions =
1555 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001556 } else if (pkg.isProductServices()) {
1557 wlPermissions =
1558 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1559 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001560 } else {
1561 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1562 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001563 // Let's check if this package is whitelisted...
1564 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1565 // If it's not, we'll also tail-recurse to the parent.
1566 return whitelisted ||
1567 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1568 }
1569
1570 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1571 BasePermission bp, PermissionsState origPermissions) {
1572 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001573 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1574 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001575 boolean privappPermissionsDisable =
1576 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1577 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1578 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1579 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1580 && !platformPackage && platformPermission) {
1581 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001582 // Only report violations for apps on system image
1583 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1584 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001585 ArraySet<String> deniedPermissions = null;
1586 if (pkg.isVendor()) {
1587 deniedPermissions = SystemConfig.getInstance()
1588 .getVendorPrivAppDenyPermissions(pkg.packageName);
1589 } else if (pkg.isProduct()) {
1590 deniedPermissions = SystemConfig.getInstance()
1591 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001592 } else if (pkg.isProductServices()) {
1593 deniedPermissions = SystemConfig.getInstance()
1594 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001595 } else {
1596 deniedPermissions = SystemConfig.getInstance()
1597 .getPrivAppDenyPermissions(pkg.packageName);
1598 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001599 final boolean permissionViolation =
1600 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001601 if (permissionViolation) {
1602 Slog.w(TAG, "Privileged permission " + perm + " for package "
1603 + pkg.packageName + " - not in privapp-permissions whitelist");
1604
1605 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1606 if (mPrivappPermissionsViolations == null) {
1607 mPrivappPermissionsViolations = new ArraySet<>();
1608 }
1609 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001610 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001611 } else {
1612 return false;
1613 }
1614 }
1615 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1616 return false;
1617 }
1618 }
1619 }
1620 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1621 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1622 final PackageParser.Package systemPackage =
1623 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001624
1625 // check if the package is allow to use this signature permission. A package is allowed to
1626 // use a signature permission if:
1627 // - it has the same set of signing certificates as the source package
1628 // - or its signing certificate was rotated from the source package's certificate
1629 // - or its signing certificate is a previous signing certificate of the defining
1630 // package, and the defining package still trusts the old certificate for permissions
1631 // - or it shares the above relationships with the system package
1632 boolean allowed =
1633 pkg.mSigningDetails.hasAncestorOrSelf(
1634 bp.getSourcePackageSetting().getSigningDetails())
1635 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1636 pkg.mSigningDetails,
1637 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1638 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1639 || systemPackage.mSigningDetails.checkCapability(
1640 pkg.mSigningDetails,
1641 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001642 if (!allowed && (privilegedPermission || oemPermission)) {
1643 if (pkg.isSystem()) {
1644 // For updated system applications, a privileged/oem permission
1645 // is granted only if it had been defined by the original application.
1646 if (pkg.isUpdatedSystemApp()) {
1647 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001648 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001649 final PackageSetting disabledPs =
1650 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1651 if (disabledPs != null
1652 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1653 // If the original was granted this permission, we take
1654 // that grant decision as read and propagate it to the
1655 // update.
1656 if ((privilegedPermission && disabledPs.isPrivileged())
1657 || (oemPermission && disabledPs.isOem()
1658 && canGrantOemPermission(disabledPs, perm))) {
1659 allowed = true;
1660 }
1661 } else {
1662 // The system apk may have been updated with an older
1663 // version of the one on the data partition, but which
1664 // granted a new system permission that it didn't have
1665 // before. In this case we do want to allow the app to
1666 // now get the new permission if the ancestral apk is
1667 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001668 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001669 && isPackageRequestingPermission(disabledPkg, perm)
1670 && ((privilegedPermission && disabledPs.isPrivileged())
1671 || (oemPermission && disabledPs.isOem()
1672 && canGrantOemPermission(disabledPs, perm)))) {
1673 allowed = true;
1674 }
1675 // Also if a privileged parent package on the system image or any of
1676 // its children requested a privileged/oem permission, the updated child
1677 // packages can also get the permission.
1678 if (pkg.parentPackage != null) {
1679 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001680 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001681 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1682 ? (PackageSetting) disabledParentPkg.mExtras : null;
1683 if (disabledParentPkg != null
1684 && ((privilegedPermission && disabledParentPs.isPrivileged())
1685 || (oemPermission && disabledParentPs.isOem()))) {
1686 if (isPackageRequestingPermission(disabledParentPkg, perm)
1687 && canGrantOemPermission(disabledParentPs, perm)) {
1688 allowed = true;
1689 } else if (disabledParentPkg.childPackages != null) {
1690 for (PackageParser.Package disabledChildPkg
1691 : disabledParentPkg.childPackages) {
1692 final PackageSetting disabledChildPs =
1693 (disabledChildPkg != null)
1694 ? (PackageSetting) disabledChildPkg.mExtras
1695 : null;
1696 if (isPackageRequestingPermission(disabledChildPkg, perm)
1697 && canGrantOemPermission(
1698 disabledChildPs, perm)) {
1699 allowed = true;
1700 break;
1701 }
1702 }
1703 }
1704 }
1705 }
1706 }
1707 } else {
1708 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1709 allowed = (privilegedPermission && pkg.isPrivileged())
1710 || (oemPermission && pkg.isOem()
1711 && canGrantOemPermission(ps, perm));
1712 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001713 // In any case, don't grant a privileged permission to privileged vendor apps, if
1714 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1715 // flag.
1716 if (allowed && privilegedPermission &&
1717 !vendorPrivilegedPermission && pkg.isVendor()) {
1718 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1719 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1720 allowed = false;
1721 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001722 }
1723 }
1724 if (!allowed) {
1725 if (!allowed
1726 && bp.isPre23()
1727 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1728 // If this was a previously normal/dangerous permission that got moved
1729 // to a system permission as part of the runtime permission redesign, then
1730 // we still want to blindly grant it to old apps.
1731 allowed = true;
1732 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001733 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1734 // need a separate flag anymore. Hence we need to check which
1735 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001736 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001737 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1738 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1739 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1740 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1741 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001742 // If this permission is to be granted to the system installer and
1743 // this app is an installer, then it gets the permission.
1744 allowed = true;
1745 }
1746 if (!allowed && bp.isVerifier()
1747 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1748 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1749 // If this permission is to be granted to the system verifier and
1750 // this app is a verifier, then it gets the permission.
1751 allowed = true;
1752 }
1753 if (!allowed && bp.isPreInstalled()
1754 && pkg.isSystem()) {
1755 // Any pre-installed system app is allowed to get this permission.
1756 allowed = true;
1757 }
1758 if (!allowed && bp.isDevelopment()) {
1759 // For development permissions, a development permission
1760 // is granted only if it was already granted.
1761 allowed = origPermissions.hasInstallPermission(perm);
1762 }
1763 if (!allowed && bp.isSetup()
1764 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1765 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1766 // If this permission is to be granted to the system setup wizard and
1767 // this app is a setup wizard, then it gets the permission.
1768 allowed = true;
1769 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001770 if (!allowed && bp.isSystemTextClassifier()
1771 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1772 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1773 UserHandle.USER_SYSTEM))) {
1774 // Special permissions for the system default text classifier.
1775 allowed = true;
1776 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001777 if (!allowed && bp.isConfigurator()
1778 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1779 PackageManagerInternal.PACKAGE_CONFIGURATOR,
1780 UserHandle.USER_SYSTEM))) {
1781 // Special permissions for the device configurator.
1782 allowed = true;
1783 }
Varun Shah5f303652018-11-16 18:11:19 -08001784 if (!allowed && bp.isWellbeing()
1785 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1786 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
1787 // Special permission granted only to the OEM specified wellbeing app
1788 allowed = true;
1789 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07001790 if (!allowed && bp.isDocumenter()
1791 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1792 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
1793 // If this permission is to be granted to the documenter and
1794 // this app is the documenter, then it gets the permission.
1795 allowed = true;
1796 }
Joe Onorato5a15b552018-12-18 10:40:04 -08001797 if (!allowed && bp.isIncidentReportApprover()
1798 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1799 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
1800 UserHandle.USER_SYSTEM))) {
1801 // If this permission is to be granted to the incident report approver and
1802 // this app is the incident report approver, then it gets the permission.
1803 allowed = true;
1804 }
George Hodulikcd7695d2019-01-29 18:17:05 -08001805 if (!allowed && bp.isAppPredictor()
1806 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1807 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
1808 // Special permissions for the system app predictor.
1809 allowed = true;
1810 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001811 }
1812 return allowed;
1813 }
1814
1815 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1816 if (!ps.isOem()) {
1817 return false;
1818 }
1819 // all oem permissions must explicitly be granted or denied
1820 final Boolean granted =
1821 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1822 if (granted == null) {
1823 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1824 + ps.name + " must be explicitly declared granted or not");
1825 }
1826 return Boolean.TRUE == granted;
1827 }
1828
1829 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001830 // Permission review applies only to apps not supporting the new permission model.
1831 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1832 return false;
1833 }
1834
1835 // Legacy apps have the permission and get user consent on launch.
1836 if (pkg == null || pkg.mExtras == null) {
1837 return false;
1838 }
1839 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1840 final PermissionsState permissionsState = ps.getPermissionsState();
1841 return permissionsState.isPermissionReviewRequired(userId);
1842 }
1843
1844 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1845 final int permCount = pkg.requestedPermissions.size();
1846 for (int j = 0; j < permCount; j++) {
1847 String requestedPermission = pkg.requestedPermissions.get(j);
1848 if (permission.equals(requestedPermission)) {
1849 return true;
1850 }
1851 }
1852 return false;
1853 }
1854
Andreas Gampea36dc622018-02-05 17:19:22 -08001855 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001856 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1857 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1858 if (pkg.parentPackage == null) {
1859 return;
1860 }
1861 if (pkg.requestedPermissions == null) {
1862 return;
1863 }
1864 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001865 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001866 if (disabledPkg == null || disabledPkg.mExtras == null) {
1867 return;
1868 }
1869 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1870 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1871 return;
1872 }
1873 final int permCount = pkg.requestedPermissions.size();
1874 for (int i = 0; i < permCount; i++) {
1875 String permission = pkg.requestedPermissions.get(i);
1876 BasePermission bp = mSettings.getPermissionLocked(permission);
1877 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1878 continue;
1879 }
1880 for (int userId : mUserManagerInt.getUserIds()) {
1881 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1882 grantRuntimePermission(
1883 permission, pkg.packageName, false, callingUid, userId, callback);
1884 }
1885 }
1886 }
1887 }
1888
1889 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1890 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1891 for (int userId : userIds) {
1892 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1893 callback);
1894 }
1895 }
1896
1897 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1898 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1899 PackageSetting ps = (PackageSetting) pkg.mExtras;
1900 if (ps == null) {
1901 return;
1902 }
1903
1904 PermissionsState permissionsState = ps.getPermissionsState();
1905
1906 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1907 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1908
1909 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1910 >= Build.VERSION_CODES.M;
1911
1912 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1913
1914 for (String permission : pkg.requestedPermissions) {
1915 final BasePermission bp;
1916 synchronized (mLock) {
1917 bp = mSettings.getPermissionLocked(permission);
1918 }
1919 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1920 && (!instantApp || bp.isInstant())
1921 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1922 && (grantedPermissions == null
1923 || ArrayUtils.contains(grantedPermissions, permission))) {
1924 final int flags = permissionsState.getPermissionFlags(permission, userId);
1925 if (supportsRuntimePermissions) {
1926 // Installer cannot change immutable permissions.
1927 if ((flags & immutableFlags) == 0) {
1928 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1929 userId, callback);
1930 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001931 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001932 // In permission review mode we clear the review flag when we
1933 // are asked to install the app with all permissions granted.
1934 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1935 updatePermissionFlags(permission, pkg.packageName,
1936 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08001937 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001938 }
1939 }
1940 }
1941 }
1942 }
1943
1944 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1945 int callingUid, final int userId, PermissionCallback callback) {
1946 if (!mUserManagerInt.exists(userId)) {
1947 Log.e(TAG, "No such user:" + userId);
1948 return;
1949 }
1950
1951 mContext.enforceCallingOrSelfPermission(
1952 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1953 "grantRuntimePermission");
1954
1955 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001956 true, // requireFullPermission
1957 true, // checkShell
1958 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001959 "grantRuntimePermission");
1960
1961 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1962 if (pkg == null || pkg.mExtras == null) {
1963 throw new IllegalArgumentException("Unknown package: " + packageName);
1964 }
1965 final BasePermission bp;
1966 synchronized(mLock) {
1967 bp = mSettings.getPermissionLocked(permName);
1968 }
1969 if (bp == null) {
1970 throw new IllegalArgumentException("Unknown permission: " + permName);
1971 }
1972 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1973 throw new IllegalArgumentException("Unknown package: " + packageName);
1974 }
1975
1976 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1977
1978 // If a permission review is required for legacy apps we represent
1979 // their permissions as always granted runtime ones since we need
1980 // to keep the review required permission flag per user while an
1981 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001982 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001983 && bp.isRuntime()) {
1984 return;
1985 }
1986
1987 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1988
1989 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1990 final PermissionsState permissionsState = ps.getPermissionsState();
1991
1992 final int flags = permissionsState.getPermissionFlags(permName, userId);
1993 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1994 throw new SecurityException("Cannot grant system fixed permission "
1995 + permName + " for package " + packageName);
1996 }
1997 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1998 throw new SecurityException("Cannot grant policy fixed permission "
1999 + permName + " for package " + packageName);
2000 }
2001
2002 if (bp.isDevelopment()) {
2003 // Development permissions must be handled specially, since they are not
2004 // normal runtime permissions. For now they apply to all users.
2005 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002006 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002007 if (callback != null) {
2008 callback.onInstallPermissionGranted();
2009 }
2010 }
2011 return;
2012 }
2013
2014 if (ps.getInstantApp(userId) && !bp.isInstant()) {
2015 throw new SecurityException("Cannot grant non-ephemeral permission"
2016 + permName + " for package " + packageName);
2017 }
2018
2019 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2020 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2021 return;
2022 }
2023
2024 final int result = permissionsState.grantRuntimePermission(bp, userId);
2025 switch (result) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002026 case PERMISSION_OPERATION_FAILURE: {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002027 return;
2028 }
2029
2030 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2031 if (callback != null) {
2032 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2033 }
2034 }
2035 break;
2036 }
2037
2038 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002039 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002040 }
2041
2042 if (callback != null) {
2043 callback.onPermissionGranted(uid, userId);
2044 }
2045
2046 // Only need to do this if user is initialized. Otherwise it's a new user
2047 // and there are no processes running as the user yet and there's no need
2048 // to make an expensive call to remount processes for the changed permissions.
2049 if (READ_EXTERNAL_STORAGE.equals(permName)
2050 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2051 final long token = Binder.clearCallingIdentity();
2052 try {
2053 if (mUserManagerInt.isUserInitialized(userId)) {
2054 StorageManagerInternal storageManagerInternal = LocalServices.getService(
2055 StorageManagerInternal.class);
2056 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2057 }
2058 } finally {
2059 Binder.restoreCallingIdentity(token);
2060 }
2061 }
2062
2063 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002064
2065 private void revokeRuntimePermission(String permName, String packageName,
2066 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002067 if (!mUserManagerInt.exists(userId)) {
2068 Log.e(TAG, "No such user:" + userId);
2069 return;
2070 }
2071
2072 mContext.enforceCallingOrSelfPermission(
2073 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2074 "revokeRuntimePermission");
2075
2076 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002077 true, // requireFullPermission
2078 true, // checkShell
2079 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002080 "revokeRuntimePermission");
2081
2082 final int appId;
2083
2084 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2085 if (pkg == null || pkg.mExtras == null) {
2086 throw new IllegalArgumentException("Unknown package: " + packageName);
2087 }
2088 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2089 throw new IllegalArgumentException("Unknown package: " + packageName);
2090 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002091 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002092 if (bp == null) {
2093 throw new IllegalArgumentException("Unknown permission: " + permName);
2094 }
2095
2096 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2097
2098 // If a permission review is required for legacy apps we represent
2099 // their permissions as always granted runtime ones since we need
2100 // to keep the review required permission flag per user while an
2101 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002102 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002103 && bp.isRuntime()) {
2104 return;
2105 }
2106
2107 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2108 final PermissionsState permissionsState = ps.getPermissionsState();
2109
2110 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07002111 // Only the system may revoke SYSTEM_FIXED permissions.
2112 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2113 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2114 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002115 + permName + " for package " + packageName);
2116 }
2117 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2118 throw new SecurityException("Cannot revoke policy fixed permission "
2119 + permName + " for package " + packageName);
2120 }
2121
2122 if (bp.isDevelopment()) {
2123 // Development permissions must be handled specially, since they are not
2124 // normal runtime permissions. For now they apply to all users.
2125 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002126 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002127 if (callback != null) {
2128 callback.onInstallPermissionRevoked();
2129 }
2130 }
2131 return;
2132 }
2133
2134 if (permissionsState.revokeRuntimePermission(bp, userId) ==
Philip P. Moltmann48456672019-01-20 13:14:03 -08002135 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002136 return;
2137 }
2138
2139 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002140 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002141 }
2142
2143 if (callback != null) {
2144 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2145 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2146 }
2147 }
2148
Andreas Gampea36dc622018-02-05 17:19:22 -08002149 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002150 private int[] revokeUnusedSharedUserPermissionsLocked(
2151 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002152 // Collect all used permissions in the UID
2153 final ArraySet<String> usedPermissions = new ArraySet<>();
2154 final List<PackageParser.Package> pkgList = suSetting.getPackages();
2155 if (pkgList == null || pkgList.size() == 0) {
2156 return EmptyArray.INT;
2157 }
2158 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07002159 if (pkg.requestedPermissions == null) {
2160 continue;
2161 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002162 final int requestedPermCount = pkg.requestedPermissions.size();
2163 for (int j = 0; j < requestedPermCount; j++) {
2164 String permission = pkg.requestedPermissions.get(j);
2165 BasePermission bp = mSettings.getPermissionLocked(permission);
2166 if (bp != null) {
2167 usedPermissions.add(permission);
2168 }
2169 }
2170 }
2171
2172 PermissionsState permissionsState = suSetting.getPermissionsState();
2173 // Prune install permissions
2174 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2175 final int installPermCount = installPermStates.size();
2176 for (int i = installPermCount - 1; i >= 0; i--) {
2177 PermissionState permissionState = installPermStates.get(i);
2178 if (!usedPermissions.contains(permissionState.getName())) {
2179 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2180 if (bp != null) {
2181 permissionsState.revokeInstallPermission(bp);
2182 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002183 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002184 }
2185 }
2186 }
2187
2188 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2189
2190 // Prune runtime permissions
2191 for (int userId : allUserIds) {
2192 List<PermissionState> runtimePermStates = permissionsState
2193 .getRuntimePermissionStates(userId);
2194 final int runtimePermCount = runtimePermStates.size();
2195 for (int i = runtimePermCount - 1; i >= 0; i--) {
2196 PermissionState permissionState = runtimePermStates.get(i);
2197 if (!usedPermissions.contains(permissionState.getName())) {
2198 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2199 if (bp != null) {
2200 permissionsState.revokeRuntimePermission(bp, userId);
2201 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002202 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002203 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2204 runtimePermissionChangedUserIds, userId);
2205 }
2206 }
2207 }
2208 }
2209
2210 return runtimePermissionChangedUserIds;
2211 }
2212
Todd Kennedyc8423932017-10-05 08:58:36 -07002213 private String[] getAppOpPermissionPackages(String permName) {
2214 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2215 return null;
2216 }
2217 synchronized (mLock) {
2218 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2219 if (pkgs == null) {
2220 return null;
2221 }
2222 return pkgs.toArray(new String[pkgs.size()]);
2223 }
2224 }
2225
2226 private int getPermissionFlags(
2227 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002228 if (!mUserManagerInt.exists(userId)) {
2229 return 0;
2230 }
2231
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002232 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
Todd Kennedy0eb97382017-10-03 16:57:22 -07002233
2234 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002235 true, // requireFullPermission
2236 false, // checkShell
2237 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002238 "getPermissionFlags");
2239
2240 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2241 if (pkg == null || pkg.mExtras == null) {
2242 return 0;
2243 }
2244 synchronized (mLock) {
2245 if (mSettings.getPermissionLocked(permName) == null) {
2246 return 0;
2247 }
2248 }
2249 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2250 return 0;
2251 }
2252 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2253 PermissionsState permissionsState = ps.getPermissionsState();
2254 return permissionsState.getPermissionFlags(permName, userId);
2255 }
2256
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002257 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2258 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2259 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2260
2261 private void updatePermissions(String packageName, PackageParser.Package pkg,
2262 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2263 PermissionCallback callback) {
2264 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2265 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2266 updatePermissions(
2267 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2268 if (pkg != null && pkg.childPackages != null) {
2269 for (PackageParser.Package childPkg : pkg.childPackages) {
2270 updatePermissions(childPkg.packageName, childPkg,
2271 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2272 }
2273 }
2274 }
2275
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002276 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2277 boolean updatePermissionsOnPreQUpdate, Collection<PackageParser.Package> allPackages,
2278 PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002279 final int flags = UPDATE_PERMISSIONS_ALL |
2280 (sdkUpdated
2281 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2282 : 0);
2283 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002284
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002285 if (updatePermissionsOnPreQUpdate) {
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002286 final int[] userIds = UserManagerService.getInstance().getUserIds();
2287
2288 for (PackageParser.Package pkg : allPackages) {
2289 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2290 if (ps == null) {
2291 return;
2292 }
2293
2294 final boolean appSupportsRuntimePermissions =
2295 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
2296 final PermissionsState permsState = ps.getPermissionsState();
2297
2298 for (String permName : new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
2299 Manifest.permission.ACCESS_COARSE_LOCATION,
2300 Manifest.permission.ACCESS_BACKGROUND_LOCATION}) {
2301 final BasePermission bp = mSettings.getPermissionLocked(permName);
2302
2303 for (int userId : userIds) {
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002304 if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
2305 Settings.Secure.LOCATION_PERMISSIONS_UPGRADE_TO_Q_MODE, 0, userId)
2306 != 0) {
2307 continue;
2308 }
2309
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002310 final PermissionState permState = permsState.getRuntimePermissionState(
2311 permName, userId);
2312
2313 if (permState != null
2314 && (permState.getFlags() & BLOCKING_PERMISSION_FLAGS) == 0) {
2315 if (permState.isGranted()) {
2316 permsState.updatePermissionFlags(bp, userId,
2317 USER_PERMISSION_FLAGS, 0);
2318 }
2319
2320 if (appSupportsRuntimePermissions) {
2321 permsState.revokeRuntimePermission(bp, userId);
2322 } else {
2323 // Force a review even for apps that were already installed
2324 permsState.updatePermissionFlags(bp, userId,
2325 FLAG_PERMISSION_REVIEW_REQUIRED,
2326 FLAG_PERMISSION_REVIEW_REQUIRED);
2327 }
2328 }
2329 }
2330 }
2331 }
2332 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002333 }
2334
2335 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2336 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2337 PermissionCallback callback) {
2338 // TODO: Most of the methods exposing BasePermission internals [source package name,
2339 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2340 // have package settings, we should make note of it elsewhere [map between
2341 // source package name and BasePermission] and cycle through that here. Then we
2342 // define a single method on BasePermission that takes a PackageSetting, changing
2343 // package name and a package.
2344 // NOTE: With this approach, we also don't need to tree trees differently than
2345 // normal permissions. Today, we need two separate loops because these BasePermission
2346 // objects are stored separately.
2347 // Make sure there are no dangling permission trees.
2348 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2349
2350 // Make sure all dynamic permissions have been assigned to a package,
2351 // and make sure there are no dangling permissions.
2352 flags = updatePermissions(changingPkgName, changingPkg, flags);
2353
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002354 synchronized (mLock) {
2355 if (mBackgroundPermissions == null) {
2356 // Cache background -> foreground permission mapping.
2357 // Only system declares background permissions, hence mapping does never change.
2358 mBackgroundPermissions = new ArrayMap<>();
2359 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002360 if (bp.perm != null && bp.perm.info != null
2361 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002362 String fgPerm = bp.name;
2363 String bgPerm = bp.perm.info.backgroundPermission;
2364
2365 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2366 if (fgPerms == null) {
2367 fgPerms = new ArrayList<>();
2368 mBackgroundPermissions.put(bgPerm, fgPerms);
2369 }
2370
2371 fgPerms.add(fgPerm);
2372 }
2373 }
2374 }
2375 }
2376
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002377 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002378 // Now update the permissions for all packages, in particular
2379 // replace the granted permissions of the system packages.
2380 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2381 for (PackageParser.Package pkg : allPackages) {
2382 if (pkg != changingPkg) {
2383 // Only replace for packages on requested volume
2384 final String volumeUuid = getVolumeUuidForPackage(pkg);
2385 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2386 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002387 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002388 }
2389 }
2390 }
2391
2392 if (changingPkg != null) {
2393 // Only replace for packages on requested volume
2394 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2395 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2396 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002397 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002398 }
2399 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2400 }
2401
2402 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002403 Set<BasePermission> needsUpdate = null;
2404 synchronized (mLock) {
2405 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2406 while (it.hasNext()) {
2407 final BasePermission bp = it.next();
2408 if (bp.isDynamic()) {
2409 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2410 }
2411 if (bp.getSourcePackageSetting() != null) {
2412 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002413 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002414 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2415 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002416 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002417 it.remove();
2418 }
2419 continue;
2420 }
2421 if (needsUpdate == null) {
2422 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2423 }
2424 needsUpdate.add(bp);
2425 }
2426 }
2427 if (needsUpdate != null) {
2428 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002429 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002430 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2431 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002432 if (sourcePkg != null && sourcePkg.mExtras != null) {
2433 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002434 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002435 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002436 }
2437 continue;
2438 }
2439 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2440 + " from package " + bp.getSourcePackageName());
2441 mSettings.removePermissionLocked(bp.getName());
2442 }
2443 }
2444 }
2445 return flags;
2446 }
2447
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002448 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002449 int flags) {
2450 Set<BasePermission> needsUpdate = null;
2451 synchronized (mLock) {
2452 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2453 while (it.hasNext()) {
2454 final BasePermission bp = it.next();
2455 if (bp.getSourcePackageSetting() != null) {
2456 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002457 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002458 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2459 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002460 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002461 it.remove();
2462 }
2463 continue;
2464 }
2465 if (needsUpdate == null) {
2466 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2467 }
2468 needsUpdate.add(bp);
2469 }
2470 }
2471 if (needsUpdate != null) {
2472 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002473 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002474 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2475 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002476 if (sourcePkg != null && sourcePkg.mExtras != null) {
2477 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002478 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002479 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002480 }
2481 continue;
2482 }
2483 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2484 + " from package " + bp.getSourcePackageName());
2485 mSettings.removePermissionLocked(bp.getName());
2486 }
2487 }
2488 }
2489 return flags;
2490 }
2491
Todd Kennedy0eb97382017-10-03 16:57:22 -07002492 private void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002493 int flagValues, int callingUid, int userId, boolean overridePolicy,
2494 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002495 if (!mUserManagerInt.exists(userId)) {
2496 return;
2497 }
2498
2499 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2500
2501 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002502 true, // requireFullPermission
2503 true, // checkShell
2504 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002505 "updatePermissionFlags");
2506
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002507 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2508 throw new SecurityException("updatePermissionFlags requires "
2509 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2510 }
2511
Todd Kennedy0eb97382017-10-03 16:57:22 -07002512 // Only the system can change these flags and nothing else.
2513 if (callingUid != Process.SYSTEM_UID) {
2514 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2515 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2516 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2517 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2518 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2519 }
2520
2521 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2522 if (pkg == null || pkg.mExtras == null) {
2523 throw new IllegalArgumentException("Unknown package: " + packageName);
2524 }
2525 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2526 throw new IllegalArgumentException("Unknown package: " + packageName);
2527 }
2528
2529 final BasePermission bp;
2530 synchronized (mLock) {
2531 bp = mSettings.getPermissionLocked(permName);
2532 }
2533 if (bp == null) {
2534 throw new IllegalArgumentException("Unknown permission: " + permName);
2535 }
2536
2537 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2538 final PermissionsState permissionsState = ps.getPermissionsState();
2539 final boolean hadState =
2540 permissionsState.getRuntimePermissionState(permName, userId) != null;
2541 final boolean permissionUpdated =
2542 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
2543 if (permissionUpdated && callback != null) {
2544 // Install and runtime permissions are stored in different places,
2545 // so figure out what permission changed and persist the change.
2546 if (permissionsState.getInstallPermissionState(permName) != null) {
2547 callback.onInstallPermissionUpdated();
2548 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2549 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002550 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002551 }
2552 }
2553 }
2554
2555 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2556 int userId, Collection<Package> packages, PermissionCallback callback) {
2557 if (!mUserManagerInt.exists(userId)) {
2558 return false;
2559 }
2560
2561 enforceGrantRevokeRuntimePermissionPermissions(
2562 "updatePermissionFlagsForAllApps");
2563 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002564 true, // requireFullPermission
2565 true, // checkShell
2566 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002567 "updatePermissionFlagsForAllApps");
2568
2569 // Only the system can change system fixed flags.
2570 if (callingUid != Process.SYSTEM_UID) {
2571 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2572 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2573 }
2574
2575 boolean changed = false;
2576 for (PackageParser.Package pkg : packages) {
2577 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2578 if (ps == null) {
2579 continue;
2580 }
2581 PermissionsState permissionsState = ps.getPermissionsState();
2582 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2583 userId, flagMask, flagValues);
2584 }
2585 return changed;
2586 }
2587
2588 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2589 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2590 != PackageManager.PERMISSION_GRANTED
2591 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2592 != PackageManager.PERMISSION_GRANTED) {
2593 throw new SecurityException(message + " requires "
2594 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2595 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2596 }
2597 }
2598
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002599 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2600 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2601 != PackageManager.PERMISSION_GRANTED
2602 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2603 != PackageManager.PERMISSION_GRANTED
2604 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2605 != PackageManager.PERMISSION_GRANTED) {
2606 throw new SecurityException(message + " requires "
2607 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2608 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
2609 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2610 }
2611 }
2612
Todd Kennedy0eb97382017-10-03 16:57:22 -07002613 /**
2614 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2615 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2616 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2617 * @param message the message to log on security exception
2618 */
2619 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002620 boolean requireFullPermission, boolean checkShell,
2621 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002622 if (userId < 0) {
2623 throw new IllegalArgumentException("Invalid userId " + userId);
2624 }
2625 if (checkShell) {
2626 PackageManagerServiceUtils.enforceShellRestriction(
2627 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2628 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002629 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002630 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002631 if (requireFullPermission) {
2632 mContext.enforceCallingOrSelfPermission(
2633 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2634 } else {
2635 try {
2636 mContext.enforceCallingOrSelfPermission(
2637 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2638 } catch (SecurityException se) {
2639 mContext.enforceCallingOrSelfPermission(
2640 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2641 }
2642 }
2643 }
2644 }
2645
Andreas Gampea71bee82018-07-20 12:55:36 -07002646 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002647 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2648 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002649 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002650 size += tree.calculateFootprint(perm);
2651 }
2652 return size;
2653 }
2654
Andreas Gampea71bee82018-07-20 12:55:36 -07002655 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002656 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2657 // We calculate the max size of permissions defined by this uid and throw
2658 // if that plus the size of 'info' would exceed our stated maximum.
2659 if (tree.getUid() != Process.SYSTEM_UID) {
2660 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2661 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2662 throw new SecurityException("Permission tree size cap exceeded");
2663 }
2664 }
2665 }
2666
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002667 private void systemReady() {
2668 mSystemReady = true;
2669 if (mPrivappPermissionsViolations != null) {
2670 throw new IllegalStateException("Signature|privileged permissions not in "
2671 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2672 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002673
2674 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002675 }
2676
2677 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2678 if (pkg == null) {
2679 return StorageManager.UUID_PRIVATE_INTERNAL;
2680 }
2681 if (pkg.isExternal()) {
2682 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2683 return StorageManager.UUID_PRIMARY_PHYSICAL;
2684 } else {
2685 return pkg.volumeUuid;
2686 }
2687 } else {
2688 return StorageManager.UUID_PRIVATE_INTERNAL;
2689 }
2690 }
2691
Todd Kennedyc8423932017-10-05 08:58:36 -07002692 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2693 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2694 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2695 return true;
2696 }
2697 }
2698 return false;
2699 }
2700
Todd Kennedy0eb97382017-10-03 16:57:22 -07002701 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002702 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002703 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002704 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002705 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002706 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002707 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002708 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2709 final LogMaker log = new LogMaker(action);
2710 log.setPackageName(packageName);
2711 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002712
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002713 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002714 }
2715
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002716 /**
2717 * Get the mapping of background permissions to their foreground permissions.
2718 *
2719 * <p>Only initialized in the system server.
2720 *
2721 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2722 */
2723 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2724 return mBackgroundPermissions;
2725 }
2726
Philip P. Moltmann48456672019-01-20 13:14:03 -08002727 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002728 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002729 public void systemReady() {
2730 PermissionManagerService.this.systemReady();
2731 }
2732 @Override
2733 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2734 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2735 }
2736 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002737 public void revokeRuntimePermissionsIfGroupChanged(
2738 @NonNull PackageParser.Package newPackage,
2739 @NonNull PackageParser.Package oldPackage,
2740 @NonNull ArrayList<String> allPackageNames,
2741 @NonNull PermissionCallback permissionCallback) {
2742 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2743 oldPackage, allPackageNames, permissionCallback);
2744 }
2745 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002746 public void addAllPermissions(Package pkg, boolean chatty) {
2747 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002748 }
2749 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002750 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2751 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2752 }
2753 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00002754 public void removeAllPermissions(Package pkg, boolean chatty) {
2755 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002756 }
2757 @Override
2758 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002759 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002760 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2761 }
2762 @Override
2763 public void removeDynamicPermission(String permName, int callingUid,
2764 PermissionCallback callback) {
2765 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002766 }
2767 @Override
2768 public void grantRuntimePermission(String permName, String packageName,
2769 boolean overridePolicy, int callingUid, int userId,
2770 PermissionCallback callback) {
2771 PermissionManagerService.this.grantRuntimePermission(
2772 permName, packageName, overridePolicy, callingUid, userId, callback);
2773 }
2774 @Override
2775 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2776 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2777 PermissionManagerService.this.grantRequestedRuntimePermissions(
2778 pkg, userIds, grantedPermissions, callingUid, callback);
2779 }
2780 @Override
2781 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2782 int callingUid, PermissionCallback callback) {
2783 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2784 pkg, callingUid, callback);
2785 }
2786 @Override
2787 public void revokeRuntimePermission(String permName, String packageName,
2788 boolean overridePolicy, int callingUid, int userId,
2789 PermissionCallback callback) {
2790 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jinae750fb2018-09-27 23:00:20 +00002791 overridePolicy, callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002792 }
2793 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002794 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2795 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2796 PermissionManagerService.this.updatePermissions(
2797 packageName, pkg, replaceGrant, allPackages, callback);
2798 }
2799 @Override
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002800 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2801 boolean updatePermissionsOnPreQUpdate, Collection<PackageParser.Package> allPackages,
2802 PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002803 PermissionManagerService.this.updateAllPermissions(
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002804 volumeUuid, sdkUpdated, updatePermissionsOnPreQUpdate, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002805 }
2806 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002807 public String[] getAppOpPermissionPackages(String permName) {
2808 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2809 }
2810 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002811 public int getPermissionFlags(String permName, String packageName, int callingUid,
2812 int userId) {
2813 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2814 callingUid, userId);
2815 }
2816 @Override
2817 public void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002818 int flagValues, int callingUid, int userId, boolean overridePolicy,
2819 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002820 PermissionManagerService.this.updatePermissionFlags(
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002821 permName, packageName, flagMask, flagValues, callingUid, userId,
2822 overridePolicy, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002823 }
2824 @Override
2825 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2826 int userId, Collection<Package> packages, PermissionCallback callback) {
2827 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2828 flagMask, flagValues, callingUid, userId, packages, callback);
2829 }
2830 @Override
2831 public void enforceCrossUserPermission(int callingUid, int userId,
2832 boolean requireFullPermission, boolean checkShell, String message) {
2833 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002834 requireFullPermission, checkShell, false, message);
2835 }
2836 @Override
2837 public void enforceCrossUserPermission(int callingUid, int userId,
2838 boolean requireFullPermission, boolean checkShell,
2839 boolean requirePermissionWhenSameUser, String message) {
2840 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2841 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002842 }
2843 @Override
2844 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2845 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2846 }
2847 @Override
2848 public int checkPermission(String permName, String packageName, int callingUid,
2849 int userId) {
2850 return PermissionManagerService.this.checkPermission(
2851 permName, packageName, callingUid, userId);
2852 }
2853 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002854 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2855 int callingUid) {
2856 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002857 }
2858 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002859 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2860 int callingUid) {
2861 return PermissionManagerService.this.getPermissionGroupInfo(
2862 groupName, flags, callingUid);
2863 }
2864 @Override
2865 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2866 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2867 }
2868 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002869 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2870 int callingUid) {
2871 return PermissionManagerService.this.getPermissionInfo(
2872 permName, packageName, flags, callingUid);
2873 }
2874 @Override
2875 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2876 int callingUid) {
2877 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2878 }
2879 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002880 public PermissionSettings getPermissionSettings() {
2881 return mSettings;
2882 }
2883 @Override
2884 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2885 return mDefaultPermissionGrantPolicy;
2886 }
2887 @Override
2888 public BasePermission getPermissionTEMP(String permName) {
2889 synchronized (PermissionManagerService.this.mLock) {
2890 return mSettings.getPermissionLocked(permName);
2891 }
2892 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002893
2894 @Override
2895 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
2896 return PermissionManagerService.this.backupRuntimePermissions(user);
2897 }
2898
2899 @Override
2900 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
2901 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
2902 }
2903
2904 @Override
2905 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
2906 @NonNull UserHandle user) {
2907 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
2908 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002909 }
2910}