blob: f0230fcb91df76ee848b19bbc00802565f7d2f9b [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;
Todd Kennedy3bc94722017-10-10 09:55:53 -070021import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Hongwei Wangf391b552018-04-06 13:52:46 -070022import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
23
Todd Kennedyc29b11a2017-10-23 15:55:59 -070024import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
25import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
26import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
27import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
28import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Todd Kennedy0eb97382017-10-03 16:57:22 -070029
30import android.Manifest;
31import android.annotation.NonNull;
32import android.annotation.Nullable;
Todd Kennedy0eb97382017-10-03 16:57:22 -070033import android.content.Context;
34import android.content.pm.PackageManager;
35import android.content.pm.PackageManagerInternal;
36import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070037import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070038import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070039import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070040import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070041import android.os.Binder;
42import android.os.Build;
43import android.os.Handler;
44import android.os.HandlerThread;
45import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070046import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070047import android.os.UserHandle;
48import android.os.UserManager;
49import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070050import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070051import android.os.storage.StorageManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070052import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.util.ArrayMap;
54import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070055import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070056import android.util.Log;
57import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070058import android.util.SparseArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070059
Todd Kennedyc29b11a2017-10-23 15:55:59 -070060import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070061import com.android.internal.logging.MetricsLogger;
62import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070063import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070064import com.android.internal.util.ArrayUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070065import com.android.server.LocalServices;
66import com.android.server.ServiceThread;
67import com.android.server.SystemConfig;
68import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070069import com.android.server.pm.PackageManagerServiceUtils;
70import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070071import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070072import com.android.server.pm.UserManagerService;
Hongwei Wangf391b552018-04-06 13:52:46 -070073import com.android.server.pm.permission.DefaultPermissionGrantPolicy
74 .DefaultPermissionGrantedCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070075import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
76import com.android.server.pm.permission.PermissionsState.PermissionState;
77
78import libcore.util.EmptyArray;
79
80import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -070081import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -070082import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -070083import java.util.Iterator;
84import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -070085import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070086import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -070087import java.util.Set;
Todd Kennedy0eb97382017-10-03 16:57:22 -070088
89/**
90 * Manages all permissions and handles permissions related tasks.
91 */
92public class PermissionManagerService {
93 private static final String TAG = "PackageManager";
94
Todd Kennedyc29b11a2017-10-23 15:55:59 -070095 /** Permission grant: not grant the permission. */
96 private static final int GRANT_DENIED = 1;
97 /** Permission grant: grant the permission as an install permission. */
98 private static final int GRANT_INSTALL = 2;
99 /** Permission grant: grant the permission as a runtime one. */
100 private static final int GRANT_RUNTIME = 3;
101 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
102 private static final int GRANT_UPGRADE = 4;
103
104 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
105 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
106 /** Empty array to avoid allocations */
107 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700108
Hongwei Wangf391b552018-04-06 13:52:46 -0700109 /** If the permission of the value is granted, so is the key */
110 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
111
112 static {
113 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
114 Manifest.permission.ACCESS_FINE_LOCATION);
115 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
116 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
117 }
118
Todd Kennedy0eb97382017-10-03 16:57:22 -0700119 /** Lock to protect internal data access */
120 private final Object mLock;
121
122 /** Internal connection to the package manager */
123 private final PackageManagerInternal mPackageManagerInt;
124
125 /** Internal connection to the user manager */
126 private final UserManagerInternal mUserManagerInt;
127
128 /** Default permission policy to provide proper behaviour out-of-the-box */
129 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
130
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700131 /**
132 * Built-in permissions. Read from system configuration files. Mapping is from
133 * UID to permission name.
134 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700135 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700136
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700137 /** Built-in group IDs given to all packages. Read from system configuration files. */
138 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700139
140 private final HandlerThread mHandlerThread;
141 private final Handler mHandler;
142 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700143 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700144
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700145 /** Internal storage for permissions and related settings */
146 @GuardedBy("mLock")
147 private final PermissionSettings mSettings;
148
149 @GuardedBy("mLock")
150 private ArraySet<String> mPrivappPermissionsViolations;
151
152 @GuardedBy("mLock")
153 private boolean mSystemReady;
154
Todd Kennedy0eb97382017-10-03 16:57:22 -0700155 PermissionManagerService(Context context,
156 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
157 @NonNull Object externalLock) {
158 mContext = context;
159 mLock = externalLock;
160 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
161 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700162 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700163
164 mHandlerThread = new ServiceThread(TAG,
165 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
166 mHandlerThread.start();
167 mHandler = new Handler(mHandlerThread.getLooper());
168 Watchdog.getInstance().addThread(mHandler);
169
170 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
171 context, mHandlerThread.getLooper(), defaultGrantCallback, this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700172 SystemConfig systemConfig = SystemConfig.getInstance();
173 mSystemPermissions = systemConfig.getSystemPermissions();
174 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700175
176 // propagate permission configuration
177 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
178 SystemConfig.getInstance().getPermissions();
179 synchronized (mLock) {
180 for (int i=0; i<permConfig.size(); i++) {
181 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
182 BasePermission bp = mSettings.getPermissionLocked(perm.name);
183 if (bp == null) {
184 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
185 mSettings.putPermissionLocked(perm.name, bp);
186 }
187 if (perm.gids != null) {
188 bp.setGids(perm.gids, perm.perUser);
189 }
190 }
191 }
192
193 LocalServices.addService(
194 PermissionManagerInternal.class, new PermissionManagerInternalImpl());
195 }
196
197 /**
198 * Creates and returns an initialized, internal service for use by other components.
199 * <p>
200 * The object returned is identical to the one returned by the LocalServices class using:
201 * {@code LocalServices.getService(PermissionManagerInternal.class);}
202 * <p>
203 * NOTE: The external lock is temporary and should be removed. This needs to be a
204 * lock created by the permission manager itself.
205 */
206 public static PermissionManagerInternal create(Context context,
207 @Nullable DefaultPermissionGrantedCallback defaultGrantCallback,
208 @NonNull Object externalLock) {
209 final PermissionManagerInternal permMgrInt =
210 LocalServices.getService(PermissionManagerInternal.class);
211 if (permMgrInt != null) {
212 return permMgrInt;
213 }
214 new PermissionManagerService(context, defaultGrantCallback, externalLock);
215 return LocalServices.getService(PermissionManagerInternal.class);
216 }
217
218 @Nullable BasePermission getPermission(String permName) {
219 synchronized (mLock) {
220 return mSettings.getPermissionLocked(permName);
221 }
222 }
223
224 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
225 if (!mUserManagerInt.exists(userId)) {
226 return PackageManager.PERMISSION_DENIED;
227 }
228
Patrick Baumann97b9b532018-04-11 14:51:30 +0000229 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
230 if (pkg != null && pkg.mExtras != null) {
231 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700232 return PackageManager.PERMISSION_DENIED;
233 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000234 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700235 final boolean instantApp = ps.getInstantApp(userId);
236 final PermissionsState permissionsState = ps.getPermissionsState();
237 if (permissionsState.hasPermission(permName, userId)) {
238 if (instantApp) {
239 synchronized (mLock) {
240 BasePermission bp = mSettings.getPermissionLocked(permName);
241 if (bp != null && bp.isInstant()) {
242 return PackageManager.PERMISSION_GRANTED;
243 }
244 }
245 } else {
246 return PackageManager.PERMISSION_GRANTED;
247 }
248 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700249 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700250 return PackageManager.PERMISSION_GRANTED;
251 }
252 }
253
254 return PackageManager.PERMISSION_DENIED;
255 }
256
Todd Kennedy3c714492017-10-27 09:12:50 -0700257 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
258 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700259 final int callingUserId = UserHandle.getUserId(callingUid);
260 final boolean isCallerInstantApp =
261 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
262 final boolean isUidInstantApp =
263 mPackageManagerInt.getInstantAppPackageName(uid) != null;
264 final int userId = UserHandle.getUserId(uid);
265 if (!mUserManagerInt.exists(userId)) {
266 return PackageManager.PERMISSION_DENIED;
267 }
268
Todd Kennedy3c714492017-10-27 09:12:50 -0700269 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700270 if (pkg.mSharedUserId != null) {
271 if (isCallerInstantApp) {
272 return PackageManager.PERMISSION_DENIED;
273 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700274 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
275 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700276 }
277 final PermissionsState permissionsState =
278 ((PackageSetting) pkg.mExtras).getPermissionsState();
279 if (permissionsState.hasPermission(permName, userId)) {
280 if (isUidInstantApp) {
281 if (mSettings.isPermissionInstant(permName)) {
282 return PackageManager.PERMISSION_GRANTED;
283 }
284 } else {
285 return PackageManager.PERMISSION_GRANTED;
286 }
287 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700288 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700289 return PackageManager.PERMISSION_GRANTED;
290 }
291 } else {
292 ArraySet<String> perms = mSystemPermissions.get(uid);
293 if (perms != null) {
294 if (perms.contains(permName)) {
295 return PackageManager.PERMISSION_GRANTED;
296 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700297 if (FULLER_PERMISSION_MAP.containsKey(permName)
298 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700299 return PackageManager.PERMISSION_GRANTED;
300 }
301 }
302 }
303 return PackageManager.PERMISSION_DENIED;
304 }
305
Hongwei Wangf391b552018-04-06 13:52:46 -0700306 /**
307 * Returns {@code true} if the permission can be implied from another granted permission.
308 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
309 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
310 * it access to any implied permissions.
311 */
312 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
313 String permName, int userId) {
314 return FULLER_PERMISSION_MAP.containsKey(permName)
315 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
316 }
317
Todd Kennedy460f28c2017-10-06 13:46:22 -0700318 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
319 int callingUid) {
320 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
321 return null;
322 }
323 synchronized (mLock) {
324 return PackageParser.generatePermissionGroupInfo(
325 mSettings.mPermissionGroups.get(groupName), flags);
326 }
327 }
328
329 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
330 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
331 return null;
332 }
333 synchronized (mLock) {
334 final int N = mSettings.mPermissionGroups.size();
335 final ArrayList<PermissionGroupInfo> out
336 = new ArrayList<PermissionGroupInfo>(N);
337 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
338 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
339 }
340 return out;
341 }
342 }
343
344 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700345 int callingUid) {
346 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
347 return null;
348 }
349 // reader
350 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700351 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700352 if (bp == null) {
353 return null;
354 }
355 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
356 bp.getProtectionLevel(), packageName, callingUid);
357 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
358 }
359 }
360
361 private List<PermissionInfo> getPermissionInfoByGroup(
362 String groupName, int flags, int callingUid) {
363 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
364 return null;
365 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700366 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700367 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
368 return null;
369 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700370 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700371 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700372 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
373 if (pi != null) {
374 out.add(pi);
375 }
376 }
377 return out;
378 }
379 }
380
381 private int adjustPermissionProtectionFlagsLocked(
382 int protectionLevel, String packageName, int uid) {
383 // Signature permission flags area always reported
384 final int protectionLevelMasked = protectionLevel
385 & (PermissionInfo.PROTECTION_NORMAL
386 | PermissionInfo.PROTECTION_DANGEROUS
387 | PermissionInfo.PROTECTION_SIGNATURE);
388 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
389 return protectionLevel;
390 }
391 // System sees all flags.
392 final int appId = UserHandle.getAppId(uid);
393 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
394 || appId == Process.SHELL_UID) {
395 return protectionLevel;
396 }
397 // Normalize package name to handle renamed packages and static libs
398 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
399 if (pkg == null) {
400 return protectionLevel;
401 }
402 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
403 return protectionLevelMasked;
404 }
405 // Apps that target O see flags for all protection levels.
406 final PackageSetting ps = (PackageSetting) pkg.mExtras;
407 if (ps == null) {
408 return protectionLevel;
409 }
410 if (ps.getAppId() != appId) {
411 return protectionLevel;
412 }
413 return protectionLevel;
414 }
415
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700416 /**
417 * We might auto-grant permissions if any permission of the group is already granted. Hence if
418 * the group of a granted permission changes we need to revoke it to avoid having permissions of
419 * the new group auto-granted.
420 *
421 * @param newPackage The new package that was installed
422 * @param oldPackage The old package that was updated
423 * @param allPackageNames All package names
424 * @param permissionCallback Callback for permission changed
425 */
426 private void revokeRuntimePermissionsIfGroupChanged(
427 @NonNull PackageParser.Package newPackage,
428 @NonNull PackageParser.Package oldPackage,
429 @NonNull ArrayList<String> allPackageNames,
430 @NonNull PermissionCallback permissionCallback) {
431 final int numOldPackagePermissions = oldPackage.permissions.size();
432 final ArrayMap<String, String> oldPermissionNameToGroupName
433 = new ArrayMap<>(numOldPackagePermissions);
434
435 for (int i = 0; i < numOldPackagePermissions; i++) {
436 final PackageParser.Permission permission = oldPackage.permissions.get(i);
437
438 if (permission.group != null) {
439 oldPermissionNameToGroupName.put(permission.info.name,
440 permission.group.info.name);
441 }
442 }
443
444 final int numNewPackagePermissions = newPackage.permissions.size();
445 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
446 newPermissionNum++) {
447 final PackageParser.Permission newPermission =
448 newPackage.permissions.get(newPermissionNum);
449 final int newProtection = newPermission.info.getProtection();
450
451 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
452 final String permissionName = newPermission.info.name;
453 final String newPermissionGroupName =
454 newPermission.group == null ? null : newPermission.group.info.name;
455 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
456 permissionName);
457
458 if (newPermissionGroupName != null
459 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
460 final int[] userIds = mUserManagerInt.getUserIds();
461 final int numUserIds = userIds.length;
462 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
463 final int userId = userIds[userIdNum];
464
465 final int numPackages = allPackageNames.size();
466 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
467 final String packageName = allPackageNames.get(packageNum);
468
469 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
470 userId) == PackageManager.PERMISSION_GRANTED) {
471 EventLog.writeEvent(0x534e4554, "72710897",
472 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900473 "Revoking permission " + permissionName +
474 " from package " + packageName +
475 " as the group changed from " + oldPermissionGroupName +
476 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700477
478 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000479 revokeRuntimePermission(permissionName, packageName, false,
480 Process.SYSTEM_UID, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700481 } catch (IllegalArgumentException e) {
482 Slog.e(TAG, "Could not revoke " + permissionName + " from "
483 + packageName, e);
484 }
485 }
486 }
487 }
488 }
489 }
490 }
491 }
492
Todd Kennedyc8423932017-10-05 08:58:36 -0700493 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
494 final int N = pkg.permissions.size();
495 for (int i=0; i<N; i++) {
496 PackageParser.Permission p = pkg.permissions.get(i);
497
498 // Assume by default that we did not install this permission into the system.
499 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
500
Todd Kennedyc8423932017-10-05 08:58:36 -0700501 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700502 // Now that permission groups have a special meaning, we ignore permission
503 // groups for legacy apps to prevent unexpected behavior. In particular,
504 // permissions for one app being granted to someone just because they happen
505 // to be in a group defined by another app (before this had no implications).
506 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
507 p.group = mSettings.mPermissionGroups.get(p.info.group);
508 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700509 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700510 && p.info.group != null && p.group == null) {
511 Slog.i(TAG, "Permission " + p.info.name + " from package "
512 + p.info.packageName + " in an unknown group " + p.info.group);
513 }
514 }
515
Todd Kennedyc8423932017-10-05 08:58:36 -0700516 if (p.tree) {
517 final BasePermission bp = BasePermission.createOrUpdate(
518 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
519 mSettings.getAllPermissionTreesLocked(), chatty);
520 mSettings.putPermissionTreeLocked(p.info.name, bp);
521 } else {
522 final BasePermission bp = BasePermission.createOrUpdate(
523 mSettings.getPermissionLocked(p.info.name),
524 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
525 mSettings.putPermissionLocked(p.info.name, bp);
526 }
527 }
528 }
529 }
530
Todd Kennedy460f28c2017-10-06 13:46:22 -0700531 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
532 final int N = pkg.permissionGroups.size();
533 StringBuilder r = null;
534 for (int i=0; i<N; i++) {
535 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
536 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
537 final String curPackageName = (cur == null) ? null : cur.info.packageName;
538 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
539 if (cur == null || isPackageUpdate) {
540 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700541 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700542 if (r == null) {
543 r = new StringBuilder(256);
544 } else {
545 r.append(' ');
546 }
547 if (isPackageUpdate) {
548 r.append("UPD:");
549 }
550 r.append(pg.info.name);
551 }
552 } else {
553 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
554 + pg.info.packageName + " ignored: original from "
555 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700556 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700557 if (r == null) {
558 r = new StringBuilder(256);
559 } else {
560 r.append(' ');
561 }
562 r.append("DUP:");
563 r.append(pg.info.name);
564 }
565 }
566 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700567 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700568 Log.d(TAG, " Permission Groups: " + r);
569 }
570
571 }
572
Hongming Jinae750fb2018-09-27 23:00:20 +0000573 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700574 synchronized (mLock) {
575 int N = pkg.permissions.size();
576 StringBuilder r = null;
577 for (int i=0; i<N; i++) {
578 PackageParser.Permission p = pkg.permissions.get(i);
579 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
580 if (bp == null) {
581 bp = mSettings.mPermissionTrees.get(p.info.name);
582 }
583 if (bp != null && bp.isPermission(p)) {
584 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700585 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700586 if (r == null) {
587 r = new StringBuilder(256);
588 } else {
589 r.append(' ');
590 }
591 r.append(p.info.name);
592 }
593 }
594 if (p.isAppOp()) {
595 ArraySet<String> appOpPkgs =
596 mSettings.mAppOpPermissionPackages.get(p.info.name);
597 if (appOpPkgs != null) {
598 appOpPkgs.remove(pkg.packageName);
599 }
600 }
601 }
602 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700603 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700604 }
605
606 N = pkg.requestedPermissions.size();
607 r = null;
608 for (int i=0; i<N; i++) {
609 String perm = pkg.requestedPermissions.get(i);
610 if (mSettings.isPermissionAppOp(perm)) {
611 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
612 if (appOpPkgs != null) {
613 appOpPkgs.remove(pkg.packageName);
614 if (appOpPkgs.isEmpty()) {
615 mSettings.mAppOpPermissionPackages.remove(perm);
616 }
617 }
618 }
619 }
620 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700621 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700622 }
623 }
624 }
625
626 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700627 PermissionInfo info, int callingUid, PermissionCallback callback) {
628 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
629 throw new SecurityException("Instant apps can't add permissions");
630 }
631 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
632 throw new SecurityException("Label must be specified in permission");
633 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700634 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700635 final boolean added;
636 final boolean changed;
637 synchronized (mLock) {
638 BasePermission bp = mSettings.getPermissionLocked(info.name);
639 added = bp == null;
640 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
641 if (added) {
642 enforcePermissionCapLocked(info, tree);
643 bp = new BasePermission(info.name, tree.getSourcePackageName(),
644 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700645 } else if (!bp.isDynamic()) {
646 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700647 + info.name);
648 }
649 changed = bp.addToTree(fixedLevel, info, tree);
650 if (added) {
651 mSettings.putPermissionLocked(info.name, bp);
652 }
653 }
654 if (changed && callback != null) {
655 callback.onPermissionChanged();
656 }
657 return added;
658 }
659
Todd Kennedyc8423932017-10-05 08:58:36 -0700660 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700661 String permName, int callingUid, PermissionCallback callback) {
662 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
663 throw new SecurityException("Instant applications don't have access to this method");
664 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700665 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700666 synchronized (mLock) {
667 final BasePermission bp = mSettings.getPermissionLocked(permName);
668 if (bp == null) {
669 return;
670 }
671 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600672 // TODO: switch this back to SecurityException
673 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700674 + permName);
675 }
676 mSettings.removePermissionLocked(permName);
677 if (callback != null) {
678 callback.onPermissionRemoved();
679 }
680 }
681 }
682
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700683 /**
684 * Restore the permission state for a package.
685 *
686 * <ul>
687 * <li>During boot the state gets restored from the disk</li>
688 * <li>During app update the state gets restored from the last version of the app</li>
689 * </ul>
690 *
691 * <p>This restores the permission state for all users.
692 *
693 * @param pkg the package the permissions belong to
694 * @param replace if the package is getting replaced (this might change the requested
695 * permissions of this package)
696 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
697 * @param callback Result call back
698 */
699 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
700 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700701 // IMPORTANT: There are two types of permissions: install and runtime.
702 // Install time permissions are granted when the app is installed to
703 // all device users and users added in the future. Runtime permissions
704 // are granted at runtime explicitly to specific users. Normal and signature
705 // protected permissions are install time permissions. Dangerous permissions
706 // are install permissions if the app's target SDK is Lollipop MR1 or older,
707 // otherwise they are runtime permissions. This function does not manage
708 // runtime permissions except for the case an app targeting Lollipop MR1
709 // being upgraded to target a newer SDK, in which case dangerous permissions
710 // are transformed from install time to runtime ones.
711
712 final PackageSetting ps = (PackageSetting) pkg.mExtras;
713 if (ps == null) {
714 return;
715 }
716 final boolean isLegacySystemApp = mPackageManagerInt.isLegacySystemApp(pkg);
717
718 final PermissionsState permissionsState = ps.getPermissionsState();
719 PermissionsState origPermissions = permissionsState;
720
721 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
722
723 boolean runtimePermissionsRevoked = false;
724 int[] updatedUserIds = EMPTY_INT_ARRAY;
725
726 boolean changedInstallPermission = false;
727
728 if (replace) {
729 ps.setInstallPermissionsFixed(false);
730 if (!ps.isSharedUser()) {
731 origPermissions = new PermissionsState(permissionsState);
732 permissionsState.reset();
733 } else {
734 // We need to know only about runtime permission changes since the
735 // calling code always writes the install permissions state but
736 // the runtime ones are written only if changed. The only cases of
737 // changed runtime permissions here are promotion of an install to
738 // runtime and revocation of a runtime from a shared user.
739 synchronized (mLock) {
740 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
741 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
742 if (!ArrayUtils.isEmpty(updatedUserIds)) {
743 runtimePermissionsRevoked = true;
744 }
745 }
746 }
747 }
748
749 permissionsState.setGlobalGids(mGlobalGids);
750
751 synchronized (mLock) {
752 final int N = pkg.requestedPermissions.size();
753 for (int i = 0; i < N; i++) {
754 final String permName = pkg.requestedPermissions.get(i);
755 final BasePermission bp = mSettings.getPermissionLocked(permName);
756 final boolean appSupportsRuntimePermissions =
757 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
758
759 if (DEBUG_INSTALL) {
760 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
761 }
762
763 if (bp == null || bp.getSourcePackageSetting() == null) {
764 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
765 if (DEBUG_PERMISSIONS) {
766 Slog.i(TAG, "Unknown permission " + permName
767 + " in package " + pkg.packageName);
768 }
769 }
770 continue;
771 }
772
773 // Limit ephemeral apps to ephemeral allowed permissions.
774 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
775 if (DEBUG_PERMISSIONS) {
776 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
777 + " for package " + pkg.packageName);
778 }
779 continue;
780 }
781
782 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
783 if (DEBUG_PERMISSIONS) {
784 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
785 + " for package " + pkg.packageName);
786 }
787 continue;
788 }
789
790 final String perm = bp.getName();
791 boolean allowedSig = false;
792 int grant = GRANT_DENIED;
793
794 // Keep track of app op permissions.
795 if (bp.isAppOp()) {
796 mSettings.addAppOpPackage(perm, pkg.packageName);
797 }
798
799 if (bp.isNormal()) {
800 // For all apps normal permissions are install time ones.
801 grant = GRANT_INSTALL;
802 } else if (bp.isRuntime()) {
803 // If a permission review is required for legacy apps we represent
804 // their permissions as always granted runtime ones since we need
805 // to keep the review required permission flag per user while an
806 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700807 if (origPermissions.hasInstallPermission(bp.getName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700808 // For legacy apps that became modern, install becomes runtime.
809 grant = GRANT_UPGRADE;
810 } else if (isLegacySystemApp) {
811 // For legacy system apps, install becomes runtime.
812 // We cannot check hasInstallPermission() for system apps since those
813 // permissions were granted implicitly and not persisted pre-M.
814 grant = GRANT_UPGRADE;
815 } else {
816 // For modern apps keep runtime permissions unchanged.
817 grant = GRANT_RUNTIME;
818 }
819 } else if (bp.isSignature()) {
820 // For all apps signature permissions are install time ones.
821 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
822 if (allowedSig) {
823 grant = GRANT_INSTALL;
824 }
825 }
826
827 if (DEBUG_PERMISSIONS) {
828 Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
829 }
830
831 if (grant != GRANT_DENIED) {
832 if (!ps.isSystem() && ps.areInstallPermissionsFixed()) {
833 // If this is an existing, non-system package, then
834 // we can't add any new permissions to it.
835 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
836 // Except... if this is a permission that was added
837 // to the platform (note: need to only do this when
838 // updating the platform).
839 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
840 grant = GRANT_DENIED;
841 }
842 }
843 }
844
845 switch (grant) {
846 case GRANT_INSTALL: {
847 // Revoke this as runtime permission to handle the case of
848 // a runtime permission being downgraded to an install one.
849 // Also in permission review mode we keep dangerous permissions
850 // for legacy apps
851 for (int userId : UserManagerService.getInstance().getUserIds()) {
852 if (origPermissions.getRuntimePermissionState(
853 perm, userId) != null) {
854 // Revoke the runtime permission and clear the flags.
855 origPermissions.revokeRuntimePermission(bp, userId);
856 origPermissions.updatePermissionFlags(bp, userId,
857 PackageManager.MASK_PERMISSION_FLAGS, 0);
858 // If we revoked a permission permission, we have to write.
859 updatedUserIds = ArrayUtils.appendInt(
860 updatedUserIds, userId);
861 }
862 }
863 // Grant an install permission.
864 if (permissionsState.grantInstallPermission(bp) !=
865 PermissionsState.PERMISSION_OPERATION_FAILURE) {
866 changedInstallPermission = true;
867 }
868 } break;
869
870 case GRANT_RUNTIME: {
871 // Grant previously granted runtime permissions.
872 for (int userId : UserManagerService.getInstance().getUserIds()) {
873 final PermissionState permissionState = origPermissions
874 .getRuntimePermissionState(perm, userId);
875 int flags = permissionState != null
876 ? permissionState.getFlags() : 0;
877 if (origPermissions.hasRuntimePermission(perm, userId)) {
878 // Don't propagate the permission in a permission review
879 // mode if the former was revoked, i.e. marked to not
880 // propagate on upgrade. Note that in a permission review
881 // mode install permissions are represented as constantly
882 // granted runtime ones since we need to keep a per user
883 // state associated with the permission. Also the revoke
884 // on upgrade flag is no longer applicable and is reset.
885 final boolean revokeOnUpgrade = (flags & PackageManager
886 .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
887 if (revokeOnUpgrade) {
888 flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
889 // Since we changed the flags, we have to write.
890 updatedUserIds = ArrayUtils.appendInt(
891 updatedUserIds, userId);
892 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700893 if (!revokeOnUpgrade) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700894 if (permissionsState.grantRuntimePermission(bp, userId) ==
895 PermissionsState.PERMISSION_OPERATION_FAILURE) {
896 // If we cannot put the permission as it was,
897 // we have to write.
898 updatedUserIds = ArrayUtils.appendInt(
899 updatedUserIds, userId);
900 }
901 }
902
903 // If the app supports runtime permissions no need for a review.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700904 if (appSupportsRuntimePermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700905 && (flags & PackageManager
906 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
907 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
908 // Since we changed the flags, we have to write.
909 updatedUserIds = ArrayUtils.appendInt(
910 updatedUserIds, userId);
911 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700912 } else if (!appSupportsRuntimePermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700913 // For legacy apps that need a permission review, every new
914 // runtime permission is granted but it is pending a review.
915 // We also need to review only platform defined runtime
916 // permissions as these are the only ones the platform knows
917 // how to disable the API to simulate revocation as legacy
918 // apps don't expect to run with revoked permissions.
919 if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
920 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
921 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
922 // We changed the flags, hence have to write.
923 updatedUserIds = ArrayUtils.appendInt(
924 updatedUserIds, userId);
925 }
926 }
927 if (permissionsState.grantRuntimePermission(bp, userId)
928 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
929 // We changed the permission, hence have to write.
930 updatedUserIds = ArrayUtils.appendInt(
931 updatedUserIds, userId);
932 }
933 }
934 // Propagate the permission flags.
935 permissionsState.updatePermissionFlags(bp, userId, flags, flags);
936 }
937 } break;
938
939 case GRANT_UPGRADE: {
940 // Grant runtime permissions for a previously held install permission.
941 final PermissionState permissionState = origPermissions
942 .getInstallPermissionState(perm);
943 final int flags =
944 (permissionState != null) ? permissionState.getFlags() : 0;
945
946 if (origPermissions.revokeInstallPermission(bp)
947 != PermissionsState.PERMISSION_OPERATION_FAILURE) {
948 // We will be transferring the permission flags, so clear them.
949 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
950 PackageManager.MASK_PERMISSION_FLAGS, 0);
951 changedInstallPermission = true;
952 }
953
954 // If the permission is not to be promoted to runtime we ignore it and
955 // also its other flags as they are not applicable to install permissions.
956 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
957 for (int userId : currentUserIds) {
958 if (permissionsState.grantRuntimePermission(bp, userId) !=
959 PermissionsState.PERMISSION_OPERATION_FAILURE) {
960 // Transfer the permission flags.
961 permissionsState.updatePermissionFlags(bp, userId,
962 flags, flags);
963 // If we granted the permission, we have to write.
964 updatedUserIds = ArrayUtils.appendInt(
965 updatedUserIds, userId);
966 }
967 }
968 }
969 } break;
970
971 default: {
972 if (packageOfInterest == null
973 || packageOfInterest.equals(pkg.packageName)) {
974 if (DEBUG_PERMISSIONS) {
975 Slog.i(TAG, "Not granting permission " + perm
976 + " to package " + pkg.packageName
977 + " because it was previously installed without");
978 }
979 }
980 } break;
981 }
982 } else {
983 if (permissionsState.revokeInstallPermission(bp) !=
984 PermissionsState.PERMISSION_OPERATION_FAILURE) {
985 // Also drop the permission flags.
986 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
987 PackageManager.MASK_PERMISSION_FLAGS, 0);
988 changedInstallPermission = true;
989 Slog.i(TAG, "Un-granting permission " + perm
990 + " from package " + pkg.packageName
991 + " (protectionLevel=" + bp.getProtectionLevel()
992 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
993 + ")");
994 } else if (bp.isAppOp()) {
995 // Don't print warning for app op permissions, since it is fine for them
996 // not to be granted, there is a UI for the user to decide.
997 if (DEBUG_PERMISSIONS
998 && (packageOfInterest == null
999 || packageOfInterest.equals(pkg.packageName))) {
1000 Slog.i(TAG, "Not granting permission " + perm
1001 + " to package " + pkg.packageName
1002 + " (protectionLevel=" + bp.getProtectionLevel()
1003 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1004 + ")");
1005 }
1006 }
1007 }
1008 }
1009
1010 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1011 !ps.isSystem() || ps.isUpdatedSystem()) {
1012 // This is the first that we have heard about this package, so the
1013 // permissions we have now selected are fixed until explicitly
1014 // changed.
1015 ps.setInstallPermissionsFixed(true);
1016 }
1017 }
1018
1019 // Persist the runtime permissions state for users with changes. If permissions
1020 // were revoked because no app in the shared user declares them we have to
1021 // write synchronously to avoid losing runtime permissions state.
1022 if (callback != null) {
1023 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1024 }
1025 }
1026
1027 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1028 boolean allowed = false;
1029 final int NP = PackageParser.NEW_PERMISSIONS.length;
1030 for (int ip=0; ip<NP; ip++) {
1031 final PackageParser.NewPermissionInfo npi
1032 = PackageParser.NEW_PERMISSIONS[ip];
1033 if (npi.name.equals(perm)
1034 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1035 allowed = true;
1036 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1037 + pkg.packageName);
1038 break;
1039 }
1040 }
1041 return allowed;
1042 }
1043
1044 /**
1045 * Determines whether a package is whitelisted for a particular privapp permission.
1046 *
1047 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1048 *
1049 * <p>This handles parent/child apps.
1050 */
1051 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001052 ArraySet<String> wlPermissions = null;
1053 if (pkg.isVendor()) {
1054 wlPermissions =
1055 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1056 } else if (pkg.isProduct()) {
1057 wlPermissions =
1058 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001059 } else if (pkg.isProductServices()) {
1060 wlPermissions =
1061 SystemConfig.getInstance().getProductServicesPrivAppPermissions(
1062 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001063 } else {
1064 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1065 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001066 // Let's check if this package is whitelisted...
1067 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1068 // If it's not, we'll also tail-recurse to the parent.
1069 return whitelisted ||
1070 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1071 }
1072
1073 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1074 BasePermission bp, PermissionsState origPermissions) {
1075 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001076 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1077 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001078 boolean privappPermissionsDisable =
1079 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1080 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1081 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1082 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1083 && !platformPackage && platformPermission) {
1084 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001085 // Only report violations for apps on system image
1086 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1087 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001088 ArraySet<String> deniedPermissions = null;
1089 if (pkg.isVendor()) {
1090 deniedPermissions = SystemConfig.getInstance()
1091 .getVendorPrivAppDenyPermissions(pkg.packageName);
1092 } else if (pkg.isProduct()) {
1093 deniedPermissions = SystemConfig.getInstance()
1094 .getProductPrivAppDenyPermissions(pkg.packageName);
Dario Freni2bef1762018-06-01 14:02:08 +01001095 } else if (pkg.isProductServices()) {
1096 deniedPermissions = SystemConfig.getInstance()
1097 .getProductServicesPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001098 } else {
1099 deniedPermissions = SystemConfig.getInstance()
1100 .getPrivAppDenyPermissions(pkg.packageName);
1101 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001102 final boolean permissionViolation =
1103 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001104 if (permissionViolation) {
1105 Slog.w(TAG, "Privileged permission " + perm + " for package "
1106 + pkg.packageName + " - not in privapp-permissions whitelist");
1107
1108 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1109 if (mPrivappPermissionsViolations == null) {
1110 mPrivappPermissionsViolations = new ArraySet<>();
1111 }
1112 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001113 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001114 } else {
1115 return false;
1116 }
1117 }
1118 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1119 return false;
1120 }
1121 }
1122 }
1123 final String systemPackageName = mPackageManagerInt.getKnownPackageName(
1124 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
1125 final PackageParser.Package systemPackage =
1126 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001127
1128 // check if the package is allow to use this signature permission. A package is allowed to
1129 // use a signature permission if:
1130 // - it has the same set of signing certificates as the source package
1131 // - or its signing certificate was rotated from the source package's certificate
1132 // - or its signing certificate is a previous signing certificate of the defining
1133 // package, and the defining package still trusts the old certificate for permissions
1134 // - or it shares the above relationships with the system package
1135 boolean allowed =
1136 pkg.mSigningDetails.hasAncestorOrSelf(
1137 bp.getSourcePackageSetting().getSigningDetails())
1138 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1139 pkg.mSigningDetails,
1140 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1141 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1142 || systemPackage.mSigningDetails.checkCapability(
1143 pkg.mSigningDetails,
1144 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001145 if (!allowed && (privilegedPermission || oemPermission)) {
1146 if (pkg.isSystem()) {
1147 // For updated system applications, a privileged/oem permission
1148 // is granted only if it had been defined by the original application.
1149 if (pkg.isUpdatedSystemApp()) {
1150 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001151 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001152 final PackageSetting disabledPs =
1153 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1154 if (disabledPs != null
1155 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1156 // If the original was granted this permission, we take
1157 // that grant decision as read and propagate it to the
1158 // update.
1159 if ((privilegedPermission && disabledPs.isPrivileged())
1160 || (oemPermission && disabledPs.isOem()
1161 && canGrantOemPermission(disabledPs, perm))) {
1162 allowed = true;
1163 }
1164 } else {
1165 // The system apk may have been updated with an older
1166 // version of the one on the data partition, but which
1167 // granted a new system permission that it didn't have
1168 // before. In this case we do want to allow the app to
1169 // now get the new permission if the ancestral apk is
1170 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001171 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001172 && isPackageRequestingPermission(disabledPkg, perm)
1173 && ((privilegedPermission && disabledPs.isPrivileged())
1174 || (oemPermission && disabledPs.isOem()
1175 && canGrantOemPermission(disabledPs, perm)))) {
1176 allowed = true;
1177 }
1178 // Also if a privileged parent package on the system image or any of
1179 // its children requested a privileged/oem permission, the updated child
1180 // packages can also get the permission.
1181 if (pkg.parentPackage != null) {
1182 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001183 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001184 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1185 ? (PackageSetting) disabledParentPkg.mExtras : null;
1186 if (disabledParentPkg != null
1187 && ((privilegedPermission && disabledParentPs.isPrivileged())
1188 || (oemPermission && disabledParentPs.isOem()))) {
1189 if (isPackageRequestingPermission(disabledParentPkg, perm)
1190 && canGrantOemPermission(disabledParentPs, perm)) {
1191 allowed = true;
1192 } else if (disabledParentPkg.childPackages != null) {
1193 for (PackageParser.Package disabledChildPkg
1194 : disabledParentPkg.childPackages) {
1195 final PackageSetting disabledChildPs =
1196 (disabledChildPkg != null)
1197 ? (PackageSetting) disabledChildPkg.mExtras
1198 : null;
1199 if (isPackageRequestingPermission(disabledChildPkg, perm)
1200 && canGrantOemPermission(
1201 disabledChildPs, perm)) {
1202 allowed = true;
1203 break;
1204 }
1205 }
1206 }
1207 }
1208 }
1209 }
1210 } else {
1211 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1212 allowed = (privilegedPermission && pkg.isPrivileged())
1213 || (oemPermission && pkg.isOem()
1214 && canGrantOemPermission(ps, perm));
1215 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001216 // In any case, don't grant a privileged permission to privileged vendor apps, if
1217 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1218 // flag.
1219 if (allowed && privilegedPermission &&
1220 !vendorPrivilegedPermission && pkg.isVendor()) {
1221 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1222 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1223 allowed = false;
1224 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001225 }
1226 }
1227 if (!allowed) {
1228 if (!allowed
1229 && bp.isPre23()
1230 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1231 // If this was a previously normal/dangerous permission that got moved
1232 // to a system permission as part of the runtime permission redesign, then
1233 // we still want to blindly grant it to old apps.
1234 allowed = true;
1235 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001236 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1237 // need a separate flag anymore. Hence we need to check which
1238 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001239 if (!allowed && bp.isInstaller()
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001240 && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1241 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
1242 || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1243 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
1244 UserHandle.USER_SYSTEM)))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001245 // If this permission is to be granted to the system installer and
1246 // this app is an installer, then it gets the permission.
1247 allowed = true;
1248 }
1249 if (!allowed && bp.isVerifier()
1250 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1251 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
1252 // If this permission is to be granted to the system verifier and
1253 // this app is a verifier, then it gets the permission.
1254 allowed = true;
1255 }
1256 if (!allowed && bp.isPreInstalled()
1257 && pkg.isSystem()) {
1258 // Any pre-installed system app is allowed to get this permission.
1259 allowed = true;
1260 }
1261 if (!allowed && bp.isDevelopment()) {
1262 // For development permissions, a development permission
1263 // is granted only if it was already granted.
1264 allowed = origPermissions.hasInstallPermission(perm);
1265 }
1266 if (!allowed && bp.isSetup()
1267 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1268 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
1269 // If this permission is to be granted to the system setup wizard and
1270 // this app is a setup wizard, then it gets the permission.
1271 allowed = true;
1272 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001273 if (!allowed && bp.isSystemTextClassifier()
1274 && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
1275 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
1276 UserHandle.USER_SYSTEM))) {
1277 // Special permissions for the system default text classifier.
1278 allowed = true;
1279 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001280 }
1281 return allowed;
1282 }
1283
1284 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1285 if (!ps.isOem()) {
1286 return false;
1287 }
1288 // all oem permissions must explicitly be granted or denied
1289 final Boolean granted =
1290 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1291 if (granted == null) {
1292 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1293 + ps.name + " must be explicitly declared granted or not");
1294 }
1295 return Boolean.TRUE == granted;
1296 }
1297
1298 private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001299 // Permission review applies only to apps not supporting the new permission model.
1300 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1301 return false;
1302 }
1303
1304 // Legacy apps have the permission and get user consent on launch.
1305 if (pkg == null || pkg.mExtras == null) {
1306 return false;
1307 }
1308 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1309 final PermissionsState permissionsState = ps.getPermissionsState();
1310 return permissionsState.isPermissionReviewRequired(userId);
1311 }
1312
1313 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1314 final int permCount = pkg.requestedPermissions.size();
1315 for (int j = 0; j < permCount; j++) {
1316 String requestedPermission = pkg.requestedPermissions.get(j);
1317 if (permission.equals(requestedPermission)) {
1318 return true;
1319 }
1320 }
1321 return false;
1322 }
1323
Andreas Gampea36dc622018-02-05 17:19:22 -08001324 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001325 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1326 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1327 if (pkg.parentPackage == null) {
1328 return;
1329 }
1330 if (pkg.requestedPermissions == null) {
1331 return;
1332 }
1333 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001334 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001335 if (disabledPkg == null || disabledPkg.mExtras == null) {
1336 return;
1337 }
1338 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1339 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1340 return;
1341 }
1342 final int permCount = pkg.requestedPermissions.size();
1343 for (int i = 0; i < permCount; i++) {
1344 String permission = pkg.requestedPermissions.get(i);
1345 BasePermission bp = mSettings.getPermissionLocked(permission);
1346 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1347 continue;
1348 }
1349 for (int userId : mUserManagerInt.getUserIds()) {
1350 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1351 grantRuntimePermission(
1352 permission, pkg.packageName, false, callingUid, userId, callback);
1353 }
1354 }
1355 }
1356 }
1357
1358 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1359 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1360 for (int userId : userIds) {
1361 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1362 callback);
1363 }
1364 }
1365
1366 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
1367 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1368 PackageSetting ps = (PackageSetting) pkg.mExtras;
1369 if (ps == null) {
1370 return;
1371 }
1372
1373 PermissionsState permissionsState = ps.getPermissionsState();
1374
1375 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1376 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
1377
1378 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1379 >= Build.VERSION_CODES.M;
1380
1381 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
1382
1383 for (String permission : pkg.requestedPermissions) {
1384 final BasePermission bp;
1385 synchronized (mLock) {
1386 bp = mSettings.getPermissionLocked(permission);
1387 }
1388 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
1389 && (!instantApp || bp.isInstant())
1390 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
1391 && (grantedPermissions == null
1392 || ArrayUtils.contains(grantedPermissions, permission))) {
1393 final int flags = permissionsState.getPermissionFlags(permission, userId);
1394 if (supportsRuntimePermissions) {
1395 // Installer cannot change immutable permissions.
1396 if ((flags & immutableFlags) == 0) {
1397 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
1398 userId, callback);
1399 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001400 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001401 // In permission review mode we clear the review flag when we
1402 // are asked to install the app with all permissions granted.
1403 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1404 updatePermissionFlags(permission, pkg.packageName,
1405 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
1406 userId, callback);
1407 }
1408 }
1409 }
1410 }
1411 }
1412
1413 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
1414 int callingUid, final int userId, PermissionCallback callback) {
1415 if (!mUserManagerInt.exists(userId)) {
1416 Log.e(TAG, "No such user:" + userId);
1417 return;
1418 }
1419
1420 mContext.enforceCallingOrSelfPermission(
1421 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1422 "grantRuntimePermission");
1423
1424 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001425 true, // requireFullPermission
1426 true, // checkShell
1427 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001428 "grantRuntimePermission");
1429
1430 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1431 if (pkg == null || pkg.mExtras == null) {
1432 throw new IllegalArgumentException("Unknown package: " + packageName);
1433 }
1434 final BasePermission bp;
1435 synchronized(mLock) {
1436 bp = mSettings.getPermissionLocked(permName);
1437 }
1438 if (bp == null) {
1439 throw new IllegalArgumentException("Unknown permission: " + permName);
1440 }
1441 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1442 throw new IllegalArgumentException("Unknown package: " + packageName);
1443 }
1444
1445 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1446
1447 // If a permission review is required for legacy apps we represent
1448 // their permissions as always granted runtime ones since we need
1449 // to keep the review required permission flag per user while an
1450 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001451 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001452 && bp.isRuntime()) {
1453 return;
1454 }
1455
1456 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1457
1458 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1459 final PermissionsState permissionsState = ps.getPermissionsState();
1460
1461 final int flags = permissionsState.getPermissionFlags(permName, userId);
1462 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1463 throw new SecurityException("Cannot grant system fixed permission "
1464 + permName + " for package " + packageName);
1465 }
1466 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1467 throw new SecurityException("Cannot grant policy fixed permission "
1468 + permName + " for package " + packageName);
1469 }
1470
1471 if (bp.isDevelopment()) {
1472 // Development permissions must be handled specially, since they are not
1473 // normal runtime permissions. For now they apply to all users.
1474 if (permissionsState.grantInstallPermission(bp) !=
1475 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1476 if (callback != null) {
1477 callback.onInstallPermissionGranted();
1478 }
1479 }
1480 return;
1481 }
1482
1483 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1484 throw new SecurityException("Cannot grant non-ephemeral permission"
1485 + permName + " for package " + packageName);
1486 }
1487
1488 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1489 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1490 return;
1491 }
1492
1493 final int result = permissionsState.grantRuntimePermission(bp, userId);
1494 switch (result) {
1495 case PermissionsState.PERMISSION_OPERATION_FAILURE: {
1496 return;
1497 }
1498
1499 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1500 if (callback != null) {
1501 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
1502 }
1503 }
1504 break;
1505 }
1506
1507 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001508 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001509 }
1510
1511 if (callback != null) {
1512 callback.onPermissionGranted(uid, userId);
1513 }
1514
1515 // Only need to do this if user is initialized. Otherwise it's a new user
1516 // and there are no processes running as the user yet and there's no need
1517 // to make an expensive call to remount processes for the changed permissions.
1518 if (READ_EXTERNAL_STORAGE.equals(permName)
1519 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1520 final long token = Binder.clearCallingIdentity();
1521 try {
1522 if (mUserManagerInt.isUserInitialized(userId)) {
1523 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1524 StorageManagerInternal.class);
1525 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1526 }
1527 } finally {
1528 Binder.restoreCallingIdentity(token);
1529 }
1530 }
1531
1532 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001533
1534 private void revokeRuntimePermission(String permName, String packageName,
1535 boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001536 if (!mUserManagerInt.exists(userId)) {
1537 Log.e(TAG, "No such user:" + userId);
1538 return;
1539 }
1540
1541 mContext.enforceCallingOrSelfPermission(
1542 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1543 "revokeRuntimePermission");
1544
1545 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001546 true, // requireFullPermission
1547 true, // checkShell
1548 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001549 "revokeRuntimePermission");
1550
1551 final int appId;
1552
1553 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1554 if (pkg == null || pkg.mExtras == null) {
1555 throw new IllegalArgumentException("Unknown package: " + packageName);
1556 }
1557 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
1558 throw new IllegalArgumentException("Unknown package: " + packageName);
1559 }
Hongming Jinae750fb2018-09-27 23:00:20 +00001560 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001561 if (bp == null) {
1562 throw new IllegalArgumentException("Unknown permission: " + permName);
1563 }
1564
1565 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
1566
1567 // If a permission review is required for legacy apps we represent
1568 // their permissions as always granted runtime ones since we need
1569 // to keep the review required permission flag per user while an
1570 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07001571 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07001572 && bp.isRuntime()) {
1573 return;
1574 }
1575
1576 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1577 final PermissionsState permissionsState = ps.getPermissionsState();
1578
1579 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07001580 // Only the system may revoke SYSTEM_FIXED permissions.
1581 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1582 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1583 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07001584 + permName + " for package " + packageName);
1585 }
1586 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1587 throw new SecurityException("Cannot revoke policy fixed permission "
1588 + permName + " for package " + packageName);
1589 }
1590
1591 if (bp.isDevelopment()) {
1592 // Development permissions must be handled specially, since they are not
1593 // normal runtime permissions. For now they apply to all users.
1594 if (permissionsState.revokeInstallPermission(bp) !=
1595 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1596 if (callback != null) {
1597 callback.onInstallPermissionRevoked();
1598 }
1599 }
1600 return;
1601 }
1602
1603 if (permissionsState.revokeRuntimePermission(bp, userId) ==
1604 PermissionsState.PERMISSION_OPERATION_FAILURE) {
1605 return;
1606 }
1607
1608 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07001609 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001610 }
1611
1612 if (callback != null) {
1613 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
1614 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
1615 }
1616 }
1617
Andreas Gampea36dc622018-02-05 17:19:22 -08001618 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001619 private int[] revokeUnusedSharedUserPermissionsLocked(
1620 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001621 // Collect all used permissions in the UID
1622 final ArraySet<String> usedPermissions = new ArraySet<>();
1623 final List<PackageParser.Package> pkgList = suSetting.getPackages();
1624 if (pkgList == null || pkgList.size() == 0) {
1625 return EmptyArray.INT;
1626 }
1627 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07001628 if (pkg.requestedPermissions == null) {
1629 continue;
1630 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07001631 final int requestedPermCount = pkg.requestedPermissions.size();
1632 for (int j = 0; j < requestedPermCount; j++) {
1633 String permission = pkg.requestedPermissions.get(j);
1634 BasePermission bp = mSettings.getPermissionLocked(permission);
1635 if (bp != null) {
1636 usedPermissions.add(permission);
1637 }
1638 }
1639 }
1640
1641 PermissionsState permissionsState = suSetting.getPermissionsState();
1642 // Prune install permissions
1643 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
1644 final int installPermCount = installPermStates.size();
1645 for (int i = installPermCount - 1; i >= 0; i--) {
1646 PermissionState permissionState = installPermStates.get(i);
1647 if (!usedPermissions.contains(permissionState.getName())) {
1648 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1649 if (bp != null) {
1650 permissionsState.revokeInstallPermission(bp);
1651 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
1652 PackageManager.MASK_PERMISSION_FLAGS, 0);
1653 }
1654 }
1655 }
1656
1657 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
1658
1659 // Prune runtime permissions
1660 for (int userId : allUserIds) {
1661 List<PermissionState> runtimePermStates = permissionsState
1662 .getRuntimePermissionStates(userId);
1663 final int runtimePermCount = runtimePermStates.size();
1664 for (int i = runtimePermCount - 1; i >= 0; i--) {
1665 PermissionState permissionState = runtimePermStates.get(i);
1666 if (!usedPermissions.contains(permissionState.getName())) {
1667 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
1668 if (bp != null) {
1669 permissionsState.revokeRuntimePermission(bp, userId);
1670 permissionsState.updatePermissionFlags(bp, userId,
1671 PackageManager.MASK_PERMISSION_FLAGS, 0);
1672 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
1673 runtimePermissionChangedUserIds, userId);
1674 }
1675 }
1676 }
1677 }
1678
1679 return runtimePermissionChangedUserIds;
1680 }
1681
Todd Kennedyc8423932017-10-05 08:58:36 -07001682 private String[] getAppOpPermissionPackages(String permName) {
1683 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1684 return null;
1685 }
1686 synchronized (mLock) {
1687 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
1688 if (pkgs == null) {
1689 return null;
1690 }
1691 return pkgs.toArray(new String[pkgs.size()]);
1692 }
1693 }
1694
1695 private int getPermissionFlags(
1696 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001697 if (!mUserManagerInt.exists(userId)) {
1698 return 0;
1699 }
1700
1701 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
1702
1703 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001704 true, // requireFullPermission
1705 false, // checkShell
1706 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001707 "getPermissionFlags");
1708
1709 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1710 if (pkg == null || pkg.mExtras == null) {
1711 return 0;
1712 }
1713 synchronized (mLock) {
1714 if (mSettings.getPermissionLocked(permName) == null) {
1715 return 0;
1716 }
1717 }
1718 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1719 return 0;
1720 }
1721 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1722 PermissionsState permissionsState = ps.getPermissionsState();
1723 return permissionsState.getPermissionFlags(permName, userId);
1724 }
1725
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001726 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
1727 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
1728 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
1729
1730 private void updatePermissions(String packageName, PackageParser.Package pkg,
1731 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
1732 PermissionCallback callback) {
1733 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
1734 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
1735 updatePermissions(
1736 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
1737 if (pkg != null && pkg.childPackages != null) {
1738 for (PackageParser.Package childPkg : pkg.childPackages) {
1739 updatePermissions(childPkg.packageName, childPkg,
1740 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
1741 }
1742 }
1743 }
1744
1745 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
1746 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
1747 final int flags = UPDATE_PERMISSIONS_ALL |
1748 (sdkUpdated
1749 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
1750 : 0);
1751 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
1752 }
1753
1754 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
1755 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
1756 PermissionCallback callback) {
1757 // TODO: Most of the methods exposing BasePermission internals [source package name,
1758 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
1759 // have package settings, we should make note of it elsewhere [map between
1760 // source package name and BasePermission] and cycle through that here. Then we
1761 // define a single method on BasePermission that takes a PackageSetting, changing
1762 // package name and a package.
1763 // NOTE: With this approach, we also don't need to tree trees differently than
1764 // normal permissions. Today, we need two separate loops because these BasePermission
1765 // objects are stored separately.
1766 // Make sure there are no dangling permission trees.
1767 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
1768
1769 // Make sure all dynamic permissions have been assigned to a package,
1770 // and make sure there are no dangling permissions.
1771 flags = updatePermissions(changingPkgName, changingPkg, flags);
1772
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07001773 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001774 // Now update the permissions for all packages, in particular
1775 // replace the granted permissions of the system packages.
1776 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
1777 for (PackageParser.Package pkg : allPackages) {
1778 if (pkg != changingPkg) {
1779 // Only replace for packages on requested volume
1780 final String volumeUuid = getVolumeUuidForPackage(pkg);
1781 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
1782 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07001783 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001784 }
1785 }
1786 }
1787
1788 if (changingPkg != null) {
1789 // Only replace for packages on requested volume
1790 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
1791 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
1792 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07001793 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001794 }
1795 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1796 }
1797
1798 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001799 Set<BasePermission> needsUpdate = null;
1800 synchronized (mLock) {
1801 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
1802 while (it.hasNext()) {
1803 final BasePermission bp = it.next();
1804 if (bp.isDynamic()) {
1805 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
1806 }
1807 if (bp.getSourcePackageSetting() != null) {
1808 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001809 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001810 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1811 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001812 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001813 it.remove();
1814 }
1815 continue;
1816 }
1817 if (needsUpdate == null) {
1818 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
1819 }
1820 needsUpdate.add(bp);
1821 }
1822 }
1823 if (needsUpdate != null) {
1824 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001825 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001826 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1827 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001828 if (sourcePkg != null && sourcePkg.mExtras != null) {
1829 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001830 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001831 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001832 }
1833 continue;
1834 }
1835 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
1836 + " from package " + bp.getSourcePackageName());
1837 mSettings.removePermissionLocked(bp.getName());
1838 }
1839 }
1840 }
1841 return flags;
1842 }
1843
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001844 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07001845 int flags) {
1846 Set<BasePermission> needsUpdate = null;
1847 synchronized (mLock) {
1848 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
1849 while (it.hasNext()) {
1850 final BasePermission bp = it.next();
1851 if (bp.getSourcePackageSetting() != null) {
1852 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001853 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07001854 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
1855 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001856 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07001857 it.remove();
1858 }
1859 continue;
1860 }
1861 if (needsUpdate == null) {
1862 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
1863 }
1864 needsUpdate.add(bp);
1865 }
1866 }
1867 if (needsUpdate != null) {
1868 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001869 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07001870 mPackageManagerInt.getPackage(bp.getSourcePackageName());
1871 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001872 if (sourcePkg != null && sourcePkg.mExtras != null) {
1873 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07001874 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001875 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07001876 }
1877 continue;
1878 }
1879 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
1880 + " from package " + bp.getSourcePackageName());
1881 mSettings.removePermissionLocked(bp.getName());
1882 }
1883 }
1884 }
1885 return flags;
1886 }
1887
Todd Kennedy0eb97382017-10-03 16:57:22 -07001888 private void updatePermissionFlags(String permName, String packageName, int flagMask,
1889 int flagValues, int callingUid, int userId, PermissionCallback callback) {
1890 if (!mUserManagerInt.exists(userId)) {
1891 return;
1892 }
1893
1894 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
1895
1896 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001897 true, // requireFullPermission
1898 true, // checkShell
1899 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001900 "updatePermissionFlags");
1901
1902 // Only the system can change these flags and nothing else.
1903 if (callingUid != Process.SYSTEM_UID) {
1904 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1905 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1906 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1907 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1908 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
1909 }
1910
1911 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
1912 if (pkg == null || pkg.mExtras == null) {
1913 throw new IllegalArgumentException("Unknown package: " + packageName);
1914 }
1915 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1916 throw new IllegalArgumentException("Unknown package: " + packageName);
1917 }
1918
1919 final BasePermission bp;
1920 synchronized (mLock) {
1921 bp = mSettings.getPermissionLocked(permName);
1922 }
1923 if (bp == null) {
1924 throw new IllegalArgumentException("Unknown permission: " + permName);
1925 }
1926
1927 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1928 final PermissionsState permissionsState = ps.getPermissionsState();
1929 final boolean hadState =
1930 permissionsState.getRuntimePermissionState(permName, userId) != null;
1931 final boolean permissionUpdated =
1932 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
1933 if (permissionUpdated && callback != null) {
1934 // Install and runtime permissions are stored in different places,
1935 // so figure out what permission changed and persist the change.
1936 if (permissionsState.getInstallPermissionState(permName) != null) {
1937 callback.onInstallPermissionUpdated();
1938 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
1939 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001940 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001941 }
1942 }
1943 }
1944
1945 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
1946 int userId, Collection<Package> packages, PermissionCallback callback) {
1947 if (!mUserManagerInt.exists(userId)) {
1948 return false;
1949 }
1950
1951 enforceGrantRevokeRuntimePermissionPermissions(
1952 "updatePermissionFlagsForAllApps");
1953 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001954 true, // requireFullPermission
1955 true, // checkShell
1956 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07001957 "updatePermissionFlagsForAllApps");
1958
1959 // Only the system can change system fixed flags.
1960 if (callingUid != Process.SYSTEM_UID) {
1961 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1962 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
1963 }
1964
1965 boolean changed = false;
1966 for (PackageParser.Package pkg : packages) {
1967 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1968 if (ps == null) {
1969 continue;
1970 }
1971 PermissionsState permissionsState = ps.getPermissionsState();
1972 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
1973 userId, flagMask, flagValues);
1974 }
1975 return changed;
1976 }
1977
1978 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
1979 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
1980 != PackageManager.PERMISSION_GRANTED
1981 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
1982 != PackageManager.PERMISSION_GRANTED) {
1983 throw new SecurityException(message + " requires "
1984 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
1985 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
1986 }
1987 }
1988
1989 /**
1990 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
1991 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
1992 * @param checkShell whether to prevent shell from access if there's a debugging restriction
1993 * @param message the message to log on security exception
1994 */
1995 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07001996 boolean requireFullPermission, boolean checkShell,
1997 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07001998 if (userId < 0) {
1999 throw new IllegalArgumentException("Invalid userId " + userId);
2000 }
2001 if (checkShell) {
2002 PackageManagerServiceUtils.enforceShellRestriction(
2003 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2004 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002005 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002006 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002007 if (requireFullPermission) {
2008 mContext.enforceCallingOrSelfPermission(
2009 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2010 } else {
2011 try {
2012 mContext.enforceCallingOrSelfPermission(
2013 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2014 } catch (SecurityException se) {
2015 mContext.enforceCallingOrSelfPermission(
2016 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2017 }
2018 }
2019 }
2020 }
2021
Andreas Gampea71bee82018-07-20 12:55:36 -07002022 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002023 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2024 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002025 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002026 size += tree.calculateFootprint(perm);
2027 }
2028 return size;
2029 }
2030
Andreas Gampea71bee82018-07-20 12:55:36 -07002031 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002032 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2033 // We calculate the max size of permissions defined by this uid and throw
2034 // if that plus the size of 'info' would exceed our stated maximum.
2035 if (tree.getUid() != Process.SYSTEM_UID) {
2036 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2037 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2038 throw new SecurityException("Permission tree size cap exceeded");
2039 }
2040 }
2041 }
2042
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002043 private void systemReady() {
2044 mSystemReady = true;
2045 if (mPrivappPermissionsViolations != null) {
2046 throw new IllegalStateException("Signature|privileged permissions not in "
2047 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2048 }
2049 }
2050
2051 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2052 if (pkg == null) {
2053 return StorageManager.UUID_PRIVATE_INTERNAL;
2054 }
2055 if (pkg.isExternal()) {
2056 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2057 return StorageManager.UUID_PRIMARY_PHYSICAL;
2058 } else {
2059 return pkg.volumeUuid;
2060 }
2061 } else {
2062 return StorageManager.UUID_PRIVATE_INTERNAL;
2063 }
2064 }
2065
Todd Kennedyc8423932017-10-05 08:58:36 -07002066 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2067 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2068 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2069 return true;
2070 }
2071 }
2072 return false;
2073 }
2074
Todd Kennedy0eb97382017-10-03 16:57:22 -07002075 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002076 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002077 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002078 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002079 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002080 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002081 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002082 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2083 final LogMaker log = new LogMaker(action);
2084 log.setPackageName(packageName);
2085 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002086
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002087 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002088 }
2089
2090 private class PermissionManagerInternalImpl extends PermissionManagerInternal {
2091 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002092 public void systemReady() {
2093 PermissionManagerService.this.systemReady();
2094 }
2095 @Override
2096 public boolean isPermissionsReviewRequired(Package pkg, int userId) {
2097 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2098 }
2099 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002100 public void revokeRuntimePermissionsIfGroupChanged(
2101 @NonNull PackageParser.Package newPackage,
2102 @NonNull PackageParser.Package oldPackage,
2103 @NonNull ArrayList<String> allPackageNames,
2104 @NonNull PermissionCallback permissionCallback) {
2105 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
2106 oldPackage, allPackageNames, permissionCallback);
2107 }
2108 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002109 public void addAllPermissions(Package pkg, boolean chatty) {
2110 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002111 }
2112 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002113 public void addAllPermissionGroups(Package pkg, boolean chatty) {
2114 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
2115 }
2116 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00002117 public void removeAllPermissions(Package pkg, boolean chatty) {
2118 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07002119 }
2120 @Override
2121 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07002122 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002123 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
2124 }
2125 @Override
2126 public void removeDynamicPermission(String permName, int callingUid,
2127 PermissionCallback callback) {
2128 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002129 }
2130 @Override
2131 public void grantRuntimePermission(String permName, String packageName,
2132 boolean overridePolicy, int callingUid, int userId,
2133 PermissionCallback callback) {
2134 PermissionManagerService.this.grantRuntimePermission(
2135 permName, packageName, overridePolicy, callingUid, userId, callback);
2136 }
2137 @Override
2138 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2139 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2140 PermissionManagerService.this.grantRequestedRuntimePermissions(
2141 pkg, userIds, grantedPermissions, callingUid, callback);
2142 }
2143 @Override
2144 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
2145 int callingUid, PermissionCallback callback) {
2146 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
2147 pkg, callingUid, callback);
2148 }
2149 @Override
2150 public void revokeRuntimePermission(String permName, String packageName,
2151 boolean overridePolicy, int callingUid, int userId,
2152 PermissionCallback callback) {
2153 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Hongming Jinae750fb2018-09-27 23:00:20 +00002154 overridePolicy, callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002155 }
2156 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002157 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
2158 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2159 PermissionManagerService.this.updatePermissions(
2160 packageName, pkg, replaceGrant, allPackages, callback);
2161 }
2162 @Override
2163 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
2164 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
2165 PermissionManagerService.this.updateAllPermissions(
2166 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002167 }
2168 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07002169 public String[] getAppOpPermissionPackages(String permName) {
2170 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
2171 }
2172 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002173 public int getPermissionFlags(String permName, String packageName, int callingUid,
2174 int userId) {
2175 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
2176 callingUid, userId);
2177 }
2178 @Override
2179 public void updatePermissionFlags(String permName, String packageName, int flagMask,
2180 int flagValues, int callingUid, int userId, PermissionCallback callback) {
2181 PermissionManagerService.this.updatePermissionFlags(
2182 permName, packageName, flagMask, flagValues, callingUid, userId, callback);
2183 }
2184 @Override
2185 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2186 int userId, Collection<Package> packages, PermissionCallback callback) {
2187 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
2188 flagMask, flagValues, callingUid, userId, packages, callback);
2189 }
2190 @Override
2191 public void enforceCrossUserPermission(int callingUid, int userId,
2192 boolean requireFullPermission, boolean checkShell, String message) {
2193 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002194 requireFullPermission, checkShell, false, message);
2195 }
2196 @Override
2197 public void enforceCrossUserPermission(int callingUid, int userId,
2198 boolean requireFullPermission, boolean checkShell,
2199 boolean requirePermissionWhenSameUser, String message) {
2200 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
2201 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002202 }
2203 @Override
2204 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2205 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
2206 }
2207 @Override
2208 public int checkPermission(String permName, String packageName, int callingUid,
2209 int userId) {
2210 return PermissionManagerService.this.checkPermission(
2211 permName, packageName, callingUid, userId);
2212 }
2213 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07002214 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
2215 int callingUid) {
2216 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07002217 }
2218 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07002219 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
2220 int callingUid) {
2221 return PermissionManagerService.this.getPermissionGroupInfo(
2222 groupName, flags, callingUid);
2223 }
2224 @Override
2225 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
2226 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
2227 }
2228 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002229 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
2230 int callingUid) {
2231 return PermissionManagerService.this.getPermissionInfo(
2232 permName, packageName, flags, callingUid);
2233 }
2234 @Override
2235 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
2236 int callingUid) {
2237 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
2238 }
2239 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07002240 public PermissionSettings getPermissionSettings() {
2241 return mSettings;
2242 }
2243 @Override
2244 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
2245 return mDefaultPermissionGrantPolicy;
2246 }
2247 @Override
2248 public BasePermission getPermissionTEMP(String permName) {
2249 synchronized (PermissionManagerService.this.mLock) {
2250 return mSettings.getPermissionLocked(permName);
2251 }
2252 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002253 }
2254}